经典的DirectDraw问题,因为我是完全按要求做的

chinagdh 2001-08-23 01:03:30
#include <windows.h>
#include <ddraw.h>

#define V_WIDTH 640 // 屏幕宽度
#define V_HEIGHT 480 // 屏幕高度
#define V_DEPTH 16 // 色彩深度

//SAFE MACRO DEFINE
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }

char g_szAppName[50] = "Test"; //程序名称
HWND g_hWnd = NULL; //窗口句柄
HINSTANCE g_hInst = NULL; //程序句柄
BOOL g_bActive = FALSE; //程序是否活动
LPDIRECTDRAW7 v_lpDD = NULL; // DirectDraw对象
LPDIRECTDRAWSURFACE7 v_lpDDSP = NULL; // 主显示表面
LPDIRECTDRAWSURFACE7 v_lpDDSB = NULL; // 主后备表面
LPDIRECTDRAWSURFACE7 v_lpDDSBuffer = NULL; //缓冲表面

//////////////////////////////////////////////////////////////////////
// 函数
//////////////////////////////////////////////////////////////////////

// Windows 消息处理函数
HRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_ACTIVATEAPP:
g_bActive = wParam;
break;
case WM_ACTIVATE:
switch(LOWORD(wParam))
{
case 1:
case 2:
if(g_bActive&&v_lpDDSP) v_lpDDSP->Restore();
break;
}
break;
case WM_DESTROY:
PostQuitMessage(0);
return 0L;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}

// Windows初始化窗口程序
BOOL InitWindow(int nCmdShow)
{
//定义窗口类
WNDCLASS wc;
//设置和注册窗口类
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = g_hInst;
wc.hIcon = LoadIcon(g_hInst, NULL);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH )GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = g_szAppName;
wc.lpszClassName = g_szAppName;
RegisterClass(&wc);
//创建窗口
g_hWnd = CreateWindow(g_szAppName,
g_szAppName,
WS_POPUP,
0,
0,
GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN),
NULL,
NULL,
g_hInst,
NULL);
//如果创建失败则反回失败
if (!g_hWnd)
{
MessageBox(NULL,"创建窗口失败\n","错误",MB_OK);
return FALSE;
}
//显示窗口
ShowWindow(g_hWnd, nCmdShow);
//更新窗口
UpdateWindow(g_hWnd);
return TRUE;
}

BOOL V_Init(HWND hWnd)
{
HRESULT ddrval;
DDSURFACEDESC2 ddsd;
DDSCAPS2 ddscaps;
// 创建DirectDraw对象
if((ddrval = DirectDrawCreateEx(NULL,(VOID**)&v_lpDD,IID_IDirectDraw7,NULL))!=DD_OK)
{
MessageBox(NULL,"DirectDrawCreate fail...\n","error",MB_OK);
return FALSE;
}
// 设置协作度
if((ddrval = v_lpDD->SetCooperativeLevel(hWnd,DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN))!=DD_OK)
{
MessageBox(NULL,"SetCooperativeLevel fail...\n","error",MB_OK);
return FALSE;
}
//改变显示模式
if((ddrval = v_lpDD->SetDisplayMode(V_WIDTH,V_HEIGHT,V_DEPTH,0,0))!=DD_OK)
{
MessageBox(NULL,"SetDisplayMode fail...\n","error",MB_OK);
return FALSE;
}
// 创建翻转表面
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS|DDSD_BACKBUFFERCOUNT;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE|DDSCAPS_SYSTEMMEMORY|
DDSCAPS_FLIP|
DDSCAPS_COMPLEX;
ddsd.dwBackBufferCount = 1;
if((ddrval = v_lpDD->CreateSurface(&ddsd,&v_lpDDSP,NULL))!= DD_OK)
{
MessageBox(NULL,"Create Primary Surface fail...\n","error",MB_OK);
return FALSE;
}
// 创建后备表面
ZeroMemory( &ddscaps, sizeof( ddscaps ) );
ddscaps.dwCaps = DDSCAPS_BACKBUFFER|DDSCAPS_SYSTEMMEMORY;
if((ddrval = v_lpDDSP->GetAttachedSurface(&ddscaps,&v_lpDDSB))!= DD_OK)
{
MessageBox(NULL,"Create Back Surface fail...\n","error",MB_OK);
return FALSE;
}
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY;
ddsd.dwWidth = V_WIDTH;
ddsd.dwHeight = V_HEIGHT;
ddrval=v_lpDD->CreateSurface(&ddsd,&v_lpDDSBuffer,NULL);
if(ddrval != DD_OK)
{
MessageBox(NULL,"创建[Buffer]表面失败","error",MB_OK);
return FALSE;
}
return TRUE;
}

void V_Term()
{
SAFE_RELEASE( v_lpDDSBuffer);
SAFE_RELEASE( v_lpDDSB );
SAFE_RELEASE( v_lpDDSP );
SAFE_RELEASE( v_lpDD );
}

HRESULT V_Flip()
{
HRESULT hr=FALSE;
if( NULL == v_lpDDSB && NULL == v_lpDDSP ) return E_POINTER;
hr=v_lpDDSBuffer->BltFast( 0, 0, v_lpDDSB, NULL,DDBLTFAST_NOCOLORKEY|DDBLTFAST_WAIT);
// 就是这里的工作,为什么没有显示出来呢
while(TRUE)
{
hr = v_lpDDSP->Flip( NULL, 0 );
if(hr==DD_OK) break;
if( hr == DDERR_SURFACELOST )
{
hr = v_lpDDSP->Restore();
if(hr!=DD_OK) break;
}
if(hr!=DDERR_WASSTILLDRAWING) break;
}
return hr;
}

DWORD DDColorMatch(IDirectDrawSurface7 * pdds, COLORREF rgb)
{
COLORREF rgbT;
HDC hdc;
DWORD dw = CLR_INVALID;
DDSURFACEDESC2 ddsd;
HRESULT hres;

//
// Use GDI SetPixel to color match for us
//
if (rgb != CLR_INVALID && pdds->GetDC(&hdc) == DD_OK)
{
rgbT = GetPixel(hdc, 0, 0); // Save current pixel value
SetPixel(hdc, 0, 0, rgb); // Set our value
pdds->ReleaseDC(hdc);
}
//
// Now lock the surface so we can read back the converted color
//
ddsd.dwSize = sizeof(ddsd);
while ((hres = pdds->Lock(NULL, &ddsd, 0, NULL)) == DDERR_WASSTILLDRAWING)
;
if (hres == DD_OK)
{
dw = *(DWORD *) ddsd.lpSurface; // Get DWORD
if (ddsd.ddpfPixelFormat.dwRGBBitCount < 32)
dw &= (1 << ddsd.ddpfPixelFormat.dwRGBBitCount) - 1; // Mask it to bpp
pdds->Unlock(NULL);
}
//
// Now put the color that was there back.
//
if (rgb != CLR_INVALID && pdds->GetDC(&hdc) == DD_OK)
{
SetPixel(hdc, 0, 0, rgbT);
pdds->ReleaseDC(hdc);
}
return dw;
}

// Winodws主程序
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
MSG msg;
LONG r=0;
g_hInst = hInstance;
if (!InitWindow(nShowCmd))
{
MessageBox(NULL,"初始化窗口失败...\n","error",MB_OK);
return FALSE;
}
V_Init(g_hWnd);
//程序消息循环
while (TRUE)
{
//如果不是空消息
if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
//获得消息
if(!GetMessage(&msg, NULL, 0, 0)) //如果是退出消息
return msg.wParam; //则退出程序
//处理消息
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else if(g_bActive) //程序是否活动
{
r+=10;
if(r>255) r=0;
DWORD clr = RGB(r,0,0);
DDBLTFX bltfx;
RECT rect;
if(v_lpDDSBuffer == NULL) return FALSE;
clr = DDColorMatch(v_lpDDSBuffer,clr);
ZeroMemory( &bltfx, sizeof(bltfx) );
bltfx.dwSize = sizeof(bltfx);
bltfx.dwFillColor = clr;
rect.left = 0;
rect.top = 0;
rect.right = V_WIDTH;
rect.bottom = V_HEIGHT;
v_lpDDSBuffer->Blt( &rect, 0, 0, DDBLT_COLORFILL | DDBLT_WAIT, &bltfx );
// 用这个说什么也不行? 问题就在这里
V_Flip();
}
else
WaitMessage();
}
V_Term();
}

为什么不能向表面写入数据?
高手快回呀
...全文
115 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
潘李亮 2001-08-25
  • 打赏
  • 举报
回复
那么我的 lpDDSPrimry->GetDC(&hDC);没返回是怎么回事,(死在这儿了)
rayma 2001-08-25
  • 打赏
  • 举报
回复
bltfast没有硬件支持也应该有软件模拟啊,没有理由会出错的,是不是BltFast的参数有误?
gameboy999 2001-08-24
  • 打赏
  • 举报
回复
learning :)
这样才好呀,^_^
chinagdh 2001-08-23
  • 打赏
  • 举报
回复
我已经把问题的位置给出了!
看来以后不要问你们了,问了也白问
chenlee 2001-08-23
  • 打赏
  • 举报
回复
嘿嘿,大家是没耐心看这么长的程序
chinagdh 2001-08-23
  • 打赏
  • 举报
回复
问了半天,还得是我自已回答,

问题在于: 我这台机器没有bltfast功能支持。所以,用bltfast没有成功。
换用blt之后,就成功了。

8,303

社区成员

发帖
与我相关
我的任务
社区描述
游戏开发相关内容讨论专区
社区管理员
  • 游戏开发
  • 呆呆敲代码的小Y
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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