objective-c – 两个FBO之间的乒乓渲染在第一帧之后失败.

objective-c – 两个FBO之间的乒乓渲染在第一帧之后失败.,第1张

概述我正在尝试创建两个FBO并实现乒乓渲染.但是,我只能让第一帧正常工作.我试图模拟生活游戏,在第一帧之后,我只得到一个黑屏.你能帮帮我查一下吗?我在这个问题上花了好几个小时. 编辑 也许我没有清楚地描述.实际上,我想使用textureB作为纹理并将其渲染为textureA,然后使用textureA渲染到屏幕,反之亦然. 编辑 我可以看到第一帧,即textureB.经过片段着色器后,它变为黑色.首先, 我正在尝试创建两个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 textureuniform float du; //the wIDth of the cellsuniform 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.

总结

以上是内存溢出为你收集整理的objective-c – 两个FBO之间的乒乓渲染在第一帧之后失败.全部内容,希望文章能够帮你解决objective-c – 两个FBO之间的乒乓渲染在第一帧之后失败.所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1225698.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存