我正在使用LWJGL将三角形渲染到带有渲染缓冲区的屏幕外帧缓冲区。渲染场景后,我使用 glReadPixels
将数据从渲染缓冲区读出到 RAM 中。前几帧工作得很好,但随后程序崩溃(SEGFAULT,或SIGABRT,...)。
我在这里做错了什么?
//Create memory buffer in RAM to copy frame from GPU to.
ByteBuffer buf = BufferUtils.createByteBuffer(3*width*height);
while(true){
// Set framebuffer, clear screen, render objects, wait for render to finish, ...
...
//Read frame from GPU to RAM
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, buf);
//Move cursor in buffer back to the begin and copy the contents to the java image
buf.position(0);
buf.get(imgBackingByteArray);
//Use buffer
...
}
使用 glReadPixels
、 ByteBuffer.get()
或基本上以任何方式访问 ByteBuffer ,可以更改指针在缓冲区中的当前位置。
这里发生的事情是:
- 缓冲区的位置最初为零。
- 对
glReadPixels
的调用将字节从 GPU 复制到缓冲区,从当前位置开始 (= 0
) - 当前位置将更改为写入缓冲区的字节数。
-
buf.position(0)
将位置重置为 0。 -
buf.get()
将缓冲区中的字节复制到imgBackingByteArray
,并将位置更改为读取的字节数 - 循环的下一次迭代尝试将字节读入缓冲区,但当前位置位于缓冲区的末尾,因此会发生缓冲区溢出。这会触发崩溃。
溶液:
//Make sure we start writing to the buffer at offset 0
buf.position(0);
//Read frame from GPU to RAM
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, buf);
//Move cursor in buffer back to the begin and copy the contents to the java image
buf.position(0);
buf.get(imgBackingByteArray);