views:

3107

answers:

5

I have an iphone app where I call these three functions in appDidFinishLaunching:

glMatrixMode(GL_PROJECTION);
glOrthof(0, rect.size.width, 0, rect.size.height, -1, 1);
glMatrixMode(GL_MODELVIEW);

When stepping through with the debugger I get EXC BAD ACCESS when I execute the first line. Any ideas why this is happening?

Btw I have another application where I do the same thing and it works fine. So I've tried to duplicate everything in that app (#imports, adding OpenGLES framework, etc) but now I'm just stuck.

+2  A: 

I've seen this error in many different situations but never specifically in yours. It usually comes up as a result of the application trying to access memory that has already been released.

Can you confirm that rect is still allocated?

Brian
+3  A: 

I've run into this with OpenGL calls if two threads are attempting to draw to the OpenGL scene at once. However, that doesn't sound like what you're doing.

Have you properly initialized your display context and framebuffer before this call? For example, in my UIView subclass that does OpenGL drawing, I call the following in its initWithCoder: method:

context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];

if (!context || ![EAGLContext setCurrentContext:context] || ![self createFramebuffer]) 
{
    [self release];
    return nil;
}

The createFramebuffer method looks like the following:

- (BOOL)createFramebuffer 
{   
    glGenFramebuffersOES(1, &viewFramebuffer);
    glGenRenderbuffersOES(1, &viewRenderbuffer);

    glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
    [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer];
    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);

    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);

    if (USE_DEPTH_BUFFER) {
     glGenRenderbuffersOES(1, &depthRenderbuffer);
     glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
     glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight);
     glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);
    }

    if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) 
    {
     return NO;
    }

    return YES;
}

This is pretty much boilerplate code, as generated by the OpenGL ES Application template in XCode. Perhaps by not initializing things before calling glMatrixMode(), you're getting a crash.

Also, why are you doing OpenGL drawing in applicationDidFinishLaunching:? Wouldn't a view or view controller be a more appropriate place for OpenGL calls than your UIApplicationDelegate?

Brad Larson
It might be because Apple's demo application, CrashLanding does it that way.
xyz
+1  A: 

You need to replace the current matrix with the identity matrix before calling glOrthof. This can be done with glLoadIdentity()

+1  A: 

Unlikely to be the problem given the date on which you submitted the bug, but you'd also see something like this if you use the Apple example code and run on an ES 2.0 capable device, as it removes the matrix stack from the spec, though the function definitions will remain visible to the compiler since the device also supports ES 1.1.

Thom
+1  A: 

Restart the iPhone Simulator. This issue is definitely due to the OpenGL context not being set properly. I found that sometimes the iPhone Simulator has issues and needs to be restarted for the OpenGL context to get set properly by [EAGLContext setCurrentContext:].

devinkb
I was also getting this error and couldn't figure out why. I found this page through google. Then I took a closer look at my code and realized that I was initializing the context with ES 2.0, but using my ES 1.1 renderer to display. Oops.
Christine