大佬教程收集整理的这篇文章主要介绍了objective-c – 两个FBO之间的乒乓渲染在第一帧之后失败.,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
编辑
也许我没有清楚地描述.实际上,我想使用textureB作为纹理并将其渲染为textureA,然后使用textureA渲染到屏幕,反之亦然.
编辑
我可以看到第一帧,即textureB.经过片段着色器后,它变为黑色.首先,我怀疑片段着色器,我将其更改为仅将黑色恢复为白色,将白色恢复为黑色.它仍然变得全黑.
设置fbo和纹理
glEnable(GL_TEXTURE_2D); glGentextures(1,&textureA); glBindTexture(GL_TEXTURE_2D,textureA); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_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); glTexImage2D(GL_TEXTURE_2D,GL_RGBA,256,GL_UNSIGNED_BYTE,null); glGentextures(1,&textureB); glBindTexture(GL_TEXTURE_2D,textureB); glTexParameteri(GL_TEXTURE_2D,GL_CLAMP_TO_EDGE); data=(GLubyte*)malloc(256*256*4*sizeof(GLubytE)); GLubyte val; for (int i = 0; i < 256 * 256 * 4; i+=4) { if (rand()%10 ==1) { val = 0; } else { val = 255; } data[i] = data[i+1] = data[i+2] = val; data[i+3] = 255; } glTexImage2D(GL_TEXTURE_2D,data); glGenFramebuffers(1,&fboA); glBindFramebuffer(GL_FRAMEBUFFER,fboA); glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D,textureA,0); glGenFramebuffers(1,&fboB); glBindFramebuffer(GL_FRAMEBUFFER,fboB); glFramebufferTexture2D(GL_FRAMEBUFFER,textureB,0);
渲染循环
if ([context API] == kEAGLRenderingAPIOpenGLES2) { if(counter%2==0) { glUseProgram(automateProg); glBindFramebuffer(GL_FRAMEBUFFER,fboA); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D,textureB); glUniform1i(AUTOMATE_TEXT,0); glUniform1f(DU,1.0/256); glUniform1f(DV,1.0/256); // update attribute values. glVertexAttribPointer(ATTRIB_VERTEX_2,2,GL_FLOAT,squareVertices); glEnabLevertexAttribArray(ATTRIB_VERTEX_2); glVertexAttribPointer(ATTRIB_TEXCOORD_2,GL_falSE,texCoord); //glEnabLevertexAttribArray(ATTRIB_TEXCOORD_2); glDrawArrays(GL_TRIANGLE_StriP,4); if (![self validateProgram:automateProg]) { NSLog(@"Failed to validate program: %d",automateProg); return; } glBindFramebuffer(GL_FRAMEBUFFER,0); glUseProgram(0); } else { glUseProgram(automateProg); glBindFramebuffer(GL_FRAMEBUFFER,fboB); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D,textureA); glUniform1i(AUTOMATE_TEXT,squareVertices); glEnabLevertexAttribArray(ATTRIB_VERTEX_2); glVertexAttribPointer(ATTRIB_TEXCOORD_2,texCoord); //glEnabLevertexAttribArray(ATTRIB_TEXCOORD_2); glDrawArrays(GL_TRIANGLE_StriP,0); glUseProgram(0); } [(EAGLView *)self.view setFramebuffer]; glClearColor(0.5f,0.5f,1.0f); glClear(GL_COLOR_BUFFER_BIT); if (counter % 2 == 0) { glUseProgram(normalProg); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D,textureB); glUniform1i(NORMAL_TEXT,0); glVertexAttribPointer(ATTRIB_VERTEX,squareVertices); glEnabLevertexAttribArray(ATTRIB_VERTEX); glVertexAttribPointer(ATTRIB_TEXCOORD,texCoord); glEnabLevertexAttribArray(ATTRIB_TEXCOORD); glDrawArrays(GL_TRIANGLE_StriP,4); if (![self validateProgram:normalProg]) { NSLog(@"Failed to validate program: %d",normalProg); return; } glUseProgram(0); } else { glUseProgram(normalProg); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D,textureA); glUniform1i(NORMAL_TEXT,normalProg); return; } glUseProgram(0); } counter++; [(EAGLView *)self.view presentFramebuffer];
片段着色器
precision mediump float; varying vec2 v_texCoord; uniform sampler2D tex; //the input texture uniform float du; //the width of the cells uniform float dv; //the height of the cells void main() { int count = 0; vec4 C = texture2D( tex,v_texCoord ); vec4 E = texture2D( tex,vec2(v_texCoord.x + du,v_texCoord.y) ); vec4 N = texture2D( tex,vec2(v_texCoord.x,v_texCoord.y + dv) ); vec4 W = texture2D( tex,vec2(v_texCoord.x - du,v_texCoord.y) ); vec4 S = texture2D( tex,v_texCoord.y - dv) ); vec4 NE = texture2D( tex,v_texCoord.y + dv) ); vec4 NW = texture2D( tex,v_texCoord.y + dv) ); vec4 SE = texture2D( tex,v_texCoord.y - dv) ); vec4 SW = texture2D( tex,v_texCoord.y - dv) ); if (E.r == 1.0) { count++; } if (N.r == 1.0) { count++; } if (W.r == 1.0) { count++; } if (s.r == 1.0) { count++; } if (NE.r == 1.0) { count++; } if (NW.r == 1.0) { count++; } if (SE.r == 1.0) { count++; } if (SW.r == 1.0) { count++; } if ( (count == 2 || count == 3)) { gl_FragColor = vec4(1.0,1.0,1.0); //cell lives... } else { gl_FragColor = vec4(0.0,0.0,1.0); //cell dies... } }
if(counter%2==0) { glBindFramebuffer(GL_FRAMEBUFFER,fboA); // will render to textureA glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D,textureB); // textureB is our input } else { ... } if (counter % 2 == 0) { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D,textureB); // textureB still as input? not textureA? } else { ... }
……这就是第二遍中发生的事情:
if(counter%2==0) { ... } else { glBindFramebuffer(GL_FRAMEBUFFER,fboB); // will render to textureB glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D,textureA); // textureA as input } if (counter % 2 == 0) { ... } else { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D,textureA); // textureA as input again? }
您在第一帧中看到某些内容的原因是,因为您实际渲染了输入数据,而不是第一次传递的结果.您在第二次传递中出现黑屏的原因可能是您的片段着色器无法正常工作.从您的着色器代码判断,访问邻居纹素的错误似乎是最合理的原因.你能提供duand dv的价值吗?
而且我不认为只使用一个纹理单元应该会有任何麻烦,正如布拉德早先指出的那样.虽然我不确定.
旁注:对于乒乓,你应该考虑创建你的FBOs as an array以使你的代码更具可读性.
编辑:
我在使用glUniform1f()设置制服du和dv时遇到问题,请尝试使用glUniform1i()(您需要在着色器中使用float()进行转换)或者使用glUniform1fv().我曾经遇到过与PowerVR GLES2驱动程序相同的问题,这个函数没有做任何事情,导致统一为0.0.
以上是大佬教程为你收集整理的objective-c – 两个FBO之间的乒乓渲染在第一帧之后失败.全部内容,希望文章能够帮你解决objective-c – 两个FBO之间的乒乓渲染在第一帧之后失败.所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。