首页 文章

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

提问于
浏览
2

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

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

wavefront .obj file通常指定了许多对象子组 .

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

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

我的问题是 -

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

glDrawElements( GL_TRIANGLES, nNumIndicesInGroup, GL_UNSIGNED_INT, ((char*)NULL)+ first-vertex-offset );

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

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

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

另外,从Wavefront obj wiki page

Smooth shading across polygons is enabled by smoothing groups.
 s 1
 ...
  # Smooth shading can be disabled as well.
  s off
  ...

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

1 回答

  • 9

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

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

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

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

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

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

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


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

    要深入了解主题,请阅读通过谷歌搜索找到的specification之一 .

相关问题