Iphone OpenGL ES渲染到纹理

Iphone OpenGL ES渲染到纹理,iphone,opengl-es,render-to-texture,Iphone,Opengl Es,Render To Texture,我一直很难在OpenGL ES中找到将场景渲染为纹理的简单代码(如果需要的话,特别是iPhone)。我有兴趣了解以下内容: 如何在OpenGL ES中将场景渲染为纹理 必须使用哪些参数来创建能够成为OpenGL ES中渲染目标的纹理 将此渲染纹理应用于其他基本体是否有任何影响 我就是这样做的 我定义了一个纹理变量(我使用Apple的Texture2D类,但如果需要,可以使用OpenGL纹理id)和一个帧缓冲区: Texture2d * texture; GLuint textureFrameBu

我一直很难在OpenGL ES中找到将场景渲染为纹理的简单代码(如果需要的话,特别是iPhone)。我有兴趣了解以下内容:

  • 如何在OpenGL ES中将场景渲染为纹理
  • 必须使用哪些参数来创建能够成为OpenGL ES中渲染目标的纹理
  • 将此渲染纹理应用于其他基本体是否有任何影响

  • 我就是这样做的

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

    Texture2d * texture;
    GLuint textureFrameBuffer;
    
    然后在某个点上,我创建纹理、帧缓冲区并附加renderbuffer。您只需执行一次即可:

    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在绘制方法中将场景渲染为_纹理:

    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
    

    现在,您可以对纹理执行任何操作。如果你想做一些后期处理(模糊,开花,阴影等),你可以

    Marco,你知道为每个需要渲染的纹理保留帧缓冲区和渲染缓冲区需要多少开销吗?我有几个我的应用程序需要绘制的大纹理,我现在使用glFramebufferTexture2DOES将不同的纹理附加到一个“额外”帧缓冲区。为每个文件保留一个单独的帧缓冲区会更好吗?请编辑您的代码以便initWithData:。。。通话无需滚动即可进行?仅需小细节。您希望有glBindFramebufferOES(GL_FRAMEBUFFER_OES,1);如果您正在iphone上“解除绑定”自定义帧缓冲区,请改为0(或者更好地存储以前的版本并在以后还原)。绑定到帧缓冲区Id 0并不总是初始化为GL会话的主帧缓冲区的Id。我的ES2会话肯定存储了一个不同的会话。我建议人们在创建GL会话时参考给定的。有苹果的Texture2D文件的链接吗?它似乎不再存在于他们的绘画应用程序中……您好,您从哪里获得的
    \u renderToTextureBuffer
    ?酷,我就是这么想的。你在一个工作示例中有这个吗?我将尝试(再次)将其添加到我的代码中,但我不确定如何在纹理中绘制
    //在这里绘制纹理中所需的内容
    我可以使用VBOs和
    glDrawArrays()