Request a DepthBuffer in OpenGL ES for iPhone

后端 未结 1 1707
借酒劲吻你
借酒劲吻你 2021-01-06 13:33

I\'m creating a 3D OpenGL ES view on the iPhone and want to set up a depth buffer, so I can use it. I\'m calling glEnable(GL_DEPTH_TEST) and such, but because

相关标签:
1条回答
  • 2021-01-06 14:13

    As you suspect, you've no depth buffer. You'll need to attach a depth buffer to your frame buffer in whatever UIView subclass you've created that uses a CAEAGLLayer as its layer.

    Supposing you're working with Apple's OpenGL ES Xcode template, the relevant UIView subclass is EAGLView. There's a method in there, createFramebuffer, that is responsible for creating the frame buffer. Initially it'll say:

    - (void)createFramebuffer
    {
        if (context && !defaultFramebuffer)
        {
            [EAGLContext setCurrentContext:context];
    
            // Create default framebuffer object.
            glGenFramebuffers(1, &defaultFramebuffer);
            glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer);
    
            // Create color render buffer and allocate backing store.
            glGenRenderbuffers(1, &colorRenderbuffer);
            glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
            [context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer];
            glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &framebufferWidth);
            glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &framebufferHeight);
    
            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderbuffer);
    
            if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
                NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER));
        }
    }
    

    What that does is generates and binds a frame buffer, then it generates and binds a colour render buffer, gifts the colour buffer the inherent storage that comes with a CAEAGLLayer, grabs the frame dimensions for later and attaches the colour buffer to the render buffer.

    You need also to create and attach a depth buffer. Which should be as simple as (with a suitable instance variable added for depthRenderbuffer; typing directly in here):

    glGenRenderbuffers(1, &depthRenderbuffer);
    glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);
    
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, framebufferWidth, framebufferHeight);
    
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer);
    

    Which does what it looks like it does — generates and binds a render buffer, allocates it storage to be a 16bit depth buffer of the same dimensions as the colour buffer and then attaches it to the frame buffer.

    So, in total (untested):

    - (void)createFramebuffer
    {
        if (context && !defaultFramebuffer)
        {
            [EAGLContext setCurrentContext:context];
    
            // Create default framebuffer object.
            glGenFramebuffers(1, &defaultFramebuffer);
            glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer);
    
            // Create color render buffer and allocate backing store.
            glGenRenderbuffers(1, &colorRenderbuffer);
            glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
            [context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer];
            glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &framebufferWidth);
            glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &framebufferHeight);
    
            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderbuffer);
    
            // Create depth render buffer and allocate backing store.
            glGenRenderbuffers(1, &depthRenderbuffer);
            glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);
    
            glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, framebufferWidth, framebufferHeight);
    
            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer);
    
            if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
                NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER));
        }
    }
    
    0 讨论(0)
提交回复
热议问题