0

I'm having some issues using the same EAGLContext across EAGLViews. I have two View Controllers, each one has one EAGLView.

Each View Controller allocates a new EAGLContext, and a subsequent framebuffer/colorbuffer is created for each respective EAGLView, but this is a waste of memory resources.

I know that it is possible to use the same EAGLContext across ViewControllers by simply binding different framebuffers/colorbuffers to different EAGLViews:

Using Multiple OpenGL Views And UIKit

But i didnt manage to achieve that so far.

Any ideas?

Thanks in advance.

DShah
  • 9,768
  • 11
  • 71
  • 127

2 Answers2

1

Finally managed to solve the problem.

In one of the view controllers i was using:

dispatch_async(openGLESContextQueue, ^{

        [(EAGLView *)self.view setFramebuffer];

        (...opengl draw code...)

        [(EAGLView *)self.view presentFramebuffer];

    });

When using EAGLContext in a multithreading environment one must be cautious to prevent other threads from accessing it at the same time using:

@syncronized(context) { ...opengl drawing here...}

and to drain the current dispatch_queue before passing control to another ViewController (through presentViewController:), using:

dispatch_sync(openGLESContextQueue, ^{});

So, by using these two tricks i was able to just use one EAGLContext across multiple views. One must also pay extra attention to the current state of the EAGLContext. I was having unexpected results because in the first view i had:

glVertexPointer(2, GL_FLOAT, 0, squareVertices);
glEnableClientState(GL_VERTEX_ARRAY);
glColorPointer(4, GL_UNSIGNED_BYTE, 0, squareColors);
glEnableClientState(GL_COLOR_ARRAY);

In the second view i had completely different drawing code, and i forgot to, of course, use:

glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);

And voilá!

Thanks :)

0

EAGLView isn't actually a single class; it's a family of classes with the same name that Apple tend to throw into their example files. So it's relatively difficult to advise on specific modifications.

My initial solution was to create a singleton class that vends a single, shared EAGLContext. EAGLContexts can be used on only one thread at a time so that's not necessarily a complete solution, but exactly what you want to do will probably depend on the semantics of your program and feels like a different topic from your actual question.

The Xcode 4.1 'OpenGL ES Application' template has context creation outside of the view, whereas I think it was previously inside, which makes things a little easier.

Tommy
  • 99,986
  • 12
  • 185
  • 204
  • I've implemented EAGLContext sharing between the two viewcontrollers via delegation (but could be a singleton class too), and everything works fine when i perform presentviewcontroller to exhibit the second view controller, but when i come back to the first - via dismiss - any opengl instruction here raises a BAD_ACCESS exception :( – Nuno Miguel Fonseca Oct 04 '11 at 12:58
  • I even implemented semaphores to make sure the shared EAGLContext doesn't get multiple accesses at the same time, but it didn't solve the problem. Interestingly enough, in the simulator everything works fine. Weird isn't it? – Nuno Miguel Fonseca Oct 04 '11 at 13:01
  • Are you actually thread hopping? If not then semaphores shouldn't be necessary — everything will be on the main thread, in the normal run loop. It might be worth turning on zombies to confirm or deny that the context is staying alive. Or subclass EAGLView with implementations of `retain`, `release`, `dealloc` and `autorelease` that do nothing but call `super`, then use those as breakpoints to trap any mistreatment. – Tommy Oct 04 '11 at 15:20