我正在尝试使用原始 DirectDraw 接口编写单个缓冲的窗口应用程序。
这纯粹是出于教育目的和公正的态度。我在玩IDirectDraw
界面(我强调这是原始版本,就像在 DirectX 1.0 中一样)。
现在,该文档包含一组关于创建后缓冲和在主表面和后缓冲表面之间翻转的教程。
但是,它没有描述如何编写一个窗口化的单缓冲区应用程序。事实上,我几乎找不到任何关于这个想法的参考。没有任何迹象表明它不可能。
DDSCL_NORMAL
通过设置与应用程序在一个窗口内的行为的合作级别。
hr = IDirectDraw_SetCooperativeLevel(lpDirectDraw, hWnd_, DDSCL_NORMAL);
if (hr != DD_OK)
return -1;
成功后创建主曲面。
ZeroMemory(&ddSurfaceDesc, sizeof ddSurfaceDesc);
ddSurfaceDesc.dwSize = sizeof ddSurfaceDesc;
ddSurfaceDesc.dwFlags = DDSD_CAPS;
ddSurfaceDesc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
hr = IDirectDraw_CreateSurface(lpDirectDraw, &ddSurfaceDesc, &lpDirectDrawPrimarySurface, (IUnknown *) NULL);
if (hr != DD_OK)
return -1;
这个函数也成功了。请注意,我没有创建后台缓冲区。
但是,在我的主循环中:
while (fIterateLoop)
{
for (ZeroMemory(&msg, sizeof msg); PeekMessage(&msg, (HWND) NULL, 0, 0, PM_REMOVE); DispatchMessage(&msg))
fIterateLoop = msg.message == WM_QUIT ? FALSE : TRUE;
if (fDraw && lpDirectDrawPrimarySurface != (LPDIRECTDRAWSURFACE) NULL)
{
HDC hdc;
hr = IDirectDrawSurface_GetDC(lpDirectDrawPrimarySurface, &hdc);
if (hr == DD_OK)
{
SetBkColor(hdc, RGB(0, 0, 0));
SetTextColor(hdc, RGB(255, 255, 255));
TextOut(hdc, 15, 15, "hello, world!", sizeof "hello, world!" - 1);
hr = IDirectDrawSurface_ReleaseDC(lpDirectDrawPrimarySurface, hdc);
}
}
}
根本没有任何东西被吸引到窗口上。我的原始代码(全屏缓冲应用程序)正确显示“你好,世界!” 在屏幕的左上角,唯一的修改是微小的编辑以停止后台缓冲区的创建,并直接写入主表面。
如果我CreateSurface
在调用后使用后备缓冲区的选项调用SetCooperativeLevel
,DDSCL_NORMAL
那么它会返回并出错。我理解这一点,因为文档指出:
如果您使用 IDirectDraw::SetCooperativeLevel 将模式设置为 DDSCL_NORMAL,则只能创建在曲面之间闪烁的曲面。
我错过了什么吗?我是否从根本上误解了 DirectDraw?我的印象是使用缓冲区是为了:
- 性能优势,以及
- 防止屏幕撕裂。
我不在乎这两个对不对。我能做些什么?