directx:DirectX - tasy (II)(节选)



  我们继续上次话题

   上讲中我们介绍了下具体步骤下面清单 1.0 包含了所有功能以及个展示如何操作显存和键盘例子我们简单地将它作为个演示

// LISTING 1.0 - DIRECT X 5.0 GAME CONSOLE ////////////////////////////////////

// INCLUDES ///////////////////////////////////////////////////////////////////

# WIN32_LEAN_AND_MEAN // make sure certain headers are d correctly

# <windows.h> // the standard windows stuff
# <windowsx.h> // the 32 bit stuff
# <mmsystem.h> // the multi media stuff
// note you need winmm.lib also
# <ddraw.h> // direct draw components

# <stdlib.h> // all the good stuff
# <stdio.h>
# <math.h>
# <float.h>

// DEFINES ////////////////////////////////////////////////////////////////////

# WINDOW_CLASS_NAME \"WINDOW_CLASS\" // this is the name of the window

// s for screen parameters

# SCREEN_WIDTH 640 // the width of the viewing surface
# SCREEN_HEIGHT 480 // the height of the viewing surface
# SCREEN_BPP 8 // the bits per pixel
# MAX_COLORS 256 // the maximum number of colors

// TYPES //////////////////////////////////////////////////////////////////////

typedef unsigned char UCHAR;

// MACROS /////////////////////////////////////////////////////////////////////

// these query the keyboard in real-time

# KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
# KEY_UP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)

// PROTOTYPES /////////////////////////////////////////////////////////////////

DD_Init(HWND hwnd);
DD_Shutdown(void);
Set_Pal_Entry( index, red, green, blue);

void Game_Init(void);
void Game_Main(void);
void Game_Shutdown(void);

// DIRECTDRAW GLOBALS ////////////////////////////////////////////////////////

LPDIRECTDRAW lpdd = NULL; // dd object
LPDIRECTDRAWSURFACE lpddsprimary = NULL; // dd primary surface
LPDIRECTDRAWPALETTE lpddpal = NULL; // a poer to the created dd palette
PALETTEENTRY color_palette[256]; // holds the shadow palette entries
DDSURFACEDESC ddsd; // a direct draw surface description struct
DDSCAPS ddscaps; // a direct draw surface capabilities struct
HRESULT ddrval; // result back from dd calls
HWND _window_handle = NULL; // used to store the window handle
UCHAR *video_buffer = NULL; // poer to video ram




// GAME GLOBALS GO HERE /////////////////////////////////////////////////////

// DIRECT X FUNCTIONS /////////////////////////////////////////////////////////

DD_Init(HWND hwnd)
{
// this function is responsible for initializing direct draw, it creates a
// primary surface

index; // looping index

// now that the windows portion is complete, start up direct draw
(DirectDrawCreate(NULL,&lpdd,NULL)!=DD_OK)
{
// shutdown any other dd objects and kill window
DD_Shutdown;
(0);
} // end

// now the coop level to exclusive and for full screen and mode x
(lpdd->SetCooperativeLevel(hwnd, DDSCL_ALLOWREBOOT | DDSCL_EXCLUSIVE |
DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX)!=DD_OK)
{
// shutdown any other dd objects and kill window
DD_Shutdown;
(0);
} // end

// now the display mode
(lpdd->SetDisplayMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP)!=DD_OK)
{
// shutdown any other dd objects and kill window
DD_Shutdown;
(0);
} // end

// Create the primary surface
ddsd.dwSize = (ddsd);
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;


(lpdd->CreateSurface(&ddsd,&lpddsprimary,NULL)!=DD_OK)
{
// shutdown any other dd objects and kill window
DD_Shutdown;
(0);
} // end

// create the palette and attach it to the primary surface

// clear all the palette entries to RGB 0,0,0
mem(color_palette,0,256*(PALETTEENTRY));

// all of the flags to the correct value
for (index=0; index<256; index)
{
// create the GRAY/RED/GREEN/BLUE palette, 64 shades of each
((index / 64)0)
{
color_palette[index].peRed = index*4;
color_palette[index].peGreen = index*4;
color_palette[index].peBlue = index*4;
} // end

((index / 64)1)
color_palette[index].peRed = (index%64)*4;

((index / 64)2)
color_palette[index].peGreen = (index%64)*4;

((index / 64)3)
color_palette[index].peBlue = (index%64)*4;

// the no collapse flag
color_palette[index].peFlags = PC_NOCOLLAPSE;

} // end for index

// now create the palette object, note that it is a member of the dd object itself
(lpdd->CreatePalette((DDPCAPS_8BIT | DDPCAPS_INITIALIZE),color_palette,&lpddpal,NULL)!=DD_OK)
{
// shutdown any other dd objects and kill window
DD_Shutdown;
(0);
} // end

// now attach the palette to the primary surface
lpddsprimary->SetPalette(lpddpal);



// success we got this far
(1);

} // end DD_Init

///////////////////////////////////////////////////////////////////////////////

DD_Shutdown(void)
{
// this function tests for dd components that have been created and releases
// them back to the operating system

// test the dd object exists
(lpdd)
{
// test there is a primary surface
(lpddsprimary)
{
// release the memory and poer to NULL
lpddsprimary->Release;
lpddsprimary = NULL;
} // end

// now release the dd object itself
lpdd->Release;
lpdd = NULL;

// success
(1);

} // end

(0);

} // end DD_Shutdown

//////////////////////////////////////////////////////////////////////////////

Set_Pal_Entry( index, red, green, blue)
{
// this function s a palette entry with the sent color

PALETTEENTRY color; // used to build up color

// RGB value in structure
color.peRed = (BYTE)red;
color.peGreen = (BYTE)green;
color.peBlue = (BYTE)blue;
color.peFlags = PC_NOCOLLAPSE;

// the color palette entry
lpddpal->SetEntries(0,index,1,&color);

// make copy in shadow palette
memcpy(&color_palette[index],
&color,
(PALETTEENTRY));

// success
(1);

} // end Set_Pal_Entry

// WINDOWS CALLBACK FUNCTION //////////////////////////////////////////////////

LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
// this is the message handler of the system

HDC hdc; // handle to graphics context
PAINTSTRUCT ps; // used to hold the pa info

// what is the message?

switch(msg)
{
WM_CREATE:
{
// do windows inits here
(0);
} ;

WM_PAINT:
{
// this message occurs when your window needs repaing
hdc = BeginPa(hwnd,&ps);
EndPa(hwnd,&ps);

(0);
} ;

WM_DESTROY:
{
// this message is sent when your window is destroyed
PostQuitMessage(0);
(0);
} ;

default:;

} // end switch

// let windows process any messages that we didn\'t take care of
(DefWindowProc(hwnd, msg, wparam, lparam));



} // end

} // end while

// shut down direct draw
DD_Shutdown;

// shutdown game
Game_Shutdown;

// to Windows
(msg.wParam);

} // end WinMain

// HERE ARE OUR GAME CONSOLE FUNCTIONS ///////////////////////////////////////////////////////

void Game_Init(void)
{
// do any initialization here
} // end Game_Init

/////////////////////////////////////////////////////////////////////////////////////////////

void Game_Shutdown(void)
{
// cleanup and release all resources here
} // end Game_Shutdown

/////////////////////////////////////////////////////////////////////////////////////////////

void Game_Main(void)
{
// process your game logic and draw next frame
// this function must exit each frame and back to windows
// also this function is responsible for controlling the frame rate
// therefore, you want the game to run at 30fps, then the function should
// take 1/30th of a second before ing

px = SCREEN_WIDTH/2, // position of player
py = SCREEN_HEIGHT/2,
color = 0; // color of blob 0..3, gray, red, green, blue

// _disibledevent=>

(KEY_DOWN(VK_ESCAPE))
PostMessage(_window_handle,WM_CLOSE,0,0); // this is how you exit you game

// which way is player moving
(KEY_DOWN(VK_RIGHT))
(px>SCREEN_WIDTH-8) px=8;

(KEY_DOWN(VK_LEFT))
(--px<8) px=SCREEN_WIDTH-8;

(KEY_DOWN(VK_UP))
(--py<8) py=SCREEN_HEIGHT-8;

(KEY_DOWN(VK_DOWN))
(py>SCREEN_HEIGHT-8) py=8;

// adjust color, notice
(KEY_DOWN(\'C\'))
{
(color>=4)
color=0;
Sleep(100);
} // end

// draw graphics
for ( pixels=0; pixels<32; pixels)
video_buffer[(px-4+rand%8)+(py-4+rand%8)*SCREEN_WIDTH] = (color*64)+rand%64;

// sync time (optional)

// use sleep to slow system down to 70ish fps
Sleep(14); // note that Sleep is extremly inaccurate, IRL you would use something more robust

// and let windows have some time

} // end Game_Main

   要编译这个并且运行它你需要在工程中包括库文件 DDRAW.LIB 和头文件 DDRAW.H 他们通过设置搜索路径存在于你 IDE 中或者是直接加到工程中去目标应该是个标准 Windows 在建立了运行它你应该可以看到个炽热水滴并且可以通过方向键来移动它<C> 键可以更改色彩按 <ESC> 可以退出现在你拥有了开始体验 DirectX 基础所有东西了你可以通过常量 SCREEN_WIDTH 和 SCREEN_HEIGHT 来尝试双缓冲、区别分辨率甚至是调色板颜色变换



   现在只剩下个可能引起问题了如果你显卡不能简单地为 DirectX 创建个线形显存模式你必须直接仔细得操作显卡了举个简单例子如果你创建了个 640 象素每行即在 640x480x256 色模式中操作下显存你必须加上 640或者是般地操作个象素点你可以这样写:

     video_buffer[x + y*640] = pixel;

   无论如何如果你显卡无法支持线形内存那么你必须去修改以便能直接真正地操作显存“线形内存跨度”这个值会比象素值大举个例子它在 640 个象素每行模式中甚至可能是 1024 个象素这个线形跨度能够通过锁定个 DirectDraw 表面描述来访问像这样:

     // 我们可以这样锁定
     lpddsprimary->Lock(NULL,&ddsd,DDLOCK_SURFACEMEMORYPTR,NULL);
    video_buffer = (UCHAR *)ddsd.lpSurface;

     // 这里就是我们可以用于操作
     lpitch = ddsd.lPitch;

   那么我们可以通过下面思路方法来直接操作显存了:

     video_buffer[x + y*lpitch] = pixel;

   因此最安全思路方法是去经常使用我们修改后得到但是这个思路方法牺牲了极大性能因此你可能会去测试他们是否会是个相等然后使用个区别基于此原理渲染

[本文例子源代码下载]

Tags:  directx9 directx9.0 directx9.0c directx

延伸阅读

最新评论

发表评论