openGL FBO 复制到纹理导致黑色/深色图像

Posted

技术标签:

【中文标题】openGL FBO 复制到纹理导致黑色/深色图像【英文标题】:openGL FBO copy to texture results in black/dark image 【发布时间】:2012-05-03 06:16:54 【问题描述】:

在我的程序中,我需要进行离屏渲染。为此,我使用 FBO。为了查看我绘制的图像是否适合测试目的,我将其从 FBO 复制到纹理,然后将纹理渲染到四边形。问题是当我从 FBO 复制到纹理并渲染它时,图像看起来很暗/变成黑色,但形状是正确的。我尝试在 FBO 中使用纹理作为附件并直接渲染它(而不将其复制到另一个纹理中)并且颜色是正确的。 下面是创建纹理的代码

//initial texture which works when rendered to a quad  
glGenTexturesEXT(3, &textureID[0]);
glBindTextureEXT(GL_TEXTURE_2D, textureID[0]);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 600, 512, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
//second one which should be a copy of the above but has tha dark color mentioned
glBindTextureEXT(GL_TEXTURE_2D, textureID[1]);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); // automatic mipmap 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 600, 512, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindTextureEXT(GL_TEXTURE_2D, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_2D,textureID[0],0);
  //Attach depth buffer to FBO
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_rb);
st1=glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);

现在在渲染函数中

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb); //biding FBO
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
 //render code
unsigned char *pixels= new unsigned char [600*512*4];
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0);  //unbiding
glBindTextureEXT(GL_TEXTURE_2D,textureID[1]); //if I change to textureID[0] result is fine
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA8,600,512,0,GL_RGBA,GL_UNSIGNED_BYTE,pixels);
glBindTextureEXT(GL_TEXTURE_2D,0);
glViewport(0, 0, 600, 512);
glClearColor(1.0,1.0,1.0,1.0);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glBindTextureEXT(GL_TEXTURE_2D, textureID[1]);
  //setting the correct matrixes + render a quad
 //before rendering a quad I set the color with
glColor3f(1.0, 1.0, 1.0);
delete[] pixels;
glutSwapBuffers();

我正在使用 glut 进行设置。在取消 FBO 并将纹理作为 glReadPixels(...) 的替代方案后,我尝试了其他功能,例如 glGetTexImage2D,但没有成功。

【问题讨论】:

【参考方案1】:

我不明白在您的第二个代码 sn-p 中对 glTexImage2D 的调用。 pixels 将只包含垃圾。你希望它做什么?


纹理已经成为 OpenGL 的核心已经很长时间了。只是glGenTexturesglBindTexture 而不是...EXT。此外,我建议使用...ARB 版本的 FBO 功能,或者仅使用 OpenGL 核心帧缓冲区支持(更高的 OpenGL 版本)。

【讨论】:

很抱歉,当你提到奇怪的函数调用后,我发现我的愚蠢和幼稚的错误。我想从内存、像素复制到创建的纹理,并认为这是执行此操作的函数。我使用 ...EXT 的原因是我使用了 EXT_frame_buffer_object,因为我的 openGL 版本只有 2.0(从我读到的 ARB 是在 3.0 中引入的)。我认为使用 ..ext 是为了安全起见。很抱歉提出这么愚蠢的问题,非常感谢您抽出时间在这件事上帮助我 ARB 是在 OpenGL-3 之前引入的。 OpenGL-3 使它们成为核心功能。 EXT 帧缓冲区也不意味着要使用 EXT 纹理函数。 glGenTexturesEXT、glBindTexturesEXT 可以追溯到 OpenGL-1.0,当时纹理本身是一个扩展(那是在 1994 年)。

以上是关于openGL FBO 复制到纹理导致黑色/深色图像的主要内容,如果未能解决你的问题,请参考以下文章

使用 FBO 和着色器 OpenGL 渲染到纹理

OpenGL:一次只有一个 FBO 工作

将绑定到 FBO 的纹理复制到另一个 OpenGL 上下文

OpenGL 3.30 / GLSL 3.30 - MRT 输出黑色纹理

渲染到窗口帧缓冲区和 FBO 以保存全尺寸纹理图像

OpenGL:渲染到 FBO 时是不是支持纹理组合器功能?