iDevGames Forums
EXC_BAD_ACCESS with gluBuild2DMipmaps - Printable Version

+- iDevGames Forums (http://www.idevgames.com/forums)
+-- Forum: Development Zone (/forum-3.html)
+--- Forum: Graphics & Audio Programming (/forum-9.html)
+--- Thread: EXC_BAD_ACCESS with gluBuild2DMipmaps (/thread-3122.html)



EXC_BAD_ACCESS with gluBuild2DMipmaps - Marjock - Aug 4, 2007 09:45 PM

NOTE: I believe the problem to be fixed now. See the next post for an explanation.

Hi guys,

I'm choosing to post this here, on the grounds that the error happens during the gluBuild2DMipmaps call, although I doubt it's actually overly related to OpenGL.

A few weeks (months?) ago, somebody gave me their texture loading class, which I altered slightly (largely just so that it uses mipmaps) and have used a couple of times since. However, in my latest project, I'm quite clearly doing something very wrong, as I get the following two occurrances when using this class:

1. When I Build and Run the program, it attempts to open, and then the debugger opens, displaying an EXC_BAD_ACCESS error, which seems to be somewhere in the middle of the gluBuild2DMipmaps() call.

2. If I place an NSLog() a few lines above this (I originally did this just to check a couple of values without using the debugger), the program Builds and Runs fine, and no error occurs. I don't understand this at all, and it leads me to believe that I'm doing something very wrong, somewhere along the way, but can't seem to figure out where.

Here's the texture loading method, and below it is a link to a screenshot of the debugger window when the program crashes.

Code:
- (id)initWithImageAtPath:(NSString*)filePath {
    self = [super init];
    
    if (![[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
        NSLog(@"Can't find image %@", [filePath lastPathComponent]);
        return 0;
    }
    
    CFURLRef texture_url = CFURLCreateWithFileSystemPath (   NULL,
                                                                  (CFStringRef)filePath,
                                                       kCFURLPOSIXPathStyle,
                                                    NO
                                                     );
        
    CGImageSourceRef image_source = CGImageSourceCreateWithURL( texture_url,
                                                               NULL);
    assert(CGImageSourceGetCount(image_source) > 0);
    
    CGImageRef image = CGImageSourceCreateImageAtIndex(image_source,
                                                       0,
                                                       NULL);
    
    width = CGImageGetWidth(image);
    height = CGImageGetHeight(image);
    
    void *data = malloc(width * height * 4);
    
    CGColorSpaceRef color_space = CGColorSpaceCreateDeviceRGB();
    
    CGContextRef context = CGBitmapContextCreate(data,
                                             width,
                                             height,
                                             8,
                                             width * 4,
                                             color_space,
                                             kCGImageAlphaPremultipliedFirst);
    
    CGContextDrawImage(context,
                       CGRectMake(0, 0, width, height),
                       image);
    
    vImage_Buffer normal, flipped;
    
    normal.data = data; // The data buffer you used for creating the CGContextRef
    normal.height = height;
    normal.width = width;
    normal.rowBytes = width * 4;
    
    flipped.data = malloc(4 * height * width);
    flipped.height = height;
    flipped.width = width;
    flipped.rowBytes = width * 4;
    
    vImage_Error error = vImageVerticalReflect_ARGB8888(&normal, &flipped, 0);
    if(error != kvImageNoError)
    {
        assert(error != kvImageNoError);
    }
    free(data);
    data = flipped.data;
    
    /******       NSLog(@"If I put an NSLog here, then the program builds and runs fine.");      ********/
    glGenTextures(1, &textureID);
    
    glBindTexture(GL_TEXTURE_2D, textureID);
    
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    
    GLfloat fLargest;
    glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &fLargest);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, fLargest);
    
    gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
    
    CFRelease(context);
    CFRelease(color_space);
    free(data);
    CFRelease(image);
    CFRelease(image_source);
    CFRelease(texture_url);
    
    return self;
}

Debugger:
http://img.photobucket.com/albums/v174/Marjock/error.png

If you need any more information or code snippets, don't hesitate to ask.

Thanks in advance,
Mark


EXC_BAD_ACCESS with gluBuild2DMipmaps - Marjock - Aug 4, 2007 11:05 PM

EDIT: But wait, I was wrong here too! Keep scrolling down to find out the real reason.

Okay, upon advice from #idevgames and OneSadCookie, I swapped the gluBuild2DMipmaps for a glTexImage2D, and the problem went away. OneSadCookie informs me gluBuild2DMipmaps are "notoriously flaky" and that I should use SGIS_generate_mipmaps instead, so I shall attempt to do that.


EXC_BAD_ACCESS with gluBuild2DMipmaps - OneSadCookie - Aug 4, 2007 11:46 PM

That said, I thought gluBuild2DMipmaps had been fixed since 10.4, at least. If it's really the cause of the problem (as opposed to some other random memory trasher elsewhere in the code), then it deserves a bug filed.


EXC_BAD_ACCESS with gluBuild2DMipmaps - Marjock - Aug 5, 2007 01:38 AM

Okay, as it turns out I was trying to load my textures too early (I was calling my load texture method in -awakeFromNib).
I have since shifted the call to -prepareOpenGL, and everything works smoothly now.

Apologies for the time I've wasted with this one,
Mark