glReadPixels()无法填充ByteBuffer

时间:2011-07-22 11:58:43

标签: java opengl lwjgl bytebuffer

好吧,我正在尝试使用LWJGL在OpenGL中为一个窗口截取屏幕截图。这是代码:

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
        // ...
    }
}

和...

  • 我已经尝试过各种版本的代码,例如在Display.update()之前放置“Screenshot”块。并且使用glReadBuffer(GL_BACK / GL_FRONT)和glDrawBuffer(GL_BACK / GL_FRONT)的组合无济于事。

  • 我已禁用所有OpenGL状态和渲染,因此只显示空白屏幕并尝试使用glReadPixels。空白屏幕假设在缓冲区中,但缓冲区中没有任何内容。

  • glGetError()不会产生任何错误。

  • 我有一个类似的C +版本可以正常工作。

  • 我在NVIDIA公司的GeForce GTS 450 / PCI / SSE2上运行Windows 7,OpenGL 4.10和LWJGL 2.7.1版。

那么,问题是什么?有任何想法吗?提前谢谢。

2 个答案:

答案 0 :(得分:1)

  

pixels.position()和pixels.limit()告诉我们缓冲区中没有任何内容

他们呢?我认为更简单的方法是查看缓冲区的内容。

此外,Display.update交换缓冲区。交换后,后台缓冲区的内容未定义。所以你应该从前端缓冲区读取(不是一个好主意)或者在交换之前读取后台缓冲区

答案 1 :(得分:0)

我进一步研究了Nico Bolas的答案。并且实现了glReadPixels确实返回了信息,尽管交换或不首先交换帧缓冲区。

所以,这是我复制字节缓冲区的方法。

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();
}

我太快地得出结论,glReadPixels()没有根据其位置和限制单独返回任何内容。谢谢,Nicol Bolas的有用输入。 = d