在OpenGL ES(iPhone)中绘制到离屏渲染缓冲区

12

我正在尝试在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);

但我对如何呈现存储感到困惑。苹果的文档说要使用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];

按照这种方式做,屏幕上不会显示任何内容。 但是,如果我将对 "offscreen...Buffer" 的引用替换为使用 renderBufferStorage 方法创建的缓冲区,它就可以正常工作。

有什么建议吗?

3个回答

3

由于无法在离屏FBO中使用presentRenderbuffer,因此您应该使用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

1

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

您想要做什么?


我正在编写一个游戏,需要将某些内容绘制到屏幕上并保持其在各帧之间的持久性。我想将这些持久性的内容绘制到离线缓冲区中,然后在每一帧中将其"blit"到屏幕上,并在其上方绘制不持久/易挥发的东西。我真的很想避免每一帧都重新创建一个持久对象列表,因为对象数量可能会很快变得难以处理。 - David Ensminger

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接