Reputation: 837
I am using SDL 1.2 in a minimal fashion to create a cross platform OpenGL context (this is on Win7 64bit) in C++. I also use glew to have my context support OpenGL 4.2 (which my driver supports).
Things work correctly at run-time but I have been noticing lately a random crash when shutting down on calling SDL_Quit.
What is the proper sequence for SDL (1.2) with OpenGL start up and shutdown?
Here is what i do currently:
int MyObj::Initialize(int width, int height, bool vsync, bool fullscreen)
{
if(SDL_Init( SDL_INIT_EVERYTHING ) < 0)
{
printf("SDL_Init failed: %s\n", SDL_GetError());
return 0;
}
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 24);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, vsync ? 1 : 0);
if((m_SurfDisplay = SDL_SetVideoMode(width, height, 24,
SDL_HWSURFACE |
SDL_GL_DOUBLEBUFFER |
(fullscreen ? SDL_FULLSCREEN : 0) |
SDL_OPENGL)) == NULL)
{
printf("SDL_SetVideoMode failed: %s\n", SDL_GetError());
return 0;
}
GLenum err = glewInit();
if (GLEW_OK != err)
return 0;
m_Running = true;
return 1;
}
int MyObj::Shutdown()
{
SDL_FreeSurface(m_SurfDisplay);
SDL_Quit();
return 1;
}
In between the init and shutdown calls i create a number of GL resources (e.g. Textures, VBOs, VAO, Shaders, etc.) and render my scene each frame, with a SDL_GL_SwapBuffers() at the end of each frame (pretty typical). Like so:
int MyObject::Run()
{
SDL_Event Event;
while(m_Running)
{
while(SDL_PollEvent(&Event))
{ OnEvent(&Event); } //this eventually causes m_Running to be set to false on "esc"
ProcessFrame();
SDL_SwapBuffers();
}
return 1;
}
Within the ~MyObject MyObject::Shutdown() is called. Where just recently SDL_Quit crashes the app. I have also tried call Shutdown instead outside of the destructor, after my render loop returns to the same effect.
One thing that I do not do (that i didn't think I needed to do) is call the glDelete* functions for all my allocated GL resources before calling Shutdown (i thought they would automatically be cleaned up by the destruction of the context, which i assumed was happening during SDL_FreeSurface or SDL_Quit(). I of course call the glDelete* function in the dtors of there wrapping objects, which eventually get called by the tale of ~MyObject, since the wrapper objects are part of other objects that are members of MyObject.
As an experiment i trying forcing all the appropriate glDelete* calls to occur before Shutdown(), and my crash never seems to occur. Funny thing i did not need to do this a week ago, and really nothing has changed according to GIT (may be wrong though).
Is it really necessary to make sure all GL resources are freed before calling MyObject::Shutdown with SDL? Does it look like I might be doing something else wrong?
Upvotes: 0
Views: 1008
Reputation: 52082
m_SurfDisplay = SDL_SetVideoMode(...)
...
SDL_FreeSurface(m_SurfDisplay);
^^^^^^^^^^^^^ naughty naughty!
The returned surface is freed by SDL_Quit and must not be freed by the caller.
Upvotes: 3