适当使用GLKBaseEffect
哎呀!
我一直在考虑更新一些旧的测试代码,试图重温 GLKit 中添加的新功能。到目前为止,我已经成功设置了 GLKViewController 并开始渲染一些基本形状,但一直在努力寻找有关 GLKBaseEffect 的任何合适的信息。
GLKBaseEffect 文档指出:
在初始化时,您的应用程序首先创建一个 OpenGL ES 2.0 上下文并将其设置为当前上下文。然后,它分配并初始化一个新的效果对象,配置其属性,并调用其prepareToDraw方法。绑定效果会导致着色器被编译并绑定到当前 OpenGL ES 上下文。基本效果还需要应用程序提供顶点数据。要提供顶点数据,请创建一个或多个顶点数组对象。对于着色器所需的每个属性,顶点数组对象应启用该属性并指向存储在顶点缓冲区对象中的数据。
我正在努力辨别的是;
我渲染的每个“模型”都需要一个 GLKBaseEffect 对象吗?或者我是否为每个“场景”使用单个 GLKBaseEffect,并在调用prepareToDraw 之前动态更改属性?
我看过一些关于游戏引擎和渲染器的教程,它们只是为每个模型使用单个 GLKBaseEffect,但如果可以通过单个实例来实现相同的效果,那么这似乎完全低效。
从阅读文档来看,这似乎是最好的方法,但考虑到我见过很多人使用多个实例,我开始认为情况并非如此。
谁能阐明这一点? GLKit 对于 iOS(以及对我来说)仍然相当新,因此我们将不胜感激任何信息。
Ahoy!
I've been looking into updating some old test code in an attempt to brush up on the new features added to GLKit. So far i've managed to set up a GLKViewController and start rendering some basic shapes but have struggled to find any decent information regarding GLKBaseEffect.
The GLKBaseEffect documentation states:
At initialization time, your application first creates an OpenGL ES 2.0 context and makes it current. Then, it allocates and initializes a new effect object, configures its properties, and calls its prepareToDraw method. Binding an effect causes a shader to be compiled and bound to the current OpenGL ES context. The base effect also requires vertex data to be supplied by your application. To supply vertex data, create one or more vertex array objects. For each attribute required by the shader, the vertex array object should enable the attribute and point to data stored in a vertex buffer object.
What i'm struggling to discern is;
Do I need a GLKBaseEffect object for each "model" I'm rendering? Or do I use a single GLKBaseEffect for each "scene" and simply change the properties on the fly before calling prepareToDraw?
I've seen a few tutorials for game engines and renderers that simply use a single GLKBaseEffect for each model but this seems wholly inefficient if the same could be achieved with a single instance instead.
From reading the documentation it almost seems like this is the best approach but considering i've seen so many people using multiple instances, i'm starting to think that this isn't the case.
Can anyone shed any light on this? GLKit is still fairly new to iOS (and to me) so any information would be greatly appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不,您不应该为每个对象创建唯一的 GLKBaseEffect。例如,如果您正在绘制一个迷宫,则该迷宫中的每个砖块可能都是其自己的对象,但它们都可以共享相同的 GLKBaseEffect。但请记住,GLKBaseEffect 还存储位置信息以及纹理、光照、雾等信息。因此,如果您想在多个位置绘制砖块(我假设您这样做:-),您可以调整它们的变换矩阵,然后调用“prepareToDraw”API。
我同意我们需要更多由广泛使用 GLKBaseEffect 的人编写的教程,以获取有关此新框架最佳实践的更多信息。
快乐航行..
No, you should not create a unique GLKBaseEffect for each object. For example, if you are drawing a maze, each brick in that maze may be its own object, but they can all share the same GLKBaseEffect. Remember though, that GLKBaseEffect also stores information in location as well as texture, lighting, fog etc. So if you want to draw the bricks in more than one place (which I assume you do :-) you tweak their transformation matrix and then call the 'prepareToDraw' API.
I agree we need more tutorials written by folks who have used GLKBaseEffect extensively to get more information on Best Practices for this new framework.
Happy sailing..
“基本”属性(lightingType、lightModelTwoSided、colorMaterialEnabled...)的每次更改都将导致在下一个“prepareToDraw”调用中加载新的着色器程序。
因此,如果您不使用渲染顺序,那么无论您对每个渲染对象使用一种效果还是对所有对象使用单一变化效果,都没有什么关系。在这两种情况下,您最终都会得到不必要的 glUseProgram 调用以及每个绘制对象的大量不必要的 OpenGL 状态更改。 (使用仪器的“OpenGL ES 分析”模板来研究生成的 OpenGL 调用)
也就是说,您的主要关注点应该是命令对象进行渲染。至少将使用相同着色器程序的所有对象分组。然后为每个组创建并使用一个 GLKBaseEffect 对象。
如果您不确定 GLKBaseEffect 属性更改是否会导致加载新的着色器程序,那么我建议使用 Instruments 来调查 OpenGL 调用。
Each change of the "fundamental" properties (lightingType, lightModelTwoSided, colorMaterialEnabled, ...) will cause a new shader program to be loaded with the next "prepareToDraw" call.
So if you don't use a rendering order then it pretty much doesn't matter if you use one effect for each rendered object or a single changing effect for all objects. In both cases you will end up with an unnecessary glUseProgram call and lots of unnecessary OpenGL state changes for each object drawn. (use the "OpenGL ES Analysis" template of instruments to investigate the generated OpenGL calls)
That said, your primary conern should be to order your objects for rendering. At least group all objects that use the same shader program. Then create and use one GLKBaseEffect object for each of those groups.
If you're not sure if a GLKBaseEffect property change will cause a new shader program being loaded then I recommend using Instruments to investigate the OpenGL calls.