0

编辑:我将 FBO 排除在外,以确保问题不是来自那里,所以现在我只是在做以下事情:

设置纹理:

GLuint FB0Texture;
glGenTextures(1, &FB0Texture);
glBindTexture(GL_TEXTURE_2D, FB0Texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, size.width, size.height, 
                 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);

然后渲染:

[self drawScene];

[(EAGLView *)self.view bindFB0];

glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 320, 480);

[self drawFullScreenQuad]; (it's actually not full screen so I can see both the 3d scene and the resulting texture)

我得到相同的结果!如果我将 FB0Texture 设置为“DEPTH_COMPONENT”纹理,则为黑色纹理,但如果我将 FB0Texture 设置为常规 GL_RGBA 纹理,则为正常场景......

所以我想我要么设置了错误的深度纹理,要么我在渲染中做错了什么会导致 RGBA 纹理看起来正常但深度纹理被搞砸了?GL_DEPTH_TEST 已启用并且工作正常(模型看起来正确)所以我认为实际渲染没有问题,但此时我迫切需要线索......

请帮忙!

// 编辑结束

我正在尝试在 iphone 上实现一些基本的阴影映射,但我一直坚持将深度值渲染为纹理……这让我发疯,我显然做错了什么,但无法弄清楚它是什么……

所以我在做什么:

  • 设置默认帧缓冲区,附加颜色渲染缓冲区和深度渲染缓冲区
  • 设置一个新的帧缓冲区(称为 FB0),将纹理附加到深度组件

然后当我渲染:

  • 将场景绘制到 FB0
  • 切换到默认帧缓冲区
  • 使用 FB0 作为纹理绘制全屏四边形

我得到......什么都没有!(好吧,我得到了一个全白色的纹理)

如果我将纹理附加到 FB0 的颜色分量而不是深度分量,一切正常,就像我将场景绘制到 FB0,然后使用 FB0 作为纹理来绘制一个全屏四边形,我会看到我想要的看看我是否直接绘制到默认帧缓冲区。

但是,当我将纹理附加到深度组件时,我得到的只是这个白色屏幕/纹理。

一些代码:

设置缓冲区:

// Create default framebuffer object.
glGenFramebuffers(1, &defaultFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer);

// Create color render buffer and allocate backing store.
glGenRenderbuffers(1, &colorRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
[context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer];
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderbuffer);

// Create depth render buffer
glGenRenderbuffers(1, &depthRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, 320, 480); 
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer);


// Create Depth Map Frame Buffer

glGenFramebuffers(1, &FB0);
glBindFramebuffer(GL_FRAMEBUFFER, FB0);

// Attach texture to depth component        

glGenTextures(1, &FB0Texture);
glBindTexture(GL_TEXTURE_2D, FB0Texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, size.width, size.height, 
                 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0);

glFramebufferTexture2D(GL_FRAMEBUFFER, 
                       GL_DEPTH_ATTACHMENT, 
                       GL_TEXTURE_2D, 
                       FB0Texture, 
                       0);

如果我在此之后检查帧缓冲区的状态,我不会收到任何错误消息,所以我假设缓冲区是正确创建的。

然后在渲染中:

[(EAGLView *)self.view setFB0]; (just binds the framebuffer)

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

[self drawScene];

[(EAGLView *)self.view setFramebuffer]; (binds back the default frame buffer)

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

[(EAGLView *)self.view bindFB0Texture];

[self drawFullScreenQuad];

[(EAGLView *)self.view presentFramebuffer];

在这一点上,我希望看到一个黑色和白色纹理,灰色级别表示深度,但我只是得到一个纯白色四边形/纹理。

同样,如果我将 FB0Texture 附加到 GL_COLOR_ATTACHMENT0 而不是 GL_DEPTH_ATTACHMENT 一切都按预期工作,我的场景会正确渲染到纹理。所以我想问题出在我如何附加纹理,或者可能是我做事的顺序?

4

1 回答 1

1

您的问题可能在于您仅将深度纹理附加到渲染到纹理 FBO,而没有附加颜色缓冲区。

如果这不起作用,Apple在他们的技术文档中建议您应该使用GL_OES_depth_texture扩展,但我自己无法在渲染深度到纹理方面完成这项工作,尽管使用它似乎可以显着提高保真度我得到的颜色渲染到纹理图像的深度测试。

编辑:哎呀,这就是你已经在做的事情了。我应该更彻底地阅读这个问题,对不起!

我目前也遇到这个问题,所以如果解决了,我很想知道如何!

编辑#2:我已经在我自己的情况下解决了这个问题。深度缓冲区将深度存储在非线性空间中,因此有必要将深度转换回线性空间以正确可视化它们(这可以通过投影近平面和远平面信息来实现)。我遇到的问题是我的大部分深度信息都存储在 0.995 到 1.0 的范围内,这意味着在我看来,它看起来像是一个完全白色的纹理。当您获得全白纹理时,这可能是您遇到的问题。

附带说明一下,Xcode 4.2 令人敬畏的 OpenGL ES 快照功能帮助我解决了这个问题。它使您可以可视化上下文中的所有纹理和渲染缓冲区对象,如果数据是非线性的,甚至可以为您重新调整颜色。正如您可能猜到的那样,这就是我的想法。

于 2011-11-01T12:15:47.687 回答