GLKBaseEffect的适当使用方法

3
啊嗨!
我一直在研究更新一些旧的测试代码,试图熟悉GLKit添加的新功能。到目前为止,我已成功地设置了一个GLKViewController并开始渲染一些基本形状,但我还是找不到关于GLKBaseEffect的任何好的信息。
GLKBaseEffect文档如下:
“在初始化时,您的应用程序首先创建一个OpenGL ES 2.0上下文并将其设为当前。然后,它分配并初始化一个新的effect对象,配置其属性,并调用其prepareToDraw方法。绑定效果会导致着色器被编译并绑定到当前的OpenGL ES上下文中。基本效果还需要您的应用程序提供顶点数据。要提供顶点数据,请创建一个或多个顶点数组对象。对于着色器所需的每个属性,顶点数组对象都应该启用该属性并指向存储在顶点缓冲区对象中的数据。”
我现在很困惑的是:
对于我正在渲染的每个“模型”,我是否需要一个GLKBaseEffect对象?或者我只需要为每个“场景”使用单个GLKBaseEffect,在调用prepareToDraw之前随时更改属性即可?
我看过一些游戏引擎和渲染器的教程,它们只是为每个模型使用单个GLKBaseEffect,但如果可以使用单个实例实现相同的功能,那么这似乎非常低效。
从文档中阅读起来,似乎这是最好的方法,但考虑到我已经看到很多人使用多个实例,我开始认为这并不是这种情况。
有人可以解释一下吗?GLKit对iOS(以及对我)来说仍然是相当新的技术,所以任何信息都将不胜感激。

有没有人广泛使用GLKBaseEffect,可以提供一些见解?如果使用单个实例还是需要多个实例,我对性能提升很感兴趣。我将编写一个测试应用程序,并发布我的结果,以供有兴趣的人参考。 - Zack Brown
2个回答

5
不,你不应该为每个对象创建一个唯一的GLKBaseEffect。例如,如果你正在绘制迷宫,迷宫中的每个砖块可能是它自己的对象,但它们都可以共享同一个GLKBaseEffect。请记住,GLKBaseEffect还存储位置、纹理、光照、雾等信息。因此,如果你想在多个地方绘制砖块(我想你是这样做的:-),你需要调整它们的变换矩阵,然后调用“prepareToDraw”API。
我认为我们需要更多由使用GLKBaseEffect进行广泛使用的人编写的教程,以获得有关这个新框架的最佳实践的更多信息。
祝愉快!

1
太棒了。我之前看到的方法并不完全正确。我开始编写测试场景,一个单一实例已经足够了。感谢您的回复 :) - Zack Brown

4
每次更改“基本”属性(lightingType、lightModelTwoSided、colorMaterialEnabled等)都会在下一次“prepareToDraw”调用时加载新的着色器程序。
因此,如果您不使用渲染顺序,则使用一个效果来渲染每个对象或使用单个变化效果来渲染所有对象几乎没有区别。在这两种情况下,每个绘制对象都会产生不必要的glUseProgram调用和大量不必要的OpenGL状态更改。(使用仪器的“OpenGL ES分析”模板来调查生成的OpenGL调用)
话虽如此,您的主要关注点应该是为了渲染您的对象而进行排序。至少将所有使用相同着色器程序的对象分组。然后为每个组创建并使用一个GLKBaseEffect对象。
如果您不确定GLKBaseEffect属性更改是否会导致加载新的着色器程序,则建议使用Instruments来调查OpenGL调用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接