views:

240

answers:

2

Hi All,

I'm trying to perform hidden line removal using polygon offset fill. The code works perfectly if I render directly to the window buffer but fails to draw the lines when passed through a FBO as shown below

alt text

The code I use to draw the objects

void drawCubes (GLboolean removeHiddenLines)
{
  glLineWidth(2.0);
  glPushMatrix();
    camera.ApplyCameraTransform();
    for(int i = 0; i < 50; i ++){
    glPushMatrix();
      cube[i].updatePerspective();
      glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
      glColor3f(1.0,1.0,1.0);
      cube[i].draw();
      glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

      if(removeHiddenLines){
          glEnable(GL_POLYGON_OFFSET_FILL);
          glPolygonOffset(1.0, 1.0);
          glColor3f(1.0, 0.0, 0.0);  //fill polygons for hidden line removal
          cube[i].draw();
          glDisable(GL_POLYGON_OFFSET_FILL);
      }
    glPopMatrix();
  }
  glPopMatrix();
}

For this example, the first pass involves rendering to both the window buffer and a FBO.

void firstPass()
{
  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glViewport(0, 0, fboWidth, fboHeight);

  glEnable(GL_DEPTH_TEST);
  glDisable(GL_TEXTURE_2D);
  drawParticleView(GL_TRUE);
  glDisable(GL_DEPTH_TEST);

  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebufferID[1]);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glViewport(0, 0, fboWidth, fboHeight);

  glEnable(GL_DEPTH_TEST);
  glDisable(GL_TEXTURE_2D);
  drawParticleView(GL_TRUE);
  glDisable(GL_DEPTH_TEST);
}

Second pass renders FBO back to window buffer.

void secondPass()
{
  glEnable(GL_TEXTURE_2D);

  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
  glBindTexture(GL_TEXTURE_2D, renderTextureID[0]);

  glViewport(fboWidth, 0, fboWidth, fboHeight);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();

  glBegin(GL_QUADS);
    glTexCoord2i(0, 0);
    glVertex2f(-1.0f, -1.0f);
    glTexCoord2i(1, 0);
    glVertex2f(1.0f, -1.0f);
    glTexCoord2i(1, 1);
    glVertex2f(1.0f, 1.0f);
    glTexCoord2i(0, 1);
    glVertex2f(-1.0f, 1.0f);
  glEnd();

  glDisable(GL_TEXTURE_2D);
}

Setup FBO's

void setupRC()
{
  setupTextures();
  glGenFramebuffersEXT(2, framebufferID);

  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebufferID[0]);
  glGenRenderbuffersEXT(1, &renderbufferID);
  glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, renderbufferID);
  glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT32, fboWidth, fboHeight);
  glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, renderbufferID);
  glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, renderTextureID[0], 0);
  GLenum fboStatus = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
  if(fboStatus != GL_FRAMEBUFFER_COMPLETE_EXT){
    fprintf(stderr, "FBO #1 Error!");
  }
  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebufferID[1]);
  glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, renderTextureID[1], 0);
  fboStatus = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
  if(fboStatus != GL_FRAMEBUFFER_COMPLETE_EXT){
     fprintf(stderr, "FBO #2 Error!");
  }
  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}

Setup textures

void setupTextures(void)
{
  glGenTextures(2, renderTextureID);

  for (GLint i = 0; i < 2; i++){
    glBindTexture(GL_TEXTURE_2D, renderTextureID[i]);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    // this may change with window size changes
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, fboWidth, fboHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
  }
  glBindTexture(GL_TEXTURE_2D, 0);
}

I don't understand why the two views wouldn't be the same? Am I missing something (obviously I am)?
Thanks

A: 

Your code seems ok to me. The weird stuff is that you still have the red cube drawn, but not the lines... What is your OpenGL implementation, driver version?

Can you test without enabling GL_POLYGON_OFFSET_FILL and/or glLineWidth to see if you see the lines (albeit hidden parts visible)?

Stringer Bell
OpenGL version string: 2.1.2 NVIDIA 185.18.36. I've tested without GL_POLGON_OFFSET_FILL and get wireframe cubes with hidden lines as expected. Also tried without glLineWidth and same thing happens.
Brett
+1  A: 

The problem is that I was rendering to a FBO without a depth attachment. Setting up the second FBO the same as the first gave the correct results.

Brett
Strange, I think that " glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT32, fboWidth, fboHeight); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, renderbufferID);" was sufficient to ahve depth buffer.
Luca