OpenGL中使用ChangeDisplaySettings设置全屏的问题

fangxu1999 2010-02-19 07:17:55
我试着在MFC单文档程序中视图类的OnDraw函数中绘制了一些物体

void CGLSample1View::OnDraw(CDC* pDC)
{
// 绘制物体
...

SwapBuffers(pDC->GetSafeHdc());
}


为了修改屏幕的分辨率从1024x768转换成800x600,使用如下的函数

void CGLSample1View::OnViewFullscreen()
{
if (m_bChange)
{
ChangeDisplaySettings(NULL, 0);
m_bChange = FALSE;
}
else
{
DEVMODE devMode;
ZeroMemory(&devMode, sizeof(DEVMODE));
devMode.dmSize = sizeof(DEVMODE);
devMode.dmBitsPerPel = 32;
devMode.dmPelsWidth = 800;
devMode.dmPelsHeight = 600;
devMode.dmDisplayFrequency = 60;
devMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY;
if (ChangeDisplaySettings(&devMode, CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL)
{
m_bChange = TRUE;
}
else
{
MessageBox("不支持指定的分辨率!");
}
}
}


在切换过程中出现了问题:
在切换分辨率的过程中,不论是从1024x768到800x600,还是相反的过程都是。一开始视图仍然显示为白色,并没有绘制出所需要的物体。
只有当人工进行修改窗口大小等操作,也就是执行一次强制视图重绘时才能够显示出来。但是我进行了测试,发现在切换的过程中OnDraw函数确实也被调用过,也没有出现什么错误,可是就是显示不出来。
经过验证,其中显示的白色为视图类的hbrBackground颜色,我把它设置成其他颜色以后,便显示成相应的了。

SetClassLong(GetSafeHwnd(), GCL_HBRBACKGROUND, (LONG)GetStockObject(DKGRAY_BRUSH));

我在切换函数最后手工调用Invalidate(FALSE); UpdateWindow();仍然无效,仍然显示背景画刷颜色。
可是当我不用OpenGL,直接使用CDC进行绘图时,分辨率切换过程没有任何问题。
我是一个OpenGL新手,可能是哪里没有用对吧。我使用的像素格式是 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,双缓冲的。并且设置了背景色为glClearColor(0, 0, 0, 0)。

请问如何才能将绘制的结果,OpenGL执行的结果在分辨率切换过程中正常的显示出来?这个问题到底是出在哪里啊?
谢谢大家
...全文
505 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
fangxu1999 2010-02-24
  • 打赏
  • 举报
回复
这样也不行啊

估计问题是来自于Windows自身的DC的实现的问题。是系统问题吧。程序代码上根本找不出问题来。
对于OpenGL的代码也非常难调试,glGetError始终返回GL_NO_ERROR,相当晕。
应该也不是OpenGL的错误。因为正常情况下绘制没有问题,只有切换分辨率时出了问题。
大概是Windows的bug吧,也只能这样认为了。
还是能用MoveWindow人工修改窗口大小,实现重绘输出了。

谢谢大家关注,但是问题的原因还是没有搞清楚啊。
fangxu1999 2010-02-23
  • 打赏
  • 举报
回复
增加了还是不行

Invalidate(FALSE);
UpdateWindow();

我在OnDraw函数里面进行了一些打印TRACE,切换分辨率时已经执行了重绘操作,只是OpenGL命令执行的结果没有。
还是莫名其妙啊
lllyyy2403 2010-02-23
  • 打赏
  • 举报
回复
有一段时间没有使用OPENGL了,关注。好象:电脑同一个时间只能有一个CDC,Opengl和你的CDC是否代表了两个CDC,从而导致问题出现?
forcal 2010-02-23
  • 打赏
  • 举报
回复
看看这个行不?
ShowWindow(hWnd,SW_SHOW); // Show The Window
SetForegroundWindow(hWnd); // Slightly Higher Priority

或者问题来自:

PeekMessage(&msg,NULL,0,0,PM_REMOVE)
GetMessage(&msg,NULL,0,0)
fangxu1999 2010-02-23
  • 打赏
  • 举报
回复
好像也不是这个问题哦。
我使用
SwapBuffers(wglGetCurrentDC());
来刷新,同时为窗口类指定了CS_OWNDC类型的风格,这样就是使用同一个DC了,句柄值也和pDC一样
仍然存在问题。

书上说只要PIXELFORMAT设置正确即可了,同一个窗口的DC
fandh 2010-02-22
  • 打赏
  • 举报
回复
OnViewFullscreen() 函数最后,加一个Invalidate();
fangxu1999 2010-02-21
  • 打赏
  • 举报
回复
谢谢关注。
重载这个函数以后直接return TRUE还是不行,此时视图区域全黑,仍然没有把OpenGL命令显示到屏幕上。
我执行了一下MoveWindow以后,图像显示出来了,这样也差不多可以了,就是想知道为什么一开始的时候OpenGL执行的命令不能显示出来啊?
还请高手指点迷津。
fandh 2010-02-21
  • 打赏
  • 举报
回复
OnEraseBkgnd(CDC* pDC)
这个函数重载后,要直接return TRUE;

你是否添加了?
fangxu1999 2010-02-19
  • 打赏
  • 举报
回复
谢谢,可是还是不行啊,我加了

glFlush();
glFinish();

这两个都不能在切换过程中立即得到绘制结果。

此外,我在程序中增加了错误检查代码如下:

GLenum errorCode = glGetError();
if (errorCode != GL_NO_ERROR)
{
TRACE("OpenGL Error: 0x%08x, %s\n", errorCode, gluGetString(errorCode));
}

发现并没有产生任何OPENGL的错误,会不会是Windows DC绘图的问题啊?
请高手指点一下,谢谢了
wuhuwy 2010-02-19
  • 打赏
  • 举报
回复
你在切换视图后加句Glflush()试试,可能是缓冲区没有立即绘图的问题

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧