c - 如何使用 OpenGL 按特定顺序绘制贴花?

标签 c opengl 3d

为了绘制贴花,我目前正在使用 glPolygonOffset(-1,-1),当我通过捏造来绘制贴花时,这使我摆脱了一些丑陋的 z-fighting 伪像贴花的 zbuffer 值,就好像贴花的多边形更靠近相机一样。我还认为我可以将 glPolygonOffset 与各种参数一起使用,以相对于彼此对贴花进行排序,但这似乎会根据相机角度进行调整,因此整个贴花最终会相互交换顺序当我四处移动相机时。

我尝试过的另一种方法位于本文档的此处:"Making Decals"

  1. Disable the depth buffer for writing, and render A.
  2. Enable the depth buffer for writing, and render B.
  3. Disable the color buffer for writing, and render A again.
  4. Enable the color buffer for writing.

这是我的尝试,但我真的不明白如何扩展它以相对于彼此按顺序绘制贴花,因为贴花是在启用深度缓冲区进行写入时绘制的,我不只是获得更多 z 战斗?

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 中订购此类贴花的教程。也许我只是使用了错误的搜索词?这个过程还有别的名字吗?

最佳答案

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

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

当然,在您的 glPolygonOffset 变得如此之大以至于您的贴花出现在它们不应该出现的东西前面之前,您可以用这种方式绘制的贴花数量是有限制的。

关于相机角度的事情:glPolygonOffsetfactor 参数应该为高角度的多边形添加额外的软糖。

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

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

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

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

关于c - 如何使用 OpenGL 按特定顺序绘制贴花?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10942188/

相关文章:

c - 共享缓冲区和同步编程的问题

c++ - 英特尔核芯显卡 3000 Opengl 3.2

python - 访问 3D numpy 数组的切片

python - 如何在 Python 中绘制 3D 地球?

php - Hook 到脚本的运行时

c - 从文件读取到 C 中的 int 缓冲区

c - 在 C 代码中从队列中读取给定元素

opengl - 访问任何与 GLEW 相关的内容都会立即导致 MinGW 中的程序崩溃

opengl - freeglut 与 glew 的区别?

jQuery/CSS3 - 不断 3d 翻转 5 div?