使用OpenGL正确关闭SDL

时间:2013-10-12 03:57:38

标签: opengl sdl

我正在以最小的方式使用SDL 1.2来在C ++中创建跨平台的OpenGL上下文(这是在Win7 64位上)。我也使用glew让我的上下文支持OpenGL 4.2(我的驱动程序支持)。

事情在运行时正常工作但我最近注意到在关闭调用SDL_Quit时随机崩溃。

SDL(1.2)与OpenGL启动和关闭的正确顺序是什么?

以下是我目前所做的事情:

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;
}

在初始和关闭调用之间,我创建了许多GL资源(例如纹理,VBO,VAO,着色器等)并在每帧渲染我的场景,每帧结束时使用SDL_GL_SwapBuffers()(漂亮)典型)。像这样:

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;
}

在〜MyObject中调用MyObject :: Shutdown()。最近,SDL_Quit崩溃了应用程序。我的渲染循环返回到相同的效果后,我也尝试在析构函数之外调用Shutdown。

我不做的一件事(我认为我不需要这样做)是在调用Shutdown之前为我所分配的GL资源调用glDelete *函数(我认为它们会被破坏后自动清理掉上下文,我假设在SDL_FreeSurface或SDL_Quit()期间发生。我当然在包装对象的dtors中调用glDelete *函数,最终由~MyObject的故事调用,因为包装器对象是其他对象的一部分作为MyObject成员的对象。

作为一个实验,我尝试强制所有适当的glDelete *调用在Shutdown()之前发生,并且我的崩溃似乎永远不会发生。有趣的事情我一周前不需要这样做,根据GIT确实没有任何改变(虽然可能是错的)。

在使用SDL调用MyObject :: Shutdown之前,是否确实需要确保释放所有GL资源?看起来我可能做错了吗?

1 个答案:

答案 0 :(得分:3)

m_SurfDisplay = SDL_SetVideoMode(...)
...
SDL_FreeSurface(m_SurfDisplay);
                ^^^^^^^^^^^^^ naughty naughty!

SDL_SetVideoMode()

  

返回的表面由SDL_Quit释放, 不得被调用者释放