当前位置: 首页 > 知识库问答 >
问题:

禁用DWM会导致OpenGL窗口中的前缓冲区损坏

松秦斩
2023-03-14

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

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

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

  1. 通过移动窗口。似乎前面的缓冲区与前面或后面的其他应用程序的图像损坏了。
  2. 如果后面有一个应用程序,它会偶尔闪到前面的缓冲区中。
  3. 我可以在opengl应用程序上方Chrome加载一个google网页,关闭chrome进程,然后移动opengl应用程序,我就会看到google主页覆盖了整个窗口内部。
  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;
}

正如您可能猜到的,我正在使用多线程,我在一个单独的线程中进行渲染。在<code>RenderingThreadRender()

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

这样做是为了允许所有的< code > SDL _窗口事件事件重新绘制,希望其中一个事件能够解决问题。不幸的是,这并没有解决问题。

我不太愿意简单地以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窗口只跟踪背景

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

共有1个答案

元景天
2023-03-14

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

总而言之,如果你有类似的问题,确保没有其他的背景。

 类似资料:
  • 我有一个wxWidgets应用程序,它有许多子opengl窗口。我使用我自己的GL画布类,而不是wx类。窗口共享它们的OpenGL上下文。我不认为它是wxwidgets的事实在这里真的很重要。 opengl窗口是一个窗口的子窗口,它们是彼此的兄弟姐妹,包含在一个选项卡控件中。有点像MDI风格的界面,但它不是MDI窗口...每个都可以单独调整大小。除非启用Aero并且DWM处于活动状态,否则所有工作

  • 在DirectX中,您可以有单独的渲染目标和深度缓冲区,因此可以绑定渲染目标和一个深度缓冲区、执行一些渲染、移除深度缓冲区然后使用旧的深度缓冲区作为纹理进行更多渲染。 你会如何在opengl中做到这一点?根据我的理解,您有一个帧缓冲区对象,其中包含颜色缓冲区和可选的深度缓冲区。我不认为我可以同时绑定多个帧缓冲器对象,我是否必须在每次更改时(可能一帧几次)重新创建帧缓冲器对象?普通的 opengl

  • 我对openGL渲染很陌生,无论我做什么,深度深度都不起作用。我显然已经启用了深度测试(),并且我清除了每一帧的缓冲区。 但是 openGL 不断显示最后在其他人面前渲染的对象... 你可以在我的github上看到我的代码。这是两个相关的文件:主循环。我的主循环在,渲染在。 我正在使用java和lwjgl。

  • 我有一个正在开发的OpenGL应用程序。正在渲染的地形似乎没有遵循深度缓冲规则,所以我猜我在某个地方搞砸了 我的代码中有GL11.glEnable(GL11.GL_CULL_FACE) 这是飞机在没有四边形在另一个后面的情况下的样子,所以即使没有z缓冲区,事情看起来也很正常。请注意,这是从“自上而下”的视图中,其中“相机”在飞机上方 而现在,从不同的角度看 离场景最远的四边形正在更靠近计算机的四边

  • 我目前正在使用LWJGL / OpenGL创建一个2D,自上而下的游戏,但是在绘制实体之后,在使用顶点缓冲区对象渲染实体后,在让它们四处移动的过程中,我遇到了一些问题。这是渲染线程的 run() 方法,以及设置方法: 实体从抽象超类继承这些方法来设置 VBO 并绘制实体(呈现线程中的 drawEntities 方法仅调用该方法,实体更新方法(见下文),而 setUpEntities 调用 setU

  • 多窗格 表 25.9. Emacs 窗格 C-x 2 M-x split-window-vertically 分隔出两个垂直窗格,水平分隔线 C-x 3 M-x split-window-horizontally 分隔出两个水平窗格,垂直分隔线 C-x 1 M-x delete-other-window 只保留当前窗格 ESC ESC ESC M-x keyboard-escape-quit 只保