Search code examples
openglglslfbo

FBO and Textures


I have attached two textures to an FBO. The first texture will be used to show a depth map. The second texture will show the object in a normal way.

If I do this, it works well and shows me the depth map.

GLuint atach0 = GL_DEPTH_ATTACHMENT;
glBindFramebuffer(GL_FRAMEBUFFER,fboBuffer);
  glDrawBuffers(1,&atach0);
  glClear(GL_DEPTH_BUFFER_BIT);
  glViewport(0.0,0.0,640,480);
  LProjection = glm::ortho(-10.0f,10.0f,-10.0f,10.0f,-500.0f,500.0f);
  LView = glm::lookAt(glm::vec3(0.0f,15.0f,0.000001f),glm::vec3(0.0f,0.0f,0.0f),glm::vec3(0.0f,1.0f,0.0f));
  LViewProjection = LProjection * LView;
  glEnable(GL_DEPTH_TEST);

  ...CUBE3D

glBindFramebuffer(GL_FRAMEBUFFER,0);

glUniform1i(uniforTEX,0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,GL_DEPTH_MAP);

  ...DRAW-DEPTH-MAP!

glBindTexture(GL_TEXTURE_2D,0);

But if I do this, it only shows a white screen and the depth map is no longer visible.

GLuint atach0 = GL_DEPTH_ATTACHMENT;
glBindFramebuffer(GL_FRAMEBUFFER,fboBuffer);
  glDrawBuffers(1,&atach0);
  glClear(GL_DEPTH_BUFFER_BIT);
  glViewport(auxrecX,auxrecY,auxrcAn,auxrcAl);
  LProjection = glm::ortho(-10.0f,10.0f,-10.0f,10.0f,-500.0f,500.0f);
  LView = glm::lookAt(glm::vec3(0.0f,15.0f,0.000001f),glm::vec3(0.0f,0.0f,0.0f),glm::vec3(0.0f,1.0f,0.0f));
  LViewProjection = LProjection * LView;
  glEnable(GL_DEPTH_TEST);

  ...CUBE3D

glBindFramebuffer(GL_FRAMEBUFFER,0);

GLuint atach1 = GL_COLOR_ATTACHMENT0;
glBindFramebuffer(GL_FRAMEBUFFER,fboBuffer);
  glDrawBuffers(1,&atach1);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glViewport(0,0,640,480);
  Projection = glm::perspective(45.0f,1.333333f,0.01f,1000.0f);
  View = glm::lookAt(glm::vec3(0.0f,0.0f,3.0),glm::vec3(0.0f,0.0f,-15.0f),glm::vec3(0.0f,1.0f,0.0f));
  ViewProjection = Projection * View;
  glEnable(GL_DEPTH_TEST);

  ...CUBE3D

glBindFramebuffer(GL_FRAMEBUFFER,0);   

glUniform1i(uniforTEX,0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,GL_DEPTH_MAP);

  ...DO NOT DRAW NOTHING

glBindTexture(GL_TEXTURE_2D,0);

I need to do it in that order. Because the first "pass" is for the use of the depth map in a shadow map. What am I doing wrong?


Solution

  • GL_DEPTH_ATTACHMENT is not valid for glDrawBuffers. glDrawBuffers of buffers into which outputs from the fragment shader data will be written.

    When you do

    GLuint atach0 = GL_DEPTH_ATTACHMENT;
    glBindFramebuffer(GL_FRAMEBUFFER,fboBuffer);
    

    then you'll get a GL_INVALID_ENUM error.

    If you don't want to wirte to the depth map, then disable the depth test of use glDepthMask. The depth buffer attachment can't be switched on and off and it can't be uses somehow like a color buffer.

    Further

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    

    will clear the depth buffer in any case.

    I think there is a basic misunderstanding how the framebuffers for a shadow map have to be set up. You'll need a framebuffer for the shadow map only. This framebuffer has to have a depth buffer only.

    You have to do mit somehow like this:

    GLuint fboShadow;      // framebuffer with depth buffer only (shadow map)
    GLuint toShadowDepth;  // texture which is the depth buffer of `fboShadow`
    
    glBindFramebuffer(GL_FRAMEBUFFER, fboShadow);
    GLuint atach0 = GL_NONE;
    glDrawBuffers(1, &atach0);
    glClear(GL_DEPTH_BUFFER_BIT);
    
    glEnable(GL_DEPTH_TEST);
    glViewport(auxrecX, auxrecY, auxrcAn, auxrcAl);
    
    // draw the shadow map to the depth buffer only
    
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
    
    glEnable(GL_DEPTH_TEST);
    glViewport(0, 0, 640, 480);
    
    glUniform1i(uniforTEX, 0);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, toShadowDepth);
    
    // draw the geometry to the default framebuffer by using the depth map