如何使用OpenGL以特定顺序绘制贴花?

时间:2012-06-08 01:56:09

标签: c opengl 3d

为了绘制贴花我现在正在使用glPolygonOffset(-1,-1),当我通过捏碎贴花的zbuffer值来绘制我的贴花时,这让我想起了一些丑陋的z-fighting文物,好像贴花一样多边形更接近相机。我还认为我可以使用glPolygonOffset与各种论点相对于彼此对贴纸进行排序,但这似乎是根据摄像机角度进行调整,因此当我移动时,整个贴花最终会相互交换顺序相机周围。

我玩过的另一种方法是在本文档的下面:"Making Decals"

  
      
  1. 禁用深度缓冲区进行写入,然后渲染A.
  2.   
  3. 启用深度缓冲区进行写入,并渲染B。
  4.   
  5. 禁用用于书写的颜色缓冲区,并再次渲染A.
  6.   
  7. 启用颜色缓冲区进行书写。
  8.   

这是我对此的尝试,但我真的不明白如何扩展这些相对于彼此的顺序绘制贴花,因为当深度缓冲区启用写入时绘制贴花,我不会得到更多的战斗?

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);  
glEnable(GL_BLEND);

//Render a red solid quad on the color mask
glDepthMask(false);
glColor3f (1.0f, 0.0f, 0.0f);
glBegin (GL_QUADS);
    glVertex2f(-1,-1);
    glVertex2f(-1,1);
    glVertex2f(1,1);
    glVertex2f(1,-1);
glEnd ();

//Render the coincident decal, a transparent square works fine for now
glDepthMask(true);
glColor4f(0.0f, 1.0f, 0.0f, 0.5f);
glTranslatef(0, 1, 0.0f);
glScalef(0.5f, 0.5f, 0.5f);
glBegin (GL_QUADS);
    glVertex2f(-1,-1);
    glVertex2f(-1,1);
    glVertex2f(1,1);
    glVertex2f(1,-1);
glEnd ();

//Render the red quad again but only on the depth buffer
glColorMask(false, false, false, false);
glLoadIdentity();
glColor3f(1.0f, 0.0f, 0.0f);
glBegin (GL_QUADS);
    glVertex2f(-1,-1);
    glVertex2f(-1,1);
    glVertex2f(1,1);
    glVertex2f(1,-1);
glEnd ();
glColorMask(true, true, true, true);

这似乎是在大多数游戏中都要做的事情,所以我确信我有更好的解决方案。但是,我已经做了很多搜索,并且无法在openGL中提出任何用于订购这样的贴花的教程。也许我只是使用错误的搜索条件?这个过程还有另一个名字吗?

1 个答案:

答案 0 :(得分:2)

按照你的建议使用glPolygonOffset并且前后渲染事物可能会提供比其他选项更好的性能,因为它应该充分利用"早期的Z" GPU中的优化。

你可能想尝试将更大的数字传递给glPolygonOffset,例如(-4,-4)用于第一个贴花,( - 8,-8)用于第二个贴花,等等 - 它是不是一门精确的科学;)

当然,在glPolygonOffset变得如此之大以至于你的贴花出现在他们不应该做的事情之前,你可以用这种方式绘制多少贴花是有限的。

Re相机角度的事情:factor的{​​{1}}参数应该为高角度的多边形添加额外的软糖。

您可以尝试的另一种方法是:

  • 正常渲染所有常规几何体
  • 禁用深度写入(但启用深度测试)
  • glPolygonOffset
  • 从后到前绘制所有贴花

另一种可能更有效的方法:

  • 在帧开始时将模板缓冲区清除为0(同时清除其他缓冲区)
  • 正常渲染所有常规几何体
  • 禁用深度写入(但启用深度测试)
  • glPolygonOffset(-1, -1)
  • glPolygonOffset(-1, -1)glStencilFunc(GL_NOTEQUAL, 1, 1)
  • 从正面到背面绘制所有贴花