|
发表于 2011-11-23 22:07:00
|
显示全部楼层
Re: 关于DirectDraw切换分辨率后黑屏
no1xbde: 关于DirectDraw切换分辨率后黑屏
切换桌面的分辨率或是程序中改变分辨率(与初始化的时候的分辨率不相同)之后,游戏直接就黑屏了。
颜色深度...
我给你一个我自己运行正确的示例:
(声明:我并不知道我这代码是否没有一点问题,只知道测试结果是正确的,即可以用alt+enter随意进行窗口和全屏切换)
- // 窗口/全屏模式切换
- void CRender::ToggleScreen(bool bWindow)
- {
- if (!m_bInit) return;
- if (bWindow == m_bWindowed) return;
- m_bWindowed = bWindow;
- // 窗口模式
- if (bWindow)
- {
- m_pDirectDraw7->RestoreDisplayMode();
- SetWindowLong(m_hWnd, GWL_STYLE, m_Wnd_Style);
- ::MoveWindow(m_hWnd, m_Wnd_Rect.left, m_Wnd_Rect.top, m_Wnd_Rect.right-m_Wnd_Rect.left, m_Wnd_Rect.bottom-m_Wnd_Rect.top, true);
- CreateSurface();
- ::UpdateWindow(m_hWnd);
- ::ShowWindow(m_hWnd, SW_SHOWNORMAL);
- ::BringWindowToTop(m_hWnd);
- }
- // 全屏模式
- else
- {
- ::GetWindowRect(m_hWnd, &m_Wnd_Rect); // 记录窗口的屏幕位置
- m_Wnd_Style = ::GetWindowLong(m_hWnd, GWL_STYLE); // 记录窗口样式
- // 改变指定窗口的属性
- SetWindowLong(m_hWnd, GWL_STYLE, WS_POPUP & ~WS_VISIBLE);
- ::MoveWindow(m_hWnd, 0, 0, m_ScreenWidth, m_ScreenHeight, true);
- ::UpdateWindow(m_hWnd);
- ::ShowWindow(m_hWnd, SW_SHOWNORMAL);
- ::BringWindowToTop(m_hWnd);
- // 设置显示模式
- if (FAILED(m_pDirectDraw7->SetDisplayMode(m_ScreenWidth, m_ScreenHeight, _SCREEN_BITS, 0, 0)))
- return;
- CreateSurface();
- }
- InitData();
- }
- // 创建主表面和后台表面
- BOOL CRender::CreateSurface()
- {
- if (m_hWnd == NULL) return FALSE;
- if (m_ScreenWidth==0 || m_ScreenHeight==0) return FALSE;
- ClearSurface();
- // 窗口模式
- if (m_bWindowed)
- {
- // 设置协作等级
- if (FAILED(m_pDirectDraw7->SetCooperativeLevel(m_hWnd, DDSCL_NORMAL)))
- return FALSE;
- // 创建主表面
- DDSURFACEDESC2 surfaceDesc;
- memset(&surfaceDesc, 0, sizeof(surfaceDesc));
- surfaceDesc.dwSize = sizeof(surfaceDesc);
- surfaceDesc.dwFlags = DDSD_CAPS; // 表示ddsCaps 成员是有效的
- surfaceDesc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; // 表示要创建的是主表面
- if (FAILED(m_pDirectDraw7->CreateSurface(&surfaceDesc, &m_pDDPrimarySurface, NULL)))
- return FALSE;
- }
- // 全屏模式
- else
- {
- // 设置协作等级
- if (FAILED(m_pDirectDraw7->SetCooperativeLevel(m_hWnd, DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT)))
- return FALSE;
- // 创建主表面
- DDSURFACEDESC2 surfaceDesc;
- memset(&surfaceDesc, 0, sizeof(surfaceDesc));
- surfaceDesc.dwSize = sizeof(surfaceDesc);
- surfaceDesc.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
- surfaceDesc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
- surfaceDesc.dwBackBufferCount = 1;
- if (m_pDirectDraw7->CreateSurface(&surfaceDesc, &m_pDDPrimarySurface, NULL) != DD_OK)
- return FALSE;
- }
- // 设置裁剪器
- if (FAILED(m_pDDPrimarySurface->SetClipper(m_pDDClipper)))
- return FALSE;
- // 创建后台缓冲表面
- DDSURFACEDESC2 surfaceDesc;
- memset(&surfaceDesc, 0, sizeof(surfaceDesc));
- surfaceDesc.dwSize = sizeof(surfaceDesc);
- surfaceDesc.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH;
- surfaceDesc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY; // 使用系统内存创建表面。DDSCAPS_OFFSCREENPLAIN:创建屏外表面。就是不与主表面等翻转表面相关的表面,通常用于位图的缓冲
- surfaceDesc.dwWidth = m_ScreenWidth;
- surfaceDesc.dwHeight = m_ScreenHeight;
- if (m_pDirectDraw7->CreateSurface(&surfaceDesc, &m_pDDBackSurface, NULL) != DD_OK)
- return FALSE;
- return TRUE;
- }
- void CRender::ClearSurface()
- {
- if (m_pDDBackSurface != NULL)
- {
- m_pDDBackSurface->Release();
- m_pDDBackSurface = NULL;
- }
- if (m_pDDPrimarySurface != NULL)
- {
- m_pDDPrimarySurface->Release();
- m_pDDPrimarySurface = NULL;
- }
- }
- // 调用的代码:
- ...
- case WM_SYSKEYDOWN:
- switch(wParam)
- {
- case VK_RETURN:
- {
- static bool bWindow = true;
- if (CRender::s_pRender != NULL)
- {
- CRender::s_pRender->ToggleScreen(bWindow = !bWindow);
- }
- }
- break;
- }
- break;
- ...
复制代码
其中有个InitData()函数我没有贴出来,里面是创建表面的内容。 |
|