OpenGL ES呈现到纹理

我一直无法找到直观的代码来渲染场景到OpenGL ES中的纹理(特别是iPhone,如果这很重要)。 我有兴趣了解以下内容:

  • 你如何渲染场景到OpenGL ES中的纹理?
  • 您必须使用哪些参数来创建能够成为OpenGL ES中渲染目标的纹理?
  • 将这个渲染纹理应用到其他基元有什么意义吗?

  • 这是我如何做的。

    我定义了一个纹理变量(我使用Apple的Texture2D类,但如果需要,可以使用OpenGL纹理ID)和一个帧缓冲区:

    Texture2d * texture;
    GLuint textureFrameBuffer;
    

    然后在某个时候,我创建纹理,帧缓冲区并附加渲染缓冲区。 这你只需要做一次:

    texture = [[Texture2D alloc] initWithData:0 
                                 pixelFormat:kTexture2DPixelFormat_RGB888
                                 pixelsWide:32
                                 pixelsHigh:32
                                 contentSize:CGSizeMake(width, height)];
    
    // create framebuffer
    glGenFramebuffersOES(1, &textureFrameBuffer);
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, textureFrameBuffer);
    
    // attach renderbuffer
    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, texture.name, 0);
    
    // unbind frame buffer
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
    

    每次我想渲染纹理时,我都会这样做:

    glBindFramebufferOES(GL_FRAMEBUFFER_OES, textureFrameBuffer);
    
    ...
    // GL commands
    ...
    
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
    

    关于您的问题3,就是这样,您可以像使用其他纹理一样使用纹理。


    要将场景渲染到纹理,您必须使用与纹理关联的帧缓冲区。 这里是我创建的一个方法来简化它:

    void glGenTextureFromFramebuffer(GLuint *t, GLuint *f, GLsizei w, GLsizei h)
    {
        glGenFramebuffers(1, f);
        glGenTextures(1, t);
    
        glBindFramebuffer(GL_FRAMEBUFFER, *f);
    
        glBindTexture(GL_TEXTURE_2D, *t);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *t, 0);
    
        GLuint depthbuffer;
        glGenRenderbuffers(1, &depthbuffer);    
        glBindRenderbuffer(GL_RENDERBUFFER, depthbuffer);
        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, w, h);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthbuffer);
    
        GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
        if(status != GL_FRAMEBUFFER_COMPLETE)
            NSLog(@"Framebuffer status: %x", (int)status);
    }
    

    您可以轻松创建帧缓冲区和纹理:

    GLuint _texture, _framebuffer;
    GLsizei w,h;
    float scale = [UIScreen mainScreen].scale;
    w = self.view.bounds.size.width * scale;
    h = self.view.bounds.size.height * scale;
    glGenTextureFromFramebuffer(&_texture, &_framebuffer, w, h);
    

    您可以稍后使用_framebuffer将绘制方法中的场景渲染为_texture:

    glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer);
    //draw here the content you want in the texture
    //_texture is now a texture with the drawn content
    
    //bind the base framebuffer
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    //or if you use GLKit
    [view bindDrawable];
    //draw normaly
    

    现在你可以做到你想要的纹理。 如果你想做一些后处理(模糊,绽放,阴影等),你可以!

    链接地址: http://www.djcxy.com/p/5801.html

    上一篇: OpenGL ES Render to Texture

    下一篇: Algorithm to draw waveform from audio