iosopengl-eseaglview

Multiple EAGLViews but only one copy of each texture - how?


I have an app running on iPad which is using lots of textures, rendering into one EAGLView. Now I need a second EAGLView, sharing textures with the first.

I can get both views rendering fine, in parallel, on screen, by fixing some design mistakes in Apple's code (e.g. the default ViewController needs some tweaks to support multiple child EAGLView objects). But I can't get the textures to be shared.

I cannot duplicate the textures (that would double memory usage - and we're using most of the mem already).

I can't find any documentation from Apple on how to share textures between multiple EAGLView's - there are "hints" that this is what EAGLShareGroup is for, allowing each GLView to have its own context, but the two contexts to share a ShareGroup - but nothing explicit that I could find.

I've tried following the answer to this question: Textures not drawing if multiple EAGLViews are used

...but it wasn't really an answer. It pointed to EAGLSharegroup without actually explaining how to use it - it seems to make no difference at all. It also pointed indirectly to a page about rendering from multiple threads - which is a completely different problem, and I don't have any of the problems listed there (app crashes etc).


Solution

  • It turns out that Apple's undocumented EAGLShareGroup ( http://developer.apple.com/library/ios/#documentation/OpenGLES/Reference/EAGLSharegroup_ClassRef/Reference/EAGLSharegroup.html ) ... cannot be instantiated without knowing its secret init method(s).

    I have no idea what that is - it's undocumented - but you can get an EAGLContext to instantiate the first sharegroup for you, and then make that your shared, global sharegroup.

    So, the following will never work:

    EAGLShareGroup *group = [[EAGLShareGropu alloc] init];
    EAGLContext *context1 = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup:group];
    EAGLContext *context2 = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup:group];
    

    HOWEVER, the following works perfectly:

    EAGLContext *context1 = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
    EAGLContext *context2 = [[EAGLContext alloc] initWithAPI:[context1 API] sharegroup:context1.sharegroup];
    

    (edited to make context2 use context1's API too - as per Apple's ES programming guide, as per Pivot's comment)