akb825
2005.08.17, 09:18 PM
This has got to be the weirdest thing EVER! I'm trying to make a game with a full screen graphics context. After getting that out, and trying to display a menu, it worked fine for a little while. Then, suddenly, it started crashing. Without changing anything major. It keeps on saying that I was accessing freed memory and the crash reporter usually gives me the line where I call glGenTextures, the debugger stopps where I free a C string. The problem is, I don't have anything else where I free it! Here's a walkthrough of what I did trying to track down the problem:
This C string is one that I'm constructing to open a texture. I malloc it, copy the bundle string, then concatenate the rest of the path. After that, I feed the string into my open TGA method, and free the string. The string is accessed twice: once to check to make sure it's not NULL, and once to open the file. That can't be a problem, but I comment it out anyway. Next, it crashes citing where I delete the TGA file after loading the texture (using glTexImage2D), saying where I set the pointer to NULL. Ok, I take that out. It then crashes pointing to the end of the function. I say WTF??? and comment out where I actually free the data, and it works. It also works when I just comment out my deleteTGA function. Neither of those should have done anything. The this class also contains Font classes which instantiate before hand it actually gets to the crash. It has a nearly identical method of opening my font texture, and if I comment out the string free and texture delete there, it usually works as well. At one point, I commented out all of my texture loading function calls, and it says I accessed freed memory when assigning an integer! (by the line number it gave me)
It gets even weirder. I commented out my capture display function calls, and ran through the debugger. It went through the instanciation of the menu class this is crashing in, it starts instanciating the fonts, goes to the malloc of the C string for accessing the font texture, then completely dies. When I look at the function calls, it suddenly jumped past all not only that font instanciation, but all the rest of them as well to where I freed the C string for opening the texture for the texture after all that is done.
When I comment out all the frees and deletes, it runs, but doesn't load one of the textures.
As a final test, I went into main.m, took out NSApplicationMainLoop, instanciated my controller, slept for 20 seconds, then quit. Lo and behold, it worked perfectly! Loaded all the textures and displayed the graphics perfectly, no malloc errors, NOTHING! I take it back out, and it crashes.
Edit: almost forgot to mention: at one point, I put in a print call, and it didn't crash! One of the textures didn't load, but it didn't crash. I took out the print statement, and it crashed again... Talk about weird. Not even accessing anything, just "cerr << "here\n";"
Here is all relevent code. I'm at a complete loss. I've been at this all day without avail. Hopefully somebody here with more cocoa experience can help me.
(mainWindow and eventView were added after trying most of this stuff, but made no difference)
AppController init (called first)
- (id)init
{
self = [super init];
if (self != nil)
{
[mainWindow makeKeyAndOrderFront:self];
appController = self;
gameView = [[GameView alloc] init];
[eventView lockFocus];
mainList = new DrawList;
Drawable *menu = new MainMenu;
mainList->insert(menu);
[gameView draw];
}
return self;
}
GameView init
- (id)init
{
self = [super init];
previousDisplay = CGDisplayCurrentMode(kCGDirectMainDisplay);
CGDisplayCapture(kCGDirectMainDisplay);
[self setFullScreen];
NSOpenGLPixelFormatAttribute attributes[] =
{
NSOpenGLPFAColorSize, (NSOpenGLPixelFormatAttribute)32,
NSOpenGLPFAAlphaSize, (NSOpenGLPixelFormatAttribute)8,
NSOpenGLPFADepthSize, (NSOpenGLPixelFormatAttribute)32,
NSOpenGLPFAStencilSize, (NSOpenGLPixelFormatAttribute)8,
NSOpenGLPFASampleBuffers, (antiAliasing) ? (NSOpenGLPixelFormatAttribute)1 : (NSOpenGLPixelFormatAttribute)0,
NSOpenGLPFASamples, (NSOpenGLPixelFormatAttribute)antiAliasing,
NSOpenGLPFAScreenMask, (NSOpenGLPixelFormatAttribute)CGDisplayIDToOpenGLD isplayMask(kCGDirectMainDisplay),
NSOpenGLPFAFullScreen,
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAAccelerated,
NSOpenGLPFAAllRenderers,
(NSOpenGLPixelFormatAttribute)0
};
NSOpenGLPixelFormat *format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
sharedContext = [[NSOpenGLContext alloc] initWithFormat:format shareContext:nil];
context = [[NSOpenGLContext alloc] initWithFormat:format shareContext:sharedContext];
[format release];
clearColor[0] = clearColor[1] = clearColor[2] = 0;
clearColor[3] = 1;
location = LOC_MAIN_MENU;
[self reshape];
[self prepare];
return self;
}
setFullScreen
- (void)setFullScreen
{
CFDictionaryRef fullScreen = CGDisplayBestModeForParameters(kCGDirectMainDispla y, 32, width, height, NULL );
CGDisplaySwitchToMode(kCGDirectMainDisplay, fullScreen);
NSRect rect = NSMakeRect(0, 0, width, height);
[[[AppController appController] mainWindow] setFrame:rect display:false];
[[[AppController appController] eventView] setFrame:rect];
}
reshape
- (void)reshape
{
[context setFullScreen];
[context makeCurrentContext];
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
ratio = (float)width/(float)height;
if (location == LOC_MAIN_MENU || location == LOC_OPTIONS_MENU || location == LOC_LEVEL_SELECT)
glOrtho(-200*ratio, 200*ratio, 0, 400, -200, 200);
else
gluPerspective(90.0, ratio, 0.1, 1000);
}
prepare
- (void)prepare
{
glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glEnable(GL_CULL_FACE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
font's constructor (texture loading part)
char *texturePath;
if (textureQuality == LOW_QUALITY)
texturePath = "/Space Chase.app/Contents/Resources/Textures/Courier low.tga";
else if (textureQuality == HIGH_QUALITY)
texturePath = "/Space Chase.app/Contents/Resources/Textures/Courier.tga";
char *completePath = (char *)malloc(strlen(appPath) + strlen(texturePath) + 1);
strcpy(completePath, appPath);
mnkyTGAInfo *tex = mnkyOpenTGA(strcat(completePath, texturePath));
free(completePath);
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, tex->components, tex->width, tex->height,
0, tex->format, GL_UNSIGNED_BYTE, tex->imageData);
mnkyDeleteTGA(&tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
currentQuality = textureQuality;
menu's constructor
MainMenu::MainMenu() : title("Space Chase", large, zero, zero, titleColor), start("Start Game", small, zero, zero, itemColor),
startSelected("Start Game", selected, zero, zero, itemColor), level("Select Level", small, zero, zero, itemColor),
levelSelected("Select Level", selected, zero, zero, itemColor), options("Options", small, zero, zero, itemColor),
optionsSelected("Options", selected, zero, zero, itemColor), highScores("High Scores", small, zero, zero, itemColor),
highScoresSelected("High Scores", selected, zero, zero, itemColor), credits("Credits", small, zero, zero, itemColor),
creditsSelected("Credits", selected, zero, zero, itemColor), quit("Quit", small, zero, zero, itemColor),
quitSelected("Quit", selected, zero, zero, itemColor), startIsSelected(0), levelIsSelected(0), optionsIsSelected(0), creditsIsSelected(0),
highScoresIsSelected(0), quitIsSelected(0), background(0), currentQuality(0)
{
char *texturePath;
if (textureQuality == LOW_QUALITY)
texturePath = "/Space Chase.app/Contents/Resources/Textures/Stars low.tga";
else if (textureQuality == HIGH_QUALITY)
texturePath = "/Space Chase.app/Contents/Resources/Textures/Stars.tga";
char *completePath = (char *)malloc(strlen(appPath) + strlen(texturePath) + 1);
strcpy(completePath, appPath);
mnkyTGAInfo *tex = mnkyOpenTGA(strcat(completePath, texturePath));
free(completePath);
glGenTextures(1, &background);
glBindTexture(GL_TEXTURE_2D, background);
glTexImage2D(GL_TEXTURE_2D, 0, tex->components, tex->width, tex->height,
0, tex->format, GL_UNSIGNED_BYTE, tex->imageData);
mnkyDeleteTGA(&tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
currentQuality = textureQuality;
}
A final note: is it possibly NSApplication not being too C++ friendly? Since this did work when commenting out its main loop....
Edit x2: before anybody asks, I did "Clean all targets" and rebuilt about 3000x already.
Edit x3: I ran it through Malloc debug, and it ran perfectly. (loaded all textures and everything) Strange...................
This C string is one that I'm constructing to open a texture. I malloc it, copy the bundle string, then concatenate the rest of the path. After that, I feed the string into my open TGA method, and free the string. The string is accessed twice: once to check to make sure it's not NULL, and once to open the file. That can't be a problem, but I comment it out anyway. Next, it crashes citing where I delete the TGA file after loading the texture (using glTexImage2D), saying where I set the pointer to NULL. Ok, I take that out. It then crashes pointing to the end of the function. I say WTF??? and comment out where I actually free the data, and it works. It also works when I just comment out my deleteTGA function. Neither of those should have done anything. The this class also contains Font classes which instantiate before hand it actually gets to the crash. It has a nearly identical method of opening my font texture, and if I comment out the string free and texture delete there, it usually works as well. At one point, I commented out all of my texture loading function calls, and it says I accessed freed memory when assigning an integer! (by the line number it gave me)
It gets even weirder. I commented out my capture display function calls, and ran through the debugger. It went through the instanciation of the menu class this is crashing in, it starts instanciating the fonts, goes to the malloc of the C string for accessing the font texture, then completely dies. When I look at the function calls, it suddenly jumped past all not only that font instanciation, but all the rest of them as well to where I freed the C string for opening the texture for the texture after all that is done.
When I comment out all the frees and deletes, it runs, but doesn't load one of the textures.
As a final test, I went into main.m, took out NSApplicationMainLoop, instanciated my controller, slept for 20 seconds, then quit. Lo and behold, it worked perfectly! Loaded all the textures and displayed the graphics perfectly, no malloc errors, NOTHING! I take it back out, and it crashes.
Edit: almost forgot to mention: at one point, I put in a print call, and it didn't crash! One of the textures didn't load, but it didn't crash. I took out the print statement, and it crashed again... Talk about weird. Not even accessing anything, just "cerr << "here\n";"
Here is all relevent code. I'm at a complete loss. I've been at this all day without avail. Hopefully somebody here with more cocoa experience can help me.
(mainWindow and eventView were added after trying most of this stuff, but made no difference)
AppController init (called first)
- (id)init
{
self = [super init];
if (self != nil)
{
[mainWindow makeKeyAndOrderFront:self];
appController = self;
gameView = [[GameView alloc] init];
[eventView lockFocus];
mainList = new DrawList;
Drawable *menu = new MainMenu;
mainList->insert(menu);
[gameView draw];
}
return self;
}
GameView init
- (id)init
{
self = [super init];
previousDisplay = CGDisplayCurrentMode(kCGDirectMainDisplay);
CGDisplayCapture(kCGDirectMainDisplay);
[self setFullScreen];
NSOpenGLPixelFormatAttribute attributes[] =
{
NSOpenGLPFAColorSize, (NSOpenGLPixelFormatAttribute)32,
NSOpenGLPFAAlphaSize, (NSOpenGLPixelFormatAttribute)8,
NSOpenGLPFADepthSize, (NSOpenGLPixelFormatAttribute)32,
NSOpenGLPFAStencilSize, (NSOpenGLPixelFormatAttribute)8,
NSOpenGLPFASampleBuffers, (antiAliasing) ? (NSOpenGLPixelFormatAttribute)1 : (NSOpenGLPixelFormatAttribute)0,
NSOpenGLPFASamples, (NSOpenGLPixelFormatAttribute)antiAliasing,
NSOpenGLPFAScreenMask, (NSOpenGLPixelFormatAttribute)CGDisplayIDToOpenGLD isplayMask(kCGDirectMainDisplay),
NSOpenGLPFAFullScreen,
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAAccelerated,
NSOpenGLPFAAllRenderers,
(NSOpenGLPixelFormatAttribute)0
};
NSOpenGLPixelFormat *format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
sharedContext = [[NSOpenGLContext alloc] initWithFormat:format shareContext:nil];
context = [[NSOpenGLContext alloc] initWithFormat:format shareContext:sharedContext];
[format release];
clearColor[0] = clearColor[1] = clearColor[2] = 0;
clearColor[3] = 1;
location = LOC_MAIN_MENU;
[self reshape];
[self prepare];
return self;
}
setFullScreen
- (void)setFullScreen
{
CFDictionaryRef fullScreen = CGDisplayBestModeForParameters(kCGDirectMainDispla y, 32, width, height, NULL );
CGDisplaySwitchToMode(kCGDirectMainDisplay, fullScreen);
NSRect rect = NSMakeRect(0, 0, width, height);
[[[AppController appController] mainWindow] setFrame:rect display:false];
[[[AppController appController] eventView] setFrame:rect];
}
reshape
- (void)reshape
{
[context setFullScreen];
[context makeCurrentContext];
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
ratio = (float)width/(float)height;
if (location == LOC_MAIN_MENU || location == LOC_OPTIONS_MENU || location == LOC_LEVEL_SELECT)
glOrtho(-200*ratio, 200*ratio, 0, 400, -200, 200);
else
gluPerspective(90.0, ratio, 0.1, 1000);
}
prepare
- (void)prepare
{
glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glEnable(GL_CULL_FACE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
font's constructor (texture loading part)
char *texturePath;
if (textureQuality == LOW_QUALITY)
texturePath = "/Space Chase.app/Contents/Resources/Textures/Courier low.tga";
else if (textureQuality == HIGH_QUALITY)
texturePath = "/Space Chase.app/Contents/Resources/Textures/Courier.tga";
char *completePath = (char *)malloc(strlen(appPath) + strlen(texturePath) + 1);
strcpy(completePath, appPath);
mnkyTGAInfo *tex = mnkyOpenTGA(strcat(completePath, texturePath));
free(completePath);
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, tex->components, tex->width, tex->height,
0, tex->format, GL_UNSIGNED_BYTE, tex->imageData);
mnkyDeleteTGA(&tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
currentQuality = textureQuality;
menu's constructor
MainMenu::MainMenu() : title("Space Chase", large, zero, zero, titleColor), start("Start Game", small, zero, zero, itemColor),
startSelected("Start Game", selected, zero, zero, itemColor), level("Select Level", small, zero, zero, itemColor),
levelSelected("Select Level", selected, zero, zero, itemColor), options("Options", small, zero, zero, itemColor),
optionsSelected("Options", selected, zero, zero, itemColor), highScores("High Scores", small, zero, zero, itemColor),
highScoresSelected("High Scores", selected, zero, zero, itemColor), credits("Credits", small, zero, zero, itemColor),
creditsSelected("Credits", selected, zero, zero, itemColor), quit("Quit", small, zero, zero, itemColor),
quitSelected("Quit", selected, zero, zero, itemColor), startIsSelected(0), levelIsSelected(0), optionsIsSelected(0), creditsIsSelected(0),
highScoresIsSelected(0), quitIsSelected(0), background(0), currentQuality(0)
{
char *texturePath;
if (textureQuality == LOW_QUALITY)
texturePath = "/Space Chase.app/Contents/Resources/Textures/Stars low.tga";
else if (textureQuality == HIGH_QUALITY)
texturePath = "/Space Chase.app/Contents/Resources/Textures/Stars.tga";
char *completePath = (char *)malloc(strlen(appPath) + strlen(texturePath) + 1);
strcpy(completePath, appPath);
mnkyTGAInfo *tex = mnkyOpenTGA(strcat(completePath, texturePath));
free(completePath);
glGenTextures(1, &background);
glBindTexture(GL_TEXTURE_2D, background);
glTexImage2D(GL_TEXTURE_2D, 0, tex->components, tex->width, tex->height,
0, tex->format, GL_UNSIGNED_BYTE, tex->imageData);
mnkyDeleteTGA(&tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
currentQuality = textureQuality;
}
A final note: is it possibly NSApplication not being too C++ friendly? Since this did work when commenting out its main loop....
Edit x2: before anybody asks, I did "Clean all targets" and rebuilt about 3000x already.
Edit x3: I ran it through Malloc debug, and it ran perfectly. (loaded all textures and everything) Strange...................