glReadPixels() fails to fill ByteBuffer
Well, I'm trying to take a screenshot for a window in OpenGL using LWJGL. Here's the code:
ByteBuffer pixels = ByteBuffer.allocateDirect(800*600*4);
pixels.order(ByteOrder.nativeOrder());
while(!Display.isCloseRequested()) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
render();
Display.update();
// "Screenshot" block
if(Keyboard.isKeyDown(Keyboard.KEY_Q)) {
pixels.clear();
glReadPixels(0, 0, 800, 600, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
pixels.flip();
// 开发者_如何学运维pixels.position() and pixels.limit() tells us that there is nothing in the buffer
// ...
}
}
And...
I've already tried various versions of the code, like placing the "Screenshot" block before Display.update(). And using combinations of glReadBuffer(GL_BACK/GL_FRONT) and glDrawBuffer(GL_BACK/GL_FRONT) to no avail.
I've disabled all OpenGL states and rendering, so that only a blank screen appears and tried using glReadPixels. A blank screen supposes to be in the buffer, but nothing is in the buffer.
glGetError() doesn't produce any error.
I have a similar C+ version that works fine.
I'm running Windows 7, OpenGL 4.10 and LWJGL version 2.7.1 on NVIDIA Corporation GeForce GTS 450/PCI/SSE2.
So, what's the problem? Any ideas? Thanks in advance.
pixels.position() and pixels.limit() tells us that there is nothing in the buffer
Do they? I think a more foolproof method would be to look at the contents of the buffer.
Also, Display.update
swaps buffers. The contents of the back buffer are undefined after a swap. So you should either read from the front buffer (not a good idea) or read the back buffer before swapping.
I further researched Nico Bolas's answer. And realized glReadPixels indeed returned information despite swapping or not swapping the frame buffers first.
So, this is how I copied the byte buffer out.
glReadPixels(0, 0, 800, 600, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
byte[] data = new byte[800*600*4];
while(pixels.hasRemaining()) {
int curr = pixels.position() / 4;
int offset = (curr%800+(curr))*4;
data[offset] = pixels.get();
data[offset+1] = pixels.get();
data[offset+2] = pixels.get();
data[offset+3] = pixels.get();
}
I jumped to conclusion too quickly, that glReadPixels() didn't return anything based on its position and limit alone. Thanks, Nicol Bolas for the helpful input. =D
精彩评论