I have an OpenGL ES application for the iPhone I am developing, being a port of a 2d-oriented application from another platform. I have chosen to render the graphics using OpenGL ES for performance reasons. However, the main application runs on a separate thread (due to the original application design), so from within my app delegate I do this:
- (void) applicationDidFinishLaunching:(UIApplication *)application {
CGRect rect = [[UIScreen mainScreen] bounds];
glView = [[EAGLView alloc] initWithFrame:rect];
[window addSubview:glView];
// launch main application in separate thread
[NSThread detachNewThreadSelector:@selector(applicationMainThread) toTarget:self withObject:nil];
}
However, I notice that any calls within the applicationMainThread that try to render something to the screen do not render anything, until that thread terminates.
I set up the actual OpenGL ES context on the child application thread, not the UI thread. If I do this:
- (void) applicationMainThread {
CGRect rect = [[UIScreen mainScreen] bounds];
[glView createContext]; // creates the open GL ES context
//Initialize OpenGL states
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glMatrixMode(GL_PROJECTION);
glOrthof(0, rect.size.width, 0, rect.size.height, -1, 1);
glMatrixMode(GL_MODELVIEW);
Texture2D *tex = [[Texture2D alloc] initWithImage:[UIImage imageNamed:@"iphone_default.png"]];
glBindTexture(GL_TEXTURE_2D, [tex name]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glDisable(GL_BLEND);
[tex drawInRect:[glView bounds]];
glEnable(GL_BLEND);
[tex release];
[glView drawView];
}
Then the texture is updated to the screen pretty much immediately, as I would expect.
However, if after the [glView drawView] call I add this one line:
[NSThread sleepForTimeInterval:5.0]; // sleep for 5 seconds
Then the screen is only updated after the 5 second delay completes. This leads me to believe that the screen only updates when the thread itself terminates (need to do more testing to confirm). This means that when I substitute the actual application code, which does multiple screen updates, none of the updates actually happen (leaving a white screen) until the application thread exits, not exactly what I wanted!
So - is there any way I can get around this, or have I done something obviously wrong?