ddraw 的blt 方法

// ------------------------------------------------------------------------- 
// 文件名      :  7_7.cpp
// 创建者      :  方煜宽
// 邮箱        :  [email protected]
// 创建时间    :  2010-12-18 17:04
// 功能描述    :  从一个表面向另一个表面复制位图 
// 地址   :  http://www.cnblogs.com/fangyukuan/archive/2011/06/08/2075907.html 
// -------------------------------------------------------------------------
#define INITGUID


#include<windows.h>
#include <ddraw.h>


#pragma   comment(lib,   "ddraw.lib")
#pragma   comment(lib,   "Dxguid.lib")
#pragma   comment(lib,   "User32.lib")
#pragma   comment(lib,   "Gdi32.lib")




LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);


HWND main_window_handle = NULL; // 全局的windows窗口句柄
int window_closed = 0; // 窗口关闭标志


LPDIRECTDRAW7 lpdd = NULL; // ddraw 接口指针
DDSURFACEDESC2 ddsd; // ddraw 显示表面 描述结构
LPDIRECTDRAWSURFACE7  lpddsprimary = NULL; // ddraw 主显示表面
LPDIRECTDRAWSURFACE7  lpddsback    = NULL; // ddraw 从显示表面


#define SCREEN_WIDTH    640 // 屏幕宽
#define SCREEN_HEIGHT   480 // 屏幕高
#define SCREEN_BPP      16 // 深度


#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEYUP(vk_code)   ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)


// this builds a 16 bit color value in 5.5.5 format (1-bit alpha mode)
#define _RGB16BIT555(r,g,b) ((b & 31) + ((g & 31) << 5) + ((r & 31) << 10))


// this builds a 16 bit color value in 5.6.5 format (green dominate mode)
#define _RGB16BIT565(r,g,b) ((b & 31) + ((g & 63) << 5) + ((r & 31) << 11))


// this builds a 32 bit color value in A.8.8.8 format (8-bit alpha mode)
#define _RGB32BIT(a,r,g,b) ((b) + ((g) << 8) + ((r) << 16) + ((a) << 24))


#define DDRAW_INIT_STRUCT(ddstruct) { memset(&ddstruct, 0, sizeof(ddstruct)); ddstruct.dwSize = sizeof(ddstruct);}




int InitGame()
{
if (FAILED(DirectDrawCreateEx(NULL, (void **)&lpdd, IID_IDirectDraw7, NULL)))
return 0;


if (FAILED(lpdd->SetCooperativeLevel(main_window_handle, 
DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT)))
return 0;


if (FAILED(lpdd->SetDisplayMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, 0, 0)))
return 0;


DDRAW_INIT_STRUCT(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; // 增加DDSD_BACKBUFFERCOUNT 表明dwBackBufferCount有效
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE  | DDSCAPS_COMPLEX | DDSCAPS_FLIP; //  多了| DDSCAPS_COMPLEX | DDSCAPS_FLIP
ddsd.dwBackBufferCount = 1; // 




if (FAILED(lpdd->CreateSurface(&ddsd, &lpddsprimary, NULL)))
return 0;


// 请求一个后备缓冲
ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;

// 得到后备缓冲
if (FAILED(lpddsprimary->GetAttachedSurface(&ddsd.ddsCaps, &lpddsback)))
return 0;


DDRAW_INIT_STRUCT(ddsd);


if (FAILED(lpddsback->Lock(NULL,&ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL)))
return 0;


USHORT *video_buffer = (USHORT *)ddsd.lpSurface;


for (int y = 0; y < SCREEN_HEIGHT; y++)
{
DWORD color = _RGB16BIT565(0,(y >> 3),0);


// 32位的颜色
color = (color) | (color << 16);


_asm
{
CLD ; clear direction of copy to forward
MOV EAX, color             ; color goes here
MOV ECX, (SCREEN_WIDTH / 2)  ; number of DWORDS goes here
MOV EDI, video_buffer      ; address of line to move data
REP STOSD                  ; send the pentium X on its way
}
// 跟上面的汇编等效
// for (DWORD ecx = 0, *edi = (DWORD*)video_buffer; ecx < (SCREEN_WIDTH / 2); ecx++)
// edi[ecx]= color;


video_buffer += (ddsd.lPitch >> 1);
}


if (FAILED(lpddsback->Unlock(NULL)))
return 0;


return 1;
}




int TermGame()
{
if (lpddsback)
{
lpddsback->Release();
lpddsback = NULL;
}


if (lpddsprimary)
{
lpddsprimary->Release();
lpddsprimary = NULL;
}


if (lpdd)
{
lpdd->Release();
lpdd = NULL;
}


return 1;
}


int MainGame()
{
if (window_closed)
return 0;


if (KEYDOWN(VK_ESCAPE))
{
PostMessage(main_window_handle,WM_CLOSE,0,0);
window_closed = 1;
}

// 随机生成一个源区域
RECT rectSrc;
rectSrc.left   = rand()%SCREEN_WIDTH;
rectSrc.top    = rand()%SCREEN_HEIGHT;
rectSrc.right  = rand()%SCREEN_WIDTH;
rectSrc.bottom = rand()%SCREEN_HEIGHT;


// 随机生成一个目标区域
RECT rectDst;
rectDst.left   = rand()%SCREEN_WIDTH;
rectDst.top    = rand()%SCREEN_HEIGHT;
rectDst.right  = rand()%SCREEN_WIDTH;
rectDst.bottom = rand()%SCREEN_HEIGHT;


// blitter
if (FAILED(lpddsprimary->Blt(&rectDst,
lpddsback,
&rectSrc,
DDBLT_WAIT,
NULL)))
{
return 0;
}

Sleep(500);


return 1;
}


int WINAPI WinMain(HINSTANCE hInstance,
  HINSTANCE hPrevInstance,
  LPSTR lpCmdLine,
  int nShowCmd)
{
HWND hwnd;
MSG msg;
TCHAR lpszClassName[] = TEXT("kuan");


WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = ::LoadIcon(NULL,IDI_APPLICATION);
wc.hCursor = ::LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground = (HBRUSH)::GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = lpszClassName;


RegisterClass(&wc);


hwnd = CreateWindow(lpszClassName,
TEXT("fangyukuan"),
WS_POPUP | WS_VISIBLE,
0,0,SCREEN_WIDTH,SCREEN_HEIGHT,
NULL,
NULL,
hInstance,
NULL);
main_window_handle = hwnd;


InitGame();
while(TRUE)
{
if (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))

if (msg.message == WM_QUIT)
break;


::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
MainGame();


}
TermGame();


return msg.wParam;
}


LRESULT CALLBACK WndProc(HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
switch(message)
{
case WM_LBUTTONDOWN:
{
::MessageBeep(0); 
}
break;
case WM_DESTROY:
::PostQuitMessage(0);
break;
default:
return ::DefWindowProc(hwnd,message,wParam,lParam);
}
return 0;
}

你可能感兴趣的:(ddraw 的blt 方法)