【问题标题】:Draw to offscreen renderbuffer in OpenGL ES (iPhone)在 OpenGL ES (iPhone) 中绘制到屏幕外渲染缓冲区
【发布时间】:2010-06-18 23:10:59
【问题描述】:

我正在尝试在 iPhone 上的 OpenGL ES 中创建一个屏幕外渲染缓冲区。我创建了这样的缓冲区:

        glGenFramebuffersOES(1, &offscreenFramebuffer);
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, offscreenFramebuffer);

    glGenRenderbuffersOES(1, &offscreenRenderbuffer);
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, offscreenRenderbuffer);
    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, offscreenRenderbuffer);

但我对如何渲染存储感到困惑。 Apple 的文档说要使用 EAGLContext renderBufferStorage:fromDrawable: 方法,但这似乎只适用于一个渲染缓冲区(正在显示的主要缓冲区)。如果我使用普通的 OpenGL 函数 glRenderBufferStorageOES,那么我似乎无法让它显示。代码如下:

        // this is in the initialization section:
    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGB8_OES, backingWidth, backingHeight);

    // and this is when I'm trying to draw to it and display it:
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, offscreenFramebuffer);
    GLfloat vc[] = {
        0.0f, 0.0f, 0.0f,
        10.0f, 10.0f, 10.0f,
        0.0f, 0.0f, 0.0f,
        -10.0f, -10.0f, -10.0f,         
    };

    glLoadIdentity();
    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(3, GL_FLOAT, 0, vc);
    glDrawArrays(GL_LINES, 0, 4);
    glDisableClientState(GL_VERTEX_ARRAY);

    glBindRenderbufferOES(GL_RENDERBUFFER_OES, offscreenRenderbuffer);
    [context presentRenderbuffer:GL_RENDERBUFFER_OES];

这样做,屏幕上不会显示任何内容。但是,如果我将对“屏幕外...缓冲区”的引用切换到使用 renderBufferStorage 方法创建的缓冲区,它就可以正常工作。

有什么建议吗?

【问题讨论】:

    标签: iphone opengl-es


    【解决方案1】:

    由于您不能将 presentRenderbuffer 与屏幕外 FBO 一起使用,您应该使用 glFramebufferTexture2DOES 将其与纹理对象相关联,然后渲染带纹理的全屏四边形。

    【讨论】:

      【解决方案2】:

      @david 好主意.. 你需要做的是@prideout 所说的.. 创建一个纹理并渲染它.. 并且每次都在一个四边形上使用该纹理。确保只绘制一次纹理,因为在您的情况下,事情是持久的。

      - (void)setUpTextureBuffer 
      {
       glGenFramebuffersOES(1, &texturebuffer); 
       glBindFramebufferOES(GL_FRAMEBUFFER_OES, texturebuffer);
      
       // create the texture
       glGenTextures(1, &canvastexture); 
       glBindTexture(GL_TEXTURE_2D, canvastexture); 
       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,  512, 512, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); 
       glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, canvastexture, 0);
      
       GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES); 
       if(status != GL_FRAMEBUFFER_COMPLETE_OES) { 
        NSLog(@"failed to make complete framebuffer object %x", status);
       }
      
       glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
       glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
      
       glClearColor(1.0, 1.0, 1.0, 1.0);
       glViewport(0, 0, 512, 512);
       glClear(GL_COLOR_BUFFER_BIT);
      }
      
      
      
      //setTargetToTexture() function
      
       glBindFramebufferOES(GL_FRAMEBUFFER_OES, tbuffer);
       glBindTexture(GL_TEXTURE_2D, allbrushes);
       glViewport(0, 0, 512, 512);
      
      //reset pointers after finishing drawing to textures
      
       glViewport(0, 0, BWIDTH, BHEIGHT);
       glVertexPointer(2, GL_FLOAT, 0, canvas);   //canvas vertices
       glTexCoordPointer(2, GL_FLOAT, 0, texels);
       glBindTexture(GL_TEXTURE_2D, boundtexture);   //bind to the texture which is the special render target 
       glBindFramebufferOES(GL_FRAMEBUFFER_OES, fbuffer); //back to normal framebuffer
      

      【讨论】:

        【解决方案3】:

        您不能呈现正常的渲染缓冲区(使用 glRenderbufferStorage 创建),它总是在屏幕外。 presentRenderbuffer: 只能用于使用 renderbufferStorage:fromDrawable: 创建的渲染缓冲区。如果您检查了该 presentRenderbuffer: 的返回值,您应该会发现它失败了。

        你想做什么?

        【讨论】:

        • 我正在编写一个游戏,在该游戏中,我将在屏幕上绘制的东西应该从一帧到另一帧都是持久的。我想将这些持久性的东西绘制到屏幕外缓冲区,然后在每一帧上将其“blit”到屏幕上并在其上绘制非持久性/易失性的东西。我真的很想避免必须维护一个持久对象列表并在每一帧重新创建它们,因为对象的数量可能会很快变得笨拙。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-26
        • 1970-01-01
        • 1970-01-01
        • 2012-01-03
        相关资源
        最近更新 更多