objective-c – 两个FBO之间的乒乓渲染在第一帧之后失败.
我正在尝试创建两个FBO并实现乒乓渲染.但是,我只能让第一帧正常工作.我试图模拟生活游戏,在第一帧之后,我只得到一个黑屏.你能帮帮我查一下吗?我在这个问题上花了好几个小时.
编辑 也许我没有清楚地描述.实际上,我想使用textureB作为纹理并将其渲染为textureA,然后使用textureA渲染到屏幕,反之亦然. 编辑 设置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-else块中将结果呈现给纹理,并将结果渲染到第二个if-else块中的屏幕?
如果是这样,那么看起来您在如何组织输入和输出时就会出错. 这是你第一次传递中发生的事情(我减少了你的代码): 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. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |