OpenGL:读取帧缓冲区的深度纹理
我在Java中使用LWJGL,它具有与C++ OpenGL相同的函数名称。请注意,我不得不使用OpenGL的“旧”固定功能管线。OpenGL:读取帧缓冲区的深度纹理
//the initialization method
public void init(int width, int height) {
//initializing the PBO
pbo_id = glGenBuffers();
// [...]
//initializing the Framebuffer
framebufferObject = glGenFramebuffers();
framebufferTexture = glGenTextures();
depthBuffer = glGenRenderbuffers();
framebufferFilter = GL_NEAREST;
glBindTexture(GL_TEXTURE_2D, framebufferTexture);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (ByteBuffer)null);
glBindFramebuffer(GL_FRAMEBUFFER, framebufferObject);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, framebufferTexture, 0);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer);
glBindTexture(GL_TEXTURE_2D, 0);
}
//this is called after the world was rendered to the framebuffer
public void capture() {
//binding the PBO
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo_id);
//binding the Framebuffer's texture
glBindTexture(GL_TEXTURE_2D, framebuffer_id);
//storing the Framebuffer's contents in the PBO
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
//unbinding the Framebuffer
glBindTexture(GL_TEXTURE_2D, 0);
//unbinding the PBO
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
}
我怎么会深度图的内容(我想被初始化为深度缓存)存储在:
我目前正在成功地使用下面的代码绘制帧缓冲区的RGB内容PixelBufferObjects PBO而不是“主”帧缓冲区内容?
UPDATE: 这是我使用的阅读深度图的内容,现在PBO该代码:
public void captureDepthMap() {
//binding the PBO
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo_id);
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
//binding the FBO
glBindFramebuffer(GL_FRAMEBUFFER, framebufferObject);
//storing the Depth Map's contents in the PBO
glReadPixels(0, 0, width, height, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT_24_8, 0);
//unbinding the FBO
glBindFramebuffer(GL_FRAMEBUFFER, 0);
//unbinding the PBO
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
}
产生的图像仅仅是黑色的但是。 这可能是什么原因造成的?我可能搞砸了一些GL格式吗?
绑定“framebuffer的纹理”并没有什么意义。此纹理仅表示一个(颜色缓冲区)附件。您可以将多个纹理附加到帧缓冲区,深度缓冲区也可以作为纹理进行存储。
如果您使用深度纹理附件而不是渲染缓冲区,则可以按照读取颜色附件的相同方式进行读取。唯一的区别是格式和数据类型:GL_DEPTH_COMPONENT
和GL_UNSIGNED_INT_24_8
。
或者,您可以使用glReadPixels (...)
从附加的渲染缓冲区读取。由于您必须指定一个矩形才能读取,因此API涉及更多一点。
这就是我目前使用'glReadPixels'从framebuffer的纹理读取:'glReadPixels(0,0,getFrameWidth(),getFrameHeight(),GL_RGB,GL_UNSIGNED_BYTE,0) ;',我将如何去阅读Renderbuffer?我会如何将其绑定? – CrushedPixel
@CrushedPixel:只要将它附加到Frambuffer对象上,就可以“绑定”渲染缓冲区。帧缓冲区只能有一个深度附件,所以你不需要做任何事情。当您调用'glReadPixels(...)'时,只需使用FBO即可,并使用正确的格式和数据类型。我上面给出的例子是一个32位打包数据类型,它是如何在GPU上本地存储24位深度缓冲区(其余的8位是未使用的填充或模板缓冲区),所以它应该转换为从渲染缓冲区直接复制到没有数据转换的pixelbuffer。 –
谢谢。我更新了我的帖子,根据您的建议显示了我的当前代码,但是结果渲染看起来不正确。 – CrushedPixel
使用深度纹理附件而不是渲染缓冲区,并且从不使用像33190这样的幻数。我不知道常量是什么,我也不打算查看它。 –
@ AndonM.Coleman我用GL_DEPTH_COMPONENT24代替了它的幻数,它与此类似。 – CrushedPixel
从帧缓冲区检索数据的规范方法是'glReadPixels'。使用像素包缓冲区PBO绑定的方式将空指针传递给数据参数将使其与PBO异步读取。另请注意,glGetTexImage仅在(桌面)OpenGL中受支持,但在ES配置文件中并不支持WebGL。所以为了前向兼容性,你不应该使用glGetTexImage – datenwolf