在OpenGL中渲染网格作为一系列子组?

fis*_*ood 2 opengl shader wavefront .obj

我正在完成一个波前对象解析器,我想用它来构造泛型网格对象.我的引擎使用OpenGL 4和着色器绘制引擎中的所有内容.

我的问题是如何确保渲染网格的最佳渲染效率.

波前obj文件通常具有指定的许多对象的子组.

可以为子组分配特定材料(例如闪亮的红色).

因此,网格可能是一个相当复杂的子组集合,每个子组都分配了自己的材料.

我的问题是 -

问:我是否需要单独绘制每个子组,例如每个子组调用glDrawElements?(所以,如果我有4个独立的子组,我必须进行四次glDrawElements调用,从而通过4次统一更改(对于材质/纹理)调用着色器4次)

glDrawElements( GL_TRIANGLES, nNumIndicesInGroup, GL_UNSIGNED_INT, ((char*)NULL)+ first-vertex-offset );
Run Code Online (Sandbox Code Playgroud)

如果这是正确的,那么我将不得不计算:

每个子组中的索引(表示每个子组的单独索引数组和VAO)子组开始的顶点偏移量

这看起来非常低效,我咆哮错了树吗?

另外,从Wavefront obj wiki页面:

Smooth shading across polygons is enabled by smoothing groups.
 s 1
 ...
  # Smooth shading can be disabled as well.
  s off
  ...
Run Code Online (Sandbox Code Playgroud)

任何人都可以建议平滑阴影值表示什么?例如s1,s2,s4等

Luc*_*uca 9

是的,您应该将每个子组与其他子组分开绘制.这是必需的,直到子组之间的状态不同.

但是你迈出了太长的一步.

要避免多次绘制调用,可以引入顶点属性,指示用于访问统一数组值的索引(材质数组,纹理数组).这样,您只需要一次绘制调用,但是您将获得一个额外属性及其相对管理的成本.

我会避免上述方法.如果一个子组有纹理而另一个没有纹理怎么办?你怎么辨别是否纹理?介绍其他属性?似乎令人困惑.

第一点是缓冲对象管理非常灵活.实际上,您可以拥有单个元素缓冲区对象和单个顶点缓冲区对象:使用偏移和交错可以满足各种复杂程度.然后,在现代硬件上,使用顶点数组对象可以最大限度地降低不同缓冲区绑定的成本.

第二点是您的软件可以将具有相同统一状态的不同子组分组,将多个绘制调用连接成一个.请记住,您可以使用绘图入口点变体,还有可以帮助您的原始重启(在剥离基元的情况下).

其他考虑因素并不重要,因为无论如何,无论是否复杂,您都必须进行绘制.接下来,当您有正确的渲染时,您可以分析应用程序和渲染,切断热点.


平滑组是共享相同选项属性(法线,纹理坐标)的顶点集合.这是元素索引顶点的情况.

要深入了解主题,请阅读google搜索找到的规范之一.