FBO blit depth buffer

Hey folks,

I’m trying to copy the depth buffer from one FBO to another using glBlitFramebuffer();

My code appears to be working, but I’m noticing a few artifacts:

  1. MSAA doesn’t appear to be working
  2. Every time I bind the camera after copying, the perspective is flipped

Here’s what’s going on

ofFbo first;
ofFbo second;

//--------------------------------------------------------------
void ofApp::setup(){

   ofFbo::Settings settings;
   settings.width = ofGetWidth();
   settings.height = ofGetHeight();
   settings.internalformat = GL_RGBA;
   settings.useDepth = true;
   //settings.depthStencilAsTexture = true;
   //settings.depthStencilInternalFormat = GL_DEPTH_COMPONENT16_ARB;
   settings.numSamples = 8;

   first.allocate( settings );
   second.allocate( settings );
}

//--------------------------------------------------------------
void ofApp::draw(){
    
    ofBackground(50);
    ofEnableDepthTest();
    
    ofVec3f camPosition;
    camPosition.set(0, ofMap(ofGetMouseY(), 0, ofGetHeight(), -50, 50, true), 80);
    
    // -------------------------- draw into first FBO --------------------------
    
    first.begin();
    
    ofClear(50);
    
    ofCamera cam;
    cam.setPosition(camPosition);
    cam.lookAt(ofVec3f(0, 0, 0), ofVec3f(0, 1, 0));
    cam.begin();
    
    ofSetColor(127);
    ofDrawBox(0, 0, 0, 30, 30, 30);
    
    cam.end();
    
    first.end();
    
    // -------------------------- draw into second FBO --------------------------
    
    second.begin();
    
    ofClear(50);
    
    // copy depth buffer using glBlitFramebuffer()
    
    int w = first.getWidth();
    int h = first.getHeight();
    
    glBindFramebuffer(GL_READ_FRAMEBUFFER, first.getId());
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
    glBlitFramebuffer(0, 0, w, h, 0, 0, w, h, GL_DEPTH_BUFFER_BIT, GL_NEAREST);

    cam.setPosition(camPosition);
    cam.lookAt(ofVec3f(0, 0, 0), ofVec3f(0, 1, 0));
    cam.begin();
    
    for(int i=-100; i<=100; i+=5){
        ofDrawLine(i, -100, i, 100);
    }
    
    cam.end();
    
    // not sure if this does anything :|
    
    glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    
    second.end();
    
    GLenum err = glGetError();
    if(err!=GL_NO_ERROR)
    {
        ofLogNotice("Error while blitting") << err;
    }
   
    // -------------------------- draw second FBO (occluded) --------------------------
    
    ofSetColor(255);
    second.draw(0, 0);
    
    if( ofGetKeyPressed('d')){
        
      // draw occluded lines normally (this is how it should look)
        
        ofSetupScreen();
        
        ofBackground(50);
    
        ofCamera debugCam;
        debugCam.setPosition(camPosition);
        debugCam.lookAt(ofVec3f(0, 0, 0), ofVec3f(0, 1, 0));
        debugCam.begin();
    
        ofSetColor(127);
        ofDrawBox(0, 0, 0, 30, 30, 30);
        
        ofSetColor(255);
        for(int i=-100; i<=100; i+=5){
            ofDrawLine(i, -100, i, 100);
        }
        
        debugCam.end();
    }
}

What’s strange is that when I blit and use second.getId(), it doesn’t work, but when I use 0 as the argument, it does.

If anybody has any thoughts or tip, I’d be super grateful.

Jeremy

For the record, it looks like the copying of the depth buffer needs to happen before i bind and draw into the second fbo. Still not 100% sure about the MSAA

// -------------------------- blit depth into second FBO --------------------------

// copy depth buffer using glBlitFramebuffer()

int w = first.getWidth();
int h = first.getHeight();

glBindFramebuffer(GL_READ_FRAMEBUFFER, first.getId());
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, second.getIdDrawBuffer());
glBlitFramebuffer(0, 0, w, h, 0, 0, w, h, GL_DEPTH_BUFFER_BIT, GL_NEAREST);

// not sure if this does anything :|

glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);

 // -------------------------- draw into second FBO --------------------------

second.begin();

//ofClear(50);

// just clear the color buffer
glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
//glDisable(GL_DEPTH_TEST);

cam.setPosition(camPosition);
cam.lookAt(ofVec3f(0, 0, 0), ofVec3f(0, 1, 0));
cam.begin();

for(int i=-100; i<=100; i+=5){
    ofDrawLine(i, -100, i, 100);
}

cam.end();
second.end();