㊣我的第二个DirectX程序:256色下的淡入和淡出(100分)

  • 主题发起人 主题发起人 gxcooo
  • 开始时间 开始时间
G

gxcooo

Unregistered / Unconfirmed
GUEST, unregistred user!
刚考完《操作系统》,开始写我的第二个directx程序:256色下的淡入和淡出
先谈谈256色吧:
有些朋友一看到256色就以为是过时的东西,游戏中256色怎么够用呢?
其实256色模式可以描述为:调色板模式下24bit模式.在该模式下,每个像素都可以赋予0-255的
一个值,这些值作为参数,起到所谓的调色板输入项数组的作用,现在,数组中每个输入相对颜色中的每一个红、蓝、绿
强度都包含一个8bits值,结果使得用每8bits表示一个像素的颜色可以达到24bits深度,即16777216种颜色,但一屏只能显示其中的256种颜色。
所以只要你不断改变调色板就可以改变这256种颜色。
再谈谈画面的淡出:
屏幕上的每一个象数的颜色都存放在一个大小为256的数组中,数组中的每一项包括3*8bits.也就是说屏幕显示内存中存放的
不是这个点的真实颜色而是一个索引。我们只要改变这个索引所指向的颜色(保存在调色板中)就可以改变这点的颜色。
当我们要进行100步淡出时,我们每一步把调色板中的那256减去1%,这样就实现了淡出效果。
淡入时情况打假可想而知了吧。

例程:http://go.163.com/progame/mytest.html (网易没法做直接链接,所以大家必须访问这个页面,新加了一些好东西[:)])
源代码:
///////////////////////////////////////////////////////////////////////////////
// mytest_api.dpr
///////////////////////////////////////////////////////////////////////////////
// This is my test program;
///////////////////////////////////////////////////////////////////////////////
program mytest_api;

//-----------------------------------------------------------------------------
// Include files
//-----------------------------------------------------------------------------
uses
Windows, Messages, DirectDraw, SysUtils, DDUtil;

{$R *.res}

const
//---------------------------------------------------------------------------
// Local definitions
//---------------------------------------------------------------------------
NAME: PChar = 'DDExample2';
TITLE: PChar = 'Direct Draw Example 2';
szBitmap: PChar = 'Background.BMP';
Step: Integer = 100; //Fade In Step Count
var
//---------------------------------------------------------------------------
// Global data
//---------------------------------------------------------------------------
g_pDD: IDirectDraw7; // DirectDraw object
g_pDDSPrimary: IDirectDrawSurface7; // DirectDraw primary surface
g_pDDPal: IDIRECTDRAWPALETTE; // The primary surface palette
ddsd: TDDSurfaceDesc2;
AnimPalette, OrgPalette: array[0..255] of PALETTEENTRY;//调色板条目
g_bActive: Boolean = False; // Is application active?

//-----------------------------------------------------------------------------
// Name: ReleaseAllObjects
// Desc: Finished with all objects we use; release them
//-----------------------------------------------------------------------------

procedure ReleaseAllObjects;
begin
if Assigned(g_pDD) then
begin
if Assigned(g_pDDSPrimary) then
begin
g_pDDSPrimary := nil;
end;
if Assigned(g_pDDPal) then
begin
g_pDDPal := nil;
end;
g_pDD := nil;
end;
end;

//-----------------------------------------------------------------------------
// Name: InitFail
// Desc: This function is called if an initialization function fails
//-----------------------------------------------------------------------------

function InitFail(h_Wnd: HWND; hRet: HRESULT; Text: string): HRESULT;
begin
ReleaseAllObjects;
MessageBox(h_Wnd, PChar(Text + ': ' + DDErrorString(hRet)), TITLE, MB_OK);
DestroyWindow(h_Wnd);
Result := hRet;
end;

//-----------------------------------------------------------------------------
// Name: FadeOut
// Desc: FadeOut
//-----------------------------------------------------------------------------

procedure FadeOut;
var
i, j: integer;
begin
for i := 0 to Step do
begin
for j := 0 to 255 do
begin
AnimPalette[j].peRed := OrgPalette[j].peRed - Trunc((OrgPalette[j].peRed * i) / Step);
AnimPalette[j].peGreen := OrgPalette[j].peGreen - Trunc((OrgPalette[j].peGreen * i) / Step);
AnimPalette[j].peBlue := OrgPalette[j].peBlue - Trunc((OrgPalette[j].peBlue * i) / Step);
AnimPalette[j].peFlags := PC_RESERVED;
end;
g_pDDPal.SetEntries(0, 0, 256, @AnimPalette);
Sleep(30);
end;
end;

//-----------------------------------------------------------------------------
// Name: FadeIn
// Desc: FadeIn
//-----------------------------------------------------------------------------

procedure FadeIn;
var
i, j: integer;
begin
for i := 0 to Step do
begin
for j := 0 to 255 do
begin
AnimPalette[j].peRed := Trunc((OrgPalette[j].peRed * i) / Step);
AnimPalette[j].peGreen := Trunc((OrgPalette[j].peGreen * i) / Step);
AnimPalette[j].peBlue := Trunc((OrgPalette[j].peBlue * i) / Step);
AnimPalette[j].peFlags := PC_RESERVED;
end;
g_pDDPal.SetEntries(0, 0, 256, @AnimPalette);
Sleep(30);
end;
end;

//-----------------------------------------------------------------------------
// Name: InitSurface
// Desc: Load a Bitmap into PrimarySurface.
//-----------------------------------------------------------------------------

function InitSurface: Boolean;
var
hbm: HBITMAP;
begin
Result := false;
hbm := LoadImage(0, szBitmap, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE or LR_CREATEDIBSECTION);
if hbm = 0 then
Exit;
DDCopyBitmap(g_pDDSPrimary, hbm, 0, 0, 640, 480);
Result := true;
end;

//-----------------------------------------------------------------------------
// Name: WindowProc
// Desc: The Main Window Procedure
//-----------------------------------------------------------------------------

function WindowProc(h_Wnd: HWND; aMSG: Cardinal; wParam: Cardinal; lParam: Integer): Integer; stdcall;
begin
case aMSG of
// Pause if minimized
WM_ACTIVATE:
begin
if HIWORD(wParam) = 0 then
g_bActive := True
else
g_bActive := False;
Result := 0;
Exit;
end;
// Clean up and close the app
WM_DESTROY:
begin
ReleaseAllObjects;
PostQuitMessage(0);
Result := 0;
Exit;
end;
// Handle any non-accelerated key commands
WM_KEYDOWN:
begin
case wParam of
VK_ESCAPE:
begin
FadeOut;
PostMessage(h_Wnd, WM_CLOSE, 0, 0);
Result := 0;
Exit;
end;
VK_F11: FadeIn;
Vk_F12: begin
FadeOut;
FadeIn;
end;
end;
end;
// Turn off the cursor since this is a full-screen app
WM_SETCURSOR:
begin
SetCursor(0);
Result := 1;
Exit;
end;
end;

Result := DefWindowProc(h_Wnd, aMSG, wParam, lParam);
end;

//-----------------------------------------------------------------------------
// Name: InitApp
// Desc: Do work required for every instance of the application:
// Create the window, initialize data
//-----------------------------------------------------------------------------

function InitApp(hInst: THANDLE; nCmdShow: Integer): HRESULT;
var
h_Wnd: HWND;
wc: WNDCLASS;
hRet: HRESULT;
pDDTemp: IDirectDraw;
begin
// Set up and register window class
wc.style := CS_HREDRAW or CS_VREDRAW;
wc.lpfnWndProc := @WindowProc;
wc.cbClsExtra := 0;
wc.cbWndExtra := 0;
wc.hInstance := hInst;
wc.hIcon := LoadIcon(hInst, 'MAINICON');
wc.hCursor := LoadCursor(0, IDC_ARROW);
wc.hbrBackground := GetStockObject(BLACK_BRUSH);
wc.lpszMenuName := NAME;
wc.lpszClassName := NAME;
RegisterClass(wc);

// Create a window
h_Wnd := CreateWindowEx(WS_EX_TOPMOST,
NAME,
TITLE,
WS_POPUP,
0,
0,
GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN),
0,
0,
hInst,
nil);

if h_Wnd = 0 then
begin
Result := 0;
Exit;
end;

ShowWindow(h_Wnd, nCmdShow);
UpdateWindow(h_Wnd);
SetFocus(h_Wnd);

///////////////////////////////////////////////////////////////////////////
// Create the main DirectDraw object
///////////////////////////////////////////////////////////////////////////
hRet := DirectDrawCreate(nil, pDDTemp, nil);
if hRet <> DD_OK then
begin
Result := InitFail(h_Wnd, hRet, 'DirectDrawCreate FAILED');
Exit;
end;
hRet := pDDTemp.QueryInterface(IDirectDraw7, g_pDD);
if hRet <> DD_OK then
begin
Result := InitFail(h_Wnd, hRet, 'QueryInterface FAILED');
Exit;
end;
pDDTemp := nil;

// Get exclusive mode
hRet := g_pDD.SetCooperativeLevel(h_Wnd, DDSCL_EXCLUSIVE or DDSCL_FULLSCREEN);
if hRet <> DD_OK then
begin
Result := InitFail(h_Wnd, hRet, 'SetCooperativeLevel FAILED');
Exit;
end;

// Set the video mode to 640X480x8
hRet := g_pDD.SetDisplayMode(640, 480, 8, 0, 0);
if hRet <> DD_OK then
begin
Result := InitFail(h_Wnd, hRet, 'SetDisplayMode FAILED');
Exit;
end;

// Create the primary surface
FillChar(ddsd, SizeOf(ddsd), 0);
ddsd.dwSize := SizeOf(ddsd);
ddsd.dwFlags := DDSD_CAPS;
ddsd.ddsCaps.dwCaps := DDSCAPS_PRIMARYSURFACE;
hRet := g_pDD.CreateSurface(ddsd, g_pDDSPrimary, nil);
if hRet <> DD_OK then
begin
Result := InitFail(h_Wnd, hRet, 'CreateSurface FAILED');
Exit;
end;

// Create and set the palette
g_pDDPal := DDLoadPalette(g_pDD, szBitmap);
if g_pDDPal = nil then
begin
Result := InitFail(h_Wnd, hRet, 'DDLoadPalette FAILED');
Exit;
end;

hRet := g_pDDSPrimary.SetPalette(g_pDDPal);
if hRet <> DD_OK then
begin
Result := InitFail(h_Wnd, hRet, 'SetPalette FAILED');
Exit;
end;
//取得调色板条目
g_pDDpal.GetEntries(0, 0, 256, @OrgPalette);

if not InitSurface then
Exit;

Result := DD_OK;
end;

//-----------------------------------------------------------------------------
// Name: WinMain
// Desc: Initialization, message loop
//-----------------------------------------------------------------------------

type
Screen = array of Word;
var
aMSG: MSG;
begin
if InitApp(GetModuleHandle(nil), SW_SHOW) <> DD_OK then
begin
Exit;
end;

while True do
begin
if PeekMessage(aMsg, 0, 0, 0, PM_NOREMOVE) then
begin
if not GetMessage(aMsg, 0, 0, 0) then
Exit;
TranslateMessage(aMsg);
DispatchMessage(aMsg);
end
else if g_bActive then
begin
if g_pDDSPrimary.IsLost = DD_OK then
begin
if g_pDDSPrimary._Restore <> DD_OK then exit;
InitSurface;
end;
end
else
begin
// Make sure we go to sleep if we have nothing else to do
WaitMessage;
end;
end;

end.



 
请上传到
http://www.playicq.com

谢谢!
 
to tomore:
谢谢你介绍这个好地方!
 
我们图形图象领域果真是人才济济,鼓励!
 
to gxcooo
呵呵!不错,你的空战游戏啥时候完工呀?
 
xdzhan,晚上好!
不好意思,我还在问自己什么时候开工呢?[:)]
现在忙着考试,打算寒假里做。可那时就没有免费的宽带享用了,唉[:(]
 
to gxcooo
这儿有一个开放源码的2D空战游戏!去看看呀!
http://www.visuel-electronics.de/index.html
http://www.srcco.de

 
真是诲人不倦啊[8D]
 
高手!!!
佩服佩服!
人才
 
多人接受答案了。
 
后退
顶部