Question

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.

Was it helpful?

Solution

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..

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top