禁用 DWM 会导致 OpenGL 窗口中的前端缓冲区损坏
DWM being disabled causes front-buffer corruption in OpenGL window
我的 SDL2 + OpenGL GUI 应用程序遇到了一些奇怪的图形损坏。现在,如果我没有使用适当的术语来描述这种情况,我深表歉意。似乎前端缓冲区正在失效,并且在缓冲区中绘制了其他应用程序?
重要说明:此损坏仅在 Windows XP 中或在 Windows 7 中使用 Windows Basic 主题时发生。
可以通过以下几种方式重现损坏:
- 通过移动窗口。似乎前端缓冲区被其前面或后面的其他应用程序的图像损坏了。
- 如果后面有一个应用程序,它偶尔会闪烁到前端缓冲区中。
- 我可以在 opengl 应用程序上方的 Chrome 中加载一个谷歌网页,关闭 chrome 进程,然后移动 opengl 应用程序,我会看到谷歌主页覆盖了整个窗口内部。
- 通过在 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 窗口仅跟踪背景
但是,这并不能解决我的问题,因为我已经在使用双缓冲。
我已经找到了解决问题的方法。任何人都不太可能遇到与我相同的问题,但您永远不知道。本质上,以前正在创建一个大小等于或大于我的应用程序的 C# 窗口。此窗口是隐藏的,但是由于XP具有全局帧缓冲而不是合成,因此存在导致损坏的冲突。
总而言之,如果您遇到类似的问题,请确保没有其他上下文。
- C++字符*缓冲区的大小
- 为什么msgrcv()将垃圾字符馈送到缓冲区
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- ostream过载时的缓冲区冲洗
- C++中的高效循环缓冲区,它将被传递给C样式数组函数参数
- Xaudio2在更改缓冲区或循环时弹出声音
- 为什么我在leetcode上收到AddressSanitizer:地址0x602000000058上的堆缓冲区溢出错误
- 如何将图像传输到c++(dll)中的缓冲区,然后在c#的缓冲区中读/写
- 如何在cpp.中使用协议缓冲区存储大缓冲区/数组(char/int)
- 多线程双缓冲区
- Android P-9.0.0_r53 Logcat主缓冲区超出定义大小
- 套接字读取后,我在缓冲区中看到意外输入
- std::带有自定义缓冲区的 iostream 不允许我写入
- 从返回的顶点缓冲区查询顶点结构
- Vulkan 中的动态顶点缓冲区格式设置
- OpenGL 16 位模板缓冲区?
- 在 leetcode 上提交解决方案时出现堆栈缓冲区溢出错误
- 在 openGL 中多次绑定缓冲区
- 有没有办法在缓存中保持空升压循环缓冲区的前端热
- 禁用 DWM 会导致 OpenGL 窗口中的前端缓冲区损坏