通过FBO后如何成功去除隐藏线?

发布于 2024-08-27 02:03:52 字数 4030 浏览 9 评论 0原文

我正在尝试使用多边形偏移填充执行隐藏线删除。如果我直接渲染到窗口缓冲区,但在通过 FBO 时无法绘制线条,则代码可以完美运行,如下所示

替代文字

我用来绘制对象的代码

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();
}

对于此示例,第一遍涉及渲染到窗口缓冲区和 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);
}

第二遍将 FBO 渲染回窗口缓冲区。

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);
}

设置 FBO 的

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);
}

设置纹理

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'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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夏天碎花小短裙 2024-09-03 02:03:52

问题是我在没有深度附件的情况下渲染到 FBO。按照与第一个 FBO 相同的方式设置第二个 FBO 可以得到正确的结果。

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.

黑凤梨 2024-09-03 02:03:52

你的代码对我来说似乎没问题。奇怪的是,你仍然绘制了红色立方体,但没有绘制线条......你的OpenGL实现是什么,驱动程序版本是什么?

您是否可以在不启用 GL_POLYGON_OFFSET_FILL 和/或 glLineWidth 的情况下进行测试,以查看是否看到线条(尽管隐藏部分可见)?

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)?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文