c – COLOR_ATTACHMENT – 如何在Framebuffer对象中渲染多个纹理
发布时间:2020-12-16 07:12:26 所属栏目:百科 来源:网络整理
导读:我试图渲染多个纹理作为COLOR_ATTACHMENTs没有成功.我从显示它们得到的只是一个黑色屏幕(带有红色清晰填充)意味着我的纹理被读取但是“空”. 我的伪代码是:将3个纹理附加到FBO,纹理索引为1,2和3,颜色附件分别为0,1和2.作为测试用例,我尝试将场景渲染为3种颜
我试图渲染多个纹理作为COLOR_ATTACHMENTs没有成功.我从显示它们得到的只是一个黑色屏幕(带有红色清晰填充)意味着我的纹理被读取但是“空”.
我的伪代码是:将3个纹理附加到FBO,纹理索引为1,2和3,颜色附件分别为0,1和2.作为测试用例,我尝试将场景渲染为3种颜色附件,以便它们能够保存相同的精确数据.然后在着色器通道2(使用2Dsampler)读取这些纹理中的任何一个并在四边形上显示它们. 我对这2个额外颜色附件的初衷是将它们用作使用GPU乒乓技术的随机数据缓冲区.到目前为止,我只是将它们用作纹理克隆用于测试目的. 当尝试从GL_TEXTURE1(COLOR_ATTACHMENT0)读取时,一切正常,但不是来自其他2(黑屏). 代码 : // Texture indices - inside a 'myGlut' struct GLenum skyboxTextureIndex = GL_TEXTURE0; GLenum colorTextureIndex = GL_TEXTURE1; unsigned int colorTextureIndexInt = 1; GLenum depthTexture1Index = GL_TEXTURE2; unsigned int depthTexture1IndexInt = 2; GLenum depthTexture2Index = GL_TEXTURE3; unsigned int depthTexture2IndexInt = 3; //** Below is inside 'main()' **// // Create frame buffer myGlut.frameBuffer = glutils::createFrameBuffer(); // Create texture to hold color buffer glActiveTexture(myGlut.colorTextureIndex); glBindTexture(GL_TEXTURE_2D,myGlut.colorTexture); myGlut.colorTexture = glutils::createTextureAttachment(myGlut.camera -> getRenderResizedWidthPx(),myGlut.camera -> getRenderResizedHeightPx()); glutils::bindTextureAttachment(GL_COLOR_ATTACHMENT0,myGlut.colorTexture); // Create 1st texture to hold depth buffer wannabe :> glActiveTexture(myGlut.depthTexture1Index); glBindTexture(GL_TEXTURE_2D,myGlut.depthTexture1); myGlut.depthTexture1 = glutils::createTextureAttachment(myGlut.camera -> getRenderResizedWidthPx(),myGlut.camera -> getRenderResizedHeightPx()); glutils::bindTextureAttachment(GL_COLOR_ATTACHMENT1,myGlut.depthTexture1); // Create 2nd texture to hold depth buffer wannabe :> glActiveTexture(myGlut.depthTexture2Index); glBindTexture(GL_TEXTURE_2D,myGlut.depthTexture2); myGlut.depthTexture2 = glutils::createTextureAttachment(myGlut.camera -> getRenderResizedWidthPx(),myGlut.camera -> getRenderResizedHeightPx()); glutils::bindTextureAttachment(GL_COLOR_ATTACHMENT2,myGlut.depthTexture2); // Check FBO if (!glutils::checkFBOStatus()) return 0; 使用glutils :: functions // Clear screen void glutils::clearScreen (float r,float g,float b,float a) { glClearColor(r,g,b,a); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } // Bind select framebuffer void glutils::bindFrameBuffer(int frameBuffer,int width,int height) { glBindFramebuffer(GL_FRAMEBUFFER,frameBuffer); glViewport(0,width,height); } // Create frame buffer GLuint glutils::createFrameBuffer() { GLuint frameBuffer; glGenFramebuffers(1,&frameBuffer); glBindFramebuffer(GL_FRAMEBUFFER,frameBuffer); return frameBuffer; } // Create a texture attachment GLuint glutils::createTextureAttachment(int width,int height) { GLuint texture; glGenTextures(1,&texture); glBindTexture(GL_TEXTURE_2D,texture); glTexImage2D(GL_TEXTURE_2D,GL_RGB,height,GL_UNSIGNED_BYTE,NULL); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); return texture; } // Bind a texture attachment to select framebuffer void glutils::bindTextureAttachment (GLenum colorAttachment,GLuint texture) { glFramebufferTexture2D(GL_FRAMEBUFFER,colorAttachment,GL_TEXTURE_2D,texture,0); } // Check current frame buffer status bool glutils::checkFBOStatus () { if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { std::cerr << "##### ERROR : Frambuffer not complete... #####" << std::endl; return false; } else return true; } 然后过剩显示功能: // Clear screen glutils::clearScreen(1.f,0.f,1.f); // Bind to custom framebuffer glutils::bindFrameBuffer(myGlut.frameBuffer,myGlut.camera -> getScreenWidthPx(),myGlut.camera -> getScreenHeightPx()); // Set draw context GLuint drawBuffers[2]; if (myGlut.depthTextureSwitch) { drawBuffers[0] = GL_COLOR_ATTACHMENT0; drawBuffers[1] = GL_COLOR_ATTACHMENT2; } else { drawBuffers[0] = GL_COLOR_ATTACHMENT0; drawBuffers[1] = GL_COLOR_ATTACHMENT1; } glDrawBuffers(2,drawBuffers); // Use main program and bind uniforms glUseProgram(myGlut.theProgram); myGlut.refreshUniformsPass_1(); // Draw quad to sample glutils::drawQuad(); // Unbind custom framebuffer -> use default (screen) glutils::unbindCurrentFrameBuffer(myGlut.camera -> getScreenWidthPx(),myGlut.camera -> getScreenHeightPx()); // Use secondary program and bind uniforms glUseProgram(myGlut.theProgram2); myGlut.refreshUniformsPass_2(); // Draw quad to apply texture to glutils::drawQuad(); // Switch myGlut.depthTextureSwitch = !myGlut.depthTextureSwitch; // Display & loop glutSwapBuffers(); glutPostRedisplay(); 相关的均匀绑定 – >通过1 glUniform1i(glGetUniformLocation(myGlut.theProgram,"depthTexture"),!myGlut.depthTextureSwitch ? myGlut.depthTexture2IndexInt : myGlut.depthTexture1IndexInt); 相关着色器代码 – >通过1 layout (location = 0) out vec4 outputColor; layout (location = 1) out vec4 outputDepth1; layout (location = 2) out vec4 outputDepth2; uniform sampler2D depthTexture; void main() { // ... outputColor = someColor; outputDepth1 = someColor; outputDepth2 = someColor; } 相关的均匀绑定 – >通过2 glUniform1i(glGetUniformLocation(myGlut.theProgram2,"texFramebuffer"),myGlut.depthTextureSwitch ? myGlut.depthTexture1IndexInt : myGlut.depthTexture2IndexInt); 使用相关着色器代码 – >通过2 uniform sampler2D texFramebuffer; out vec4 outputColor; // ... void main() { outputColor = texture(texFramebuffer,vec2(gl_FragCoord.x / screenWidthPx * resRatio,gl_FragCoord.y / screenHeightPx * resRatio)); } 简而言之:我的GL_TEXTURE0保持场景,而GL_TEXTURE1和GL_TEXTURE2为黑色.为什么? 解决方法
我终于找到了罪魁祸首.因为我在循环display()函数中绑定了framebuffer,所以在绑定FBO之后我也需要绑定纹理附件.改为
// Bind to custom framebuffer glutils::bindFrameBuffer(myGlut.frameBuffer,myGlut.camera -> getScreenHeightPx()); // Bind to select attachments glutils::bindTextureAttachment(GL_COLOR_ATTACHMENT0,myGlut.colorTexture); if (!myGlut.depthTextureSwitch) glutils::bindTextureAttachment(GL_COLOR_ATTACHMENT1,myGlut.depthTexture1); else glutils::bindTextureAttachment(GL_COLOR_ATTACHMENT1,myGlut.depthTexture2); 允许我渲染所有需要的颜色附件. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容
- 配置Oracle Instant Client环境
- ruby-on-rails – Rails:如何从上传显示图像
- ruby-on-rails – Javascript Blob的Ruby rest-client API请
- NoSQL/MongoDB安装
- C++实例输入多行数字到数组
- Oracle EBS Interface/API(8)-标准展BOM存储过程
- ruby-on-rails – Rails – 在视图中渲染视图 – 传递参数
- oracle日期与字符串的互相转换SQL语句
- ruby-on-rails – vim / macvim:找到定义方法/符号的位置
- ruby-on-rails – 我应该将哪个版本的rails用于新项目