0

我的 SDL2 + OpenGL GUI 应用程序出现了一些奇怪的图形损坏。现在,如果我没有使用适当的术语来描述这种情况,我深表歉意。似乎前端缓冲区正在失效并且正在缓冲区中绘制其他应用程序?

重要提示:此损坏仅发生在 Windows XP 中或在 Windows 7 中使用 Windows Basic 主题时。

损坏可以通过几种方式重现:

  1. 通过移动窗口。似乎前端缓冲区被它前面或后面的其他应用程序的图像破坏了。
  2. 如果后面有应用程序,它偶尔会闪入前端缓冲区。
  3. 我可以在opengl应用程序上方的Chrome中加载一个谷歌网页,关闭chrome进程,然后移动opengl应用程序,我会看到谷歌主页覆盖了整个窗口内部。
  4. 通过在 opengl 窗口上移动另一个应用程序。

似乎我在移动其他窗口时也看到了损坏,即使它们不与 opengl 窗口重叠,只要我已经尝试过上面发布的一个。

inline int UI::RenderingThread()
{
   UI::Window::Instance().RenderingThreadEnter();
   while( UI::Window::Instance().RenderingThreadActive() )
   {
      unsigned int ticks = SDL_GetTicks();
      UI::Window::Instance().RenderingThreadUpdate();
      UI::Window::Instance().RenderingThreadRender();
      ticks = SDL_GetTicks() - ticks;
      if( ticks < 33 )
      {
         SDL_Delay( 33 - ticks );
      }
   }
   UI::Window::Instance().RenderingThreadExit();

   return 0;
}

正如您可能猜到的那样,我正在使用多线程,并且我在单独的线程中进行渲染。在该RenderingThreadRender()函数中,我仅在内容发生更改或我已请求重绘时重绘。

case SDL_WINDOWEVENT:
   switch( sdl_event.window.event )
   {
      default:
         UI::Window::Instance().Redraw();
         break;
   }

这样做是为了允许所有SDL_WINDOWEVENT事件重绘,希望其中一个事件能够解决问题。不幸的是,这并没有解决问题。

我很犹豫是否只是不断地以 30 或 60 fps 的速度重绘我的应用程序,因为我注意到这样做会使其他应用程序在移动它们时变得迟缓。

初始化:

SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); 
this->window = SDL_CreateWindow( this->caption.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
                                 UI::WindowSize::Instance().GetWindowWidth(), UI::WindowSize::Instance().GetWindowHeight(),
                                 SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE );

glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glViewport(0, 0, UI::WindowSize::Instance().GetWindowWidth(), UI::WindowSize::Instance().GetWindowHeight());

// Set the OpenGL view
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho( 0, UI::WindowSize::Instance().GetWindowWidth(), UI::WindowSize::Instance().GetWindowHeight(), 0, -1, 1 );
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
glDisable( GL_DITHER );

渲染:

if( this->redraw )
{
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     glLoadIdentity();

     // a few DrawArrays

     SDL_GL_SwapWindow( this->window ); 
}

有谁知道可能导致此问题的原因以及如何解决?

编辑:更多的研究向我指出了以下两个问题:

https://superuser.com/questions/316738/what-happens-with-the-off-screen-front-buffers-in-windows-7-when-dwm-is-disabled

C++ OpenGL 窗口只跟踪背景

但是,这并不能解决我的问题,因为我已经在使用双缓冲了。

4

1 回答 1

0

我找到了解决我的问题的方法。不太可能有人会遇到与我相同的问题,但你永远不知道。本质上,之前创建了一个大小等于或大于我的应用程序的 C# 窗口。这个窗口是隐藏的,但是因为 XP 有一个全局帧缓冲区而不是一个合成,所以存在一个导致损坏的冲突。

总而言之,如果您遇到类似的问题,请确保没有其他上下文。

于 2013-09-18T19:22:26.077 回答