OpenGL ES Render to Texture

I have been having trouble finding straightforward code to render a scene to a texture in OpenGL ES (specifically for the iPhone, if that matters). I am interested in knowing the following:

  • How do you render a scene to a texture in OpenGL ES?
  • What parameters must you use to create a texture that is capable of being a render target in OpenGL ES?
  • Are there any implications with applying this rendered texture to other primitives?

  • This is how I'm doing it.

    I define a texture variable (I use Apple's Texture2D class, but you can use an OpenGL texture id if you want), and a frame buffer:

    Texture2d * texture;
    GLuint textureFrameBuffer;
    

    Then at some point, I create the texture, frame buffer and attach the renderbuffer. This you only need to do it once:

    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);
    

    Every time I want to render to the texture, I do:

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

    About your question 3, that's it, you can use the texture as if it is any other texture.


    To render the scene to a texture you must use a framebuffer associated with a texture. Here is a method that i created to simplify it :

    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);
    }
    

    You can create the frame buffer and the texture easily :

    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);
    

    You can later use _framebuffer to render the scene into _texture in your draw method :

    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
    

    Now you can do what you want with the texture. If you want to do some post processing (blur, bloom, shadow, etc...) you can !

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

    上一篇: 在OpenGL中通过表面动画纹理

    下一篇: OpenGL ES呈现到纹理