本篇是
创建游戏内核(9)的续篇,其中涉及到的3D图形基础知识请参阅D3D中基本三角形面的绘制。
图形系统和GRAPHICS
GRAPHICS用于设置显示模式和渲染状态以及清除设备等,一旦初始化了GRAPHICS对象,就能够同几乎所有图形内核的类组件结合起来使用。
来看看GRAPHICS类的定义:
class GRAPHICS
{
protected:
HWND _hwnd; // window handle pointer to parent window
IDirect3D9* _d3d; // pointer to Direct3D
IDirect3DDevice9* _d3d_device; // pointer to Direct3D device
ID3DXSprite* _sprite; // pointer to Direct3D sprite
D3DDISPLAYMODE _display_mode; // display mode
BOOL _is_windowed; // flag indicates whether use window mode
BOOL _use_zbuffer; // flag indicates whethre use z-buffer
BOOL _support_hal; // flag indicates whether support hardware accelerator
long _width; // display mode width
long _height; // display mode height
char _bpp; // bits per pixel
unsigned char _ambient_red; // ambient red color value
unsigned char _ambient_green; // ambient green color value
unsigned char _ambient_blue; // ambient blue color value
public:
GRAPHICS();
~GRAPHICS();
IDirect3D9* Get_Direct3D_COM();
IDirect3DDevice9* Get_Device_COM();
ID3DXSprite* Get_Sprite_COM();
BOOL Init();
void Shutdown();
BOOL Set_Mode(HWND hwnd, BOOL is_windowed = TRUE, BOOL use_zbuffer = FALSE,
long width = 0, long height = 0, char bpp = 0);
long Get_Num_Display_Modes(D3DFORMAT format);
BOOL Get_Display_Mode_Info(long mode_index, D3DDISPLAYMODE* display_mode, D3DFORMAT format);
char Get_Format_Bpp(D3DFORMAT format);
BOOL Check_Format(D3DFORMAT format, BOOL is_windowed, BOOL support_hal);
BOOL Display();
BOOL Begin_Scene();
BOOL End_Scene();
BOOL Begin_Sprite();
BOOL End_Sprite();
BOOL Clear(long color = 0, float zbuffer = 1.0f);
BOOL Clear_Display(long color = 0);
BOOL Clear_ZBuffer(float zbuffer = 1.0f);
long Get_Width();
long Get_Height();
char Get_Bpp();
BOOL Support_Hal();
BOOL Use_ZBuffer();
BOOL Set_Perspective(float fov = D3DX_PI / 4.0f, float aspect = 1.3333f,
float near_z = 1.0f, float far_z = 10000.0f);
BOOL Set_World_Position(WORLD_POSITION* world_pos);
BOOL Set_Camera(CAMERA* camera);
BOOL Set_Light(long light_index, LIGHT* light);
BOOL Set_Material(MATERIAL* material);
BOOL Set_Texture(short texture_sample, TEXTURE* texture);
BOOL Set_Ambient_Light(unsigned char red, unsigned char green, unsigned char blue);
void Get_Ambient_Light(unsigned char* red, unsigned char* green, unsigned char* blue);
BOOL Enable_Light(long light_index, BOOL enable = TRUE);
BOOL Enable_Lighting(BOOL enable = TRUE);
BOOL Enable_ZBuffer(BOOL enable = TRUE);
BOOL Enable_Alpha_Blendin(BOOL enable = TRUE, DWORD source = D3DBLEND_SRCALPHA,
DWORD dest = D3DBLEND_INVSRCALPHA);
BOOL Enable_Alpha_Testing(BOOL enalbe = TRUE);
};
再来看看类GRAPHICS的实现:
//-------------------------------------------------------------------
// Constructor, initialize data member.
//-------------------------------------------------------------------
GRAPHICS::GRAPHICS()
{
_hwnd = NULL;
_d3d = NULL;
_d3d_device = NULL;
_sprite = NULL;
_ambient_red = _ambient_green = _ambient_blue = 255;
_width = 0;
_height = 0;
_bpp = 0;
_is_windowed = TRUE;
_use_zbuffer = FALSE;
_support_hal = FALSE;
}
//-------------------------------------------------------------------
// Destructor, release all COM objects.
//-------------------------------------------------------------------
GRAPHICS::~GRAPHICS()
{
Shutdown();
}
//-------------------------------------------------------------------
// Initialize graphics component, just create Direct3D object.
//-------------------------------------------------------------------
BOOL GRAPHICS::Init()
{
Shutdown();
return ((_d3d = Direct3DCreate9(D3D_SDK_VERSION)) != NULL);
}
//-------------------------------------------------------------------
// Set display mode for D3D.
//-------------------------------------------------------------------
BOOL GRAPHICS::Set_Mode(HWND hwnd, BOOL is_windowed, BOOL use_zbuffer, long width, long height, char bpp)
{
D3DPRESENT_PARAMETERS present_para;
D3DFORMAT format, alt_format;
RECT wnd_rect, client_rect;
long wnd_width, wnd_height;
float aspect;
// error checking
if((_hwnd = hwnd) == NULL || _d3d == NULL)
return FALSE;
// 1) get the current display format
if(FAILED(_d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &_display_mode)))
return FALSE;
// 2) Configure width, height, bpp; resizing window.
// configure width
if(width == 0)
{
if(! is_windowed) // default to screen width if fullscreen
_width = _display_mode.Width;
else // otherwise grab from client size
{
GetClientRect(_hwnd, &client_rect);
_width = client_rect.right;
}
}
else
_width = width;
// configure height
if(height == 0)
{
if(! is_windowed) // default to screen height if fullscreen
_height = _display_mode.Height;
else // Otherwise grab from client size
{
GetClientRect(_hwnd, &client_rect);
_height = client_rect.bottom;
}
}
else
_height = height;
// configure bpp
if(!(_bpp = bpp) || is_windowed)
{
// get dsiplay bpp
if(! (_bpp = Get_Format_Bpp(_display_mode.Format)))
return FALSE;
}
// resize client window if using windowed mode
if(is_windowed)
{
GetWindowRect(_hwnd, &wnd_rect);
GetClientRect(_hwnd, &client_rect);
wnd_width = (wnd_rect.right - wnd_rect.left) - client_rect.right + _width;
wnd_height = (wnd_rect.bottom - wnd_rect.top) - client_rect.bottom + _height;
MoveWindow(_hwnd, wnd_rect.left, wnd_rect.top, wnd_width, wnd_height, TRUE);
}
// 3) setup presentation parameters
// clear presentation structure
ZeroMemory(&present_para, sizeof(D3DPRESENT_PARAMETERS));
// default to no hardware acceleration detected
_support_hal = FALSE;
// setup windowed or fullscreen usage
if((_is_windowed = is_windowed) == TRUE)
{
present_para.Windowed = TRUE;
present_para.SwapEffect = D3DSWAPEFFECT_DISCARD;
present_para.BackBufferFormat = _display_mode.Format;
// see if video card supports hardware acceleration
if(! Check_Format(_display_mode.Format, TRUE, TRUE))
return FALSE;
_support_hal = TRUE;
}
else // fullscreen mode
{
present_para.Windowed = FALSE;
present_para.SwapEffect = D3DSWAPEFFECT_FLIP;
present_para.BackBufferWidth = _width;
present_para.BackBufferHeight = _height;
present_para.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
present_para.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
// figure display format to use
if(_bpp == 32)
{
format = D3DFMT_X8R8G8B8;
alt_format = D3DFMT_X8R8G8B8;
}
else if(_bpp == 24)
{
format = D3DFMT_R8G8B8;
alt_format = D3DFMT_R8G8B8;
}
else if(_bpp == 16)
{
format = D3DFMT_R5G6B5;
alt_format = D3DFMT_X1R5G5B5;
}
else if(_bpp = 8)
{
format = D3DFMT_P8;
alt_format = D3DFMT_P8;
}
// check for hal device
if(Check_Format(format, FALSE, TRUE))
_support_hal = TRUE;
else
{
// check for hal device in alternate format
if(Check_Format(alt_format, FALSE, TRUE))
{
_support_hal = TRUE;
format = alt_format;
}
else
{
// check for emulation device in alternate format
if(! Check_Format(alt_format, FALSE, FALSE))
return FALSE;
else
format = alt_format;
}
}
present_para.BackBufferFormat = format;
}
// setup zbuffer format - 16bit
if((_use_zbuffer = use_zbuffer) == TRUE)
{
present_para.EnableAutoDepthStencil = TRUE;
present_para.AutoDepthStencilFormat = D3DFMT_D16;
}
else
present_para.EnableAutoDepthStencil = FALSE;
// create the Direct3D device object
if(FAILED(_d3d->CreateDevice(D3DADAPTER_DEFAULT,
_support_hal ? D3DDEVTYPE_HAL : D3DDEVTYPE_REF,
hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_para, &_d3d_device)))
{
if(! _use_zbuffer)
return FALSE;
// Now, create Direct3D device no use zbuffer.
_use_zbuffer = FALSE;
present_para.EnableAutoDepthStencil = FALSE;
if(FAILED(_d3d->CreateDevice(D3DADAPTER_DEFAULT,
_support_hal ? D3DDEVTYPE_HAL : D3DDEVTYPE_REF,
hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_para, &_d3d_device)))
{
return FALSE;
}
}
// 4) set rendering state
// set default rendering states
Enable_Lighting(FALSE);
Enable_ZBuffer(_use_zbuffer);
Enable_Alpha_Blending(FALSE);
Enable_Alpha_Testing(FALSE);
// Enable texture rendering stages and filter types
_d3d_device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
_d3d_device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
_d3d_device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
// Set the sampler state value
_d3d_device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
_d3d_device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
// 5) set color and transform matrix
// Set default ambient color to white
Set_Ambient_Light(255, 255, 255);
// calculate the aspect ratio based on window size
aspect = (float)_height / _width;
Set_Perspective(D3DX_PI/4, aspect, 1.0f, 10000.0f);
// 6) create sprite object
// Create a sprite object which is associated with a particular device.
// Sprite objects are used to draw 2D image to the screen.
if(FAILED(D3DXCreateSprite(_d3d_device, &_sprite)))
return FALSE;
return TRUE;
}
//-------------------------------------------------------------------
// Release graphics COM object.
//-------------------------------------------------------------------
void GRAPHICS::Shutdown()
{
Release_COM(_sprite);
Release_COM(_d3d_device);
Release_COM(_d3d);
}
//-------------------------------------------------------------------------
// Get pointer to Direct3D.
//-------------------------------------------------------------------------
IDirect3D9* GRAPHICS::Get_Direct3D_COM()
{
return _d3d;
}
//-------------------------------------------------------------------------
// Get pointer to Direct3D device.
//-------------------------------------------------------------------------
IDirect3DDevice9* GRAPHICS::Get_Device_COM()
{
return _d3d_device;
}
//-------------------------------------------------------------------
// Get pointer to Direct3D sprite.
//-------------------------------------------------------------------
ID3DXSprite* GRAPHICS::Get_Sprite_COM()
{
return _sprite;
}
//-------------------------------------------------------------------
// Returns the number of display modes available on this adapter.
//-------------------------------------------------------------------
long GRAPHICS::Get_Num_Display_Modes(D3DFORMAT format)
{
if(_d3d == NULL)
return 0;
return (long)_d3d->GetAdapterModeCount(D3DADAPTER_DEFAULT, format);
}
//-------------------------------------------------------------------
// Get display mode information.
//-------------------------------------------------------------------
BOOL GRAPHICS::Get_Display_Mode_Info(long mode_index, D3DDISPLAYMODE* display_mode, D3DFORMAT format)
{
if(_d3d == NULL)
return FALSE;
// Get the number of display modes available on this adapter
long max_mode = Get_Num_Display_Modes(format);
if(mode_index >= max_mode)
return FALSE;
// Queries the device to determine whether the specified adapter supports the requested format and display mode.
// This method could be used in a loop to enumerate all the available adapter modes.
if(FAILED(_d3d->EnumAdapterModes(D3DADAPTER_DEFAULT, format, mode_index, display_mode)))
return FALSE;
return TRUE;
}
//-------------------------------------------------------------------
// Get display mode BPP.
//-------------------------------------------------------------------
char GRAPHICS::Get_Format_Bpp(D3DFORMAT format)
{
switch(format)
{
// 32 bit modes
case D3DFMT_A8R8G8B8:
case D3DFMT_X8R8G8B8:
return 32;
// 24 bit modes
case D3DFMT_R8G8B8:
return 24;
// 16 bit modes
case D3DFMT_R5G6B5:
case D3DFMT_X1R5G5B5:
case D3DFMT_A1R5G5B5:
case D3DFMT_A4R4G4B4:
return 16;
// 8 bit modes
case D3DFMT_A8P8:
case D3DFMT_P8:
return 8;
}
return 0;
}
//-------------------------------------------------------------------
// Check whether specified display mode is supported on this adapter.
//-------------------------------------------------------------------
BOOL GRAPHICS::Check_Format(D3DFORMAT format, BOOL is_windowed, BOOL support_hal)
{
// verifies whether a hardware accelerated device type can be used on this adapter
if(FAILED(_d3d->CheckDeviceType(D3DADAPTER_DEFAULT, support_hal ? D3DDEVTYPE_HAL : D3DDEVTYPE_REF,
format, format, is_windowed)))
{
return FALSE;
}
return TRUE;
}
//-------------------------------------------------------------------
// Enables or disables a set of lighting parameters.
//-------------------------------------------------------------------
BOOL GRAPHICS::Enable_Light(long light_index, BOOL enable)
{
if(_d3d_device == NULL)
return FALSE;
// enables or disables a set of lighting parameters within a device
if(FAILED(_d3d_device->LightEnable(light_index, enable)))
return FALSE;
return TRUE;
}
//-------------------------------------------------------------------
// Enable or disable light.
//-------------------------------------------------------------------
BOOL GRAPHICS::Enable_Lighting(BOOL enable)
{
if(_d3d_device == NULL)
return FALSE;
if(FAILED(_d3d_device->SetRenderState(D3DRS_LIGHTING, enable)))
return FALSE;
return TRUE;
}
//-------------------------------------------------------------------
// Enable or disable z-buffer.
//-------------------------------------------------------------------
BOOL GRAPHICS::Enable_ZBuffer(BOOL enable)
{
if(_d3d_device == NULL || !_use_zbuffer)
return FALSE;
if(FAILED(_d3d_device->SetRenderState(D3DRS_ZENABLE, enable ? D3DZB_TRUE : D3DZB_FALSE)))
return FALSE;
return TRUE;
}
//-------------------------------------------------------------------
// Enable or disable alpha blending.
//-------------------------------------------------------------------
BOOL GRAPHICS::Enable_Alpha_Blending(BOOL enable, DWORD source, DWORD dest)
{
if(_d3d_device == NULL)
return FALSE;
// enable or disable alpha blending
if(FAILED(_d3d_device->SetRenderState(D3DRS_ALPHABLENDENABLE, enable)))
return FALSE;
// set blend type
if(enable)
{
_d3d_device->SetRenderState(D3DRS_SRCBLEND, source);
_d3d_device->SetRenderState(D3DRS_DESTBLEND, dest);
}
return TRUE;
}
//-------------------------------------------------------------------
// Enable or disable alpha testing.
//-------------------------------------------------------------------
BOOL GRAPHICS::Enable_Alpha_Testing(BOOL enable)
{
if(_d3d_device == NULL)
return FALSE;
if(FAILED(_d3d_device->SetRenderState(D3DRS_ALPHATESTENABLE, enable)))
return FALSE;
// set alpha testing type
if(enable)
{
_d3d_device->SetRenderState(D3DRS_ALPHAREF, 0x08);
_d3d_device->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);
}
return TRUE;
}
//-------------------------------------------------------------------
// Set ambient light color.
//-------------------------------------------------------------------
BOOL GRAPHICS::Set_Ambient_Light(unsigned char red, unsigned char green, unsigned char blue)
{
if(_d3d_device == NULL)
return FALSE;
_ambient_red = red;
_ambient_green = green;
_ambient_blue = blue;
D3DCOLOR color = D3DCOLOR_XRGB(_ambient_red, _ambient_green, _ambient_blue);
if(FAILED(_d3d_device->SetRenderState(D3DRS_AMBIENT, color)))
return FALSE;
return TRUE;
}
//-------------------------------------------------------------------
// Get ambient light color.
//-------------------------------------------------------------------
void GRAPHICS::Get_Ambient_Light(unsigned char* red, unsigned char* green, unsigned char* blue)
{
if(red != NULL) *red = _ambient_red;
if(green != NULL) *green = _ambient_green;
if(blue != NULL) *blue = _ambient_blue;
}
//-------------------------------------------------------------------
// Set perspective projection transform matrix.
//-------------------------------------------------------------------
BOOL GRAPHICS::Set_Perspective(float fov, float aspect, float near_z, float far_z)
{
D3DXMATRIX mat_proj;
if(_d3d_device == NULL)
return FALSE;
// builds a left-handed perspective projection matrix based on a field of view
D3DXMatrixPerspectiveFovLH(&mat_proj, fov, aspect, near_z, far_z);
// set projection matrix
if(FAILED(_d3d_device->SetTransform(D3DTS_PROJECTION, &mat_proj)))
return FALSE;
return TRUE;
}
//-------------------------------------------------------------------
// Inform D3D begin graphic render.
//-------------------------------------------------------------------
BOOL GRAPHICS::Begin_Scene()
{
if(_d3d_device == NULL)
return FALSE;
if(FAILED(_d3d_device->BeginScene()))
return FALSE;
return TRUE;
}
//-------------------------------------------------------------------
// Inform D3D end graphic render.
//-------------------------------------------------------------------
BOOL GRAPHICS::End_Scene()
{
// error checking
if(_d3d_device == NULL)
return FALSE;
// release all textures
for(short i = 0; i < 8; i++)
_d3d_device->SetTexture(i, NULL);
// end the scene
if(FAILED(_d3d_device->EndScene()))
return FALSE;
return TRUE;
}
//-------------------------------------------------------------------
// Prepares a device for drawing sprites.
//-------------------------------------------------------------------
BOOL GRAPHICS::Begin_Sprite()
{
if(_sprite == NULL)
return FALSE;
if(FAILED(_sprite->Begin(0)))
return FALSE;
return TRUE;
}
//-------------------------------------------------------------------
// End sprite render.
//-------------------------------------------------------------------
BOOL GRAPHICS::End_Sprite()
{
if(_sprite == NULL)
return FALSE;
// Forces all batched sprites to be submitted to the device.
// Restores the device state to how it was before ID3DXSprite::Begin was called.
if(FAILED(_sprite->End()))
return FALSE;
return TRUE;
}
//-------------------------------------------------------------------
// Presents the contents of the next buffer in the sequence of back
// buffers owned by the device.
//-------------------------------------------------------------------
BOOL GRAPHICS::Display()
{
if(_d3d_device == NULL)
return FALSE;
if(FAILED(_d3d_device->Present(NULL, NULL, NULL, NULL)))
return FALSE;
return TRUE;
}
//-------------------------------------------------------------------
// Clear screen, if using z-buffer, then clear z-buffer too.
//-------------------------------------------------------------------
BOOL GRAPHICS::Clear(long color, float zbuffer)
{
if(_d3d_device == NULL)
return FALSE;
// only clear screen if no zbuffer
if(! _use_zbuffer)
return Clear_Display(color);
// clear display and zbuffer
if(FAILED(_d3d_device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, color, zbuffer, 0)))
return FALSE;
return TRUE;
}
//-------------------------------------------------------------------
// Clear display buffer with specified color.
//-------------------------------------------------------------------
BOOL GRAPHICS::Clear_Display(long color)
{
if(_d3d_device == NULL)
return FALSE;
if(FAILED(_d3d_device->Clear(0, NULL, D3DCLEAR_TARGET, color, 1.0f, 0)))
return FALSE;
return TRUE;
}
//-------------------------------------------------------------------
// Clear z-buffer.
//-------------------------------------------------------------------
BOOL GRAPHICS::Clear_ZBuffer(float zbuffer)
{
if(_d3d_device == NULL || !_use_zbuffer)
return FALSE;
if(FAILED(_d3d_device->Clear(0, NULL, D3DCLEAR_ZBUFFER, 0, zbuffer, 0)))
return FALSE;
return TRUE;
}
//-------------------------------------------------------------------
// Get display mode width.
//-------------------------------------------------------------------
long GRAPHICS::Get_Width()
{
return _width;
}
//-------------------------------------------------------------------
// Get display mode height.
//-------------------------------------------------------------------
long GRAPHICS::Get_Height()
{
return _height;
}
//-------------------------------------------------------------------
// Get BPP.
//-------------------------------------------------------------------
char GRAPHICS::Get_Bpp()
{
return _bpp;
}
//-------------------------------------------------------------------
// Get flags which indicates whether support hardware acceleration.
//-------------------------------------------------------------------
BOOL GRAPHICS::Support_Hal()
{
return _support_hal;
}
//-------------------------------------------------------------------
// Get flags which indicates whether using z-buffer.
//-------------------------------------------------------------------
BOOL GRAPHICS::Use_ZBuffer()
{
return _use_zbuffer;
}
//-------------------------------------------------------------------
// Set view transform matrix.
//-------------------------------------------------------------------
BOOL GRAPHICS::Set_Camera(CAMERA* camera)
{
if(_d3d_device == NULL || camera == NULL)
return FALSE;
if(FAILED(_d3d_device->SetTransform(D3DTS_VIEW, camera->Get_Matrix())))
return FALSE;
return TRUE;
}
//-------------------------------------------------------------------
// Set world transform matrix.
//-------------------------------------------------------------------
BOOL GRAPHICS::Set_World_Position(WORLD_POSITION* world_pos)
{
if(world_pos == NULL || _d3d_device == NULL)
return FALSE;
if(FAILED(_d3d_device->SetTransform(D3DTS_WORLD, world_pos->Get_Matrix(this))))
return FALSE;
return TRUE;
}
//-------------------------------------------------------------------
// Set light for Direct3D device.
//-------------------------------------------------------------------
BOOL GRAPHICS::Set_Light(long light_index, LIGHT *light)
{
if(_d3d_device == NULL || light == NULL)
return FALSE;
if(FAILED(_d3d_device->SetLight(light_index, light->Get_Light())))
return FALSE;
return TRUE;
}
//-------------------------------------------------------------------
// Set material for Direct3D device.
//-------------------------------------------------------------------
BOOL GRAPHICS::Set_Material(MATERIAL *material)
{
if(_d3d_device == NULL)
return FALSE;
if(material)
{
if(FAILED(_d3d_device->SetMaterial(material->Get_Material())))
return FALSE;
}
return TRUE;
}
//-------------------------------------------------------------------
// Set texture for Direct3D device.
//-------------------------------------------------------------------
BOOL GRAPHICS::Set_Texture(short texture_sample, TEXTURE *texture)
{
// error checking
if(_d3d_device == NULL || texture_sample < 0 || texture_sample > 7)
return FALSE;
if(texture == NULL)
{
// clear the texture
if(FAILED(_d3d_device->SetTexture(texture_sample, NULL)))
return FALSE;
}
else
{
// set the texture
if(FAILED(_d3d_device->SetTexture(texture_sample, texture->Get_Texture_COM())))
return FALSE;
}
return TRUE;
}
使用GRAPHICS类,首先要调用GRAPHICS::Init,接着调用GRAPHICS::Set_Mode设置各种显示模式,Set_Mode最少只需要一个父窗口句柄,缺省情况下,显示模式被设置成不带Z缓冲的窗口进行输出。如果要使用全屏,必须将is_windowed参数设置为FALSE,并指定有效的width,height以及每像素的位数。如果将以上任何值设置成0,Set_Mode就会使用当前桌面设置,如果使用窗口模式并指定了不同的width和height,父窗口就会被重新调整大小,以适合这些width和height值。GRAPHICS::Set_Mode是一个比较“聪明”的函数,它会检测硬件是否支持硬件加速和Z缓冲,如果这两个特性都不支持,Set_Mode函数就会使用Direct3D模拟3D函数并停止使用Z缓冲以确保此模式能够被设置。
在渲染任何东西之前,必须调用GRAPHICS::Begin_Scene函数,在渲染完成之后,要调用GRAPHICS::End_Scene函数,随后再调用GRAPHICS::Display函数以显示图形。要在渲染之前清除屏幕,直接调用适当的清除函数即可。如果没有使用Z缓冲,就不要调用Clear函数,而要使用Clear_Display函数,因为Clear函数需要一个Z缓冲值。
要设置和启用光照,需要调用GRAPHICS::Enable_Lighting函数。Alpha混合能够带来奇妙的效果,而且还允许程序员指定精确的混合值(用于源混合和目标混合),Alpha测试能够帮助程序员绘制那些麻烦的透明纹理。
以下给出测试代码:
点击下载源码和工程
/*****************************************************************************
PURPOSE:
Test for class GRAPHICS.
*****************************************************************************/
#include "Core_Global.h"
#pragma warning(disable : 4996)
//===========================================================================
// Defines class APP which public inherits from class APPLICATION.
//===========================================================================
class APP : public APPLICATION
{
private:
GRAPHICS _graphics;
TEXTURE _texture;
IDirect3DVertexBuffer9* _vertex_buffer;
// The 2D vertex format and descriptor
typedef struct
{
float x, y, z; // 2D coordinates
float rhw; // rhw
float u, v; // texture coordinates
} VERTEX;
#define VERTEX_FVF (D3DFVF_XYZRHW | D3DFVF_TEX1)
public:
APP();
BOOL Init();
BOOL Shutdown();
BOOL Frame();
};
//-----------------------------------------------------------------------------
// Consturctor, initialize member data.
//-----------------------------------------------------------------------------
APP::APP()
{
_vertex_buffer = NULL;
}
//-----------------------------------------------------------------------------
// Initialize graphics, set display mode, set vertex buffer, load texture file.
//-----------------------------------------------------------------------------
BOOL APP::Init()
{
BYTE* vertex_ptr;
// initialize vertex data
VERTEX verts[] = {
{ 50.0f, 50.0f, 1.0f, 1.0f, 0.0f, 0.0f },
{ 350.0f, 50.0f, 1.0f, 1.0f, 1.0f, 0.0f },
{ 50.0f, 350.0f, 1.0f, 1.0f, 0.0f, 1.0f },
{ 350.0f, 350.0f, 1.0f, 1.0f, 1.0f, 1.0f }
};
// initialize graphics
if (! _graphics.Init())
return FALSE;
// set display mode for graphics
if(! _graphics.Set_Mode(Get_Hwnd(), TRUE, FALSE, 400, 400, 16))
return FALSE;
// create the vertex buffer and set data
_graphics.Get_Device_COM()->CreateVertexBuffer(sizeof(VERTEX) * 4, 0, VERTEX_FVF,
D3DPOOL_DEFAULT, &_vertex_buffer, NULL);
// locks a range of vertex data and obtains a pointer to the vertex buffer memory
_vertex_buffer->Lock(0, 0, (void**)&vertex_ptr, 0);
memcpy(vertex_ptr, verts, sizeof(verts));
// unlocks vertex data
_vertex_buffer->Unlock();
// load texture file
if(! _texture.Load(&_graphics, "Texture.jpg"))
return FALSE;
return TRUE;
}
//-----------------------------------------------------------------------------
// Release all d3d resource.
//-----------------------------------------------------------------------------
BOOL APP::Shutdown()
{
Release_COM(_vertex_buffer);
return TRUE;
}
//-----------------------------------------------------------------------------
// Render a frame.
//-----------------------------------------------------------------------------
BOOL APP::Frame()
{
// clear display with specified color
_graphics.Clear_Display(D3DCOLOR_RGBA(0, 0, 0, 255));
// begin scene
if(_graphics.Begin_Scene())
{
// set the vertex stream, shader, and texture.
// binds a vertex buffer to a device data stream
_graphics.Get_Device_COM()->SetStreamSource(0, _vertex_buffer, 0, sizeof(VERTEX));
// set the current vertex stream declation
_graphics.Get_Device_COM()->SetFVF(VERTEX_FVF);
// assigns a texture to a stage for a device
_graphics.Set_Texture(0, &_texture);
// renders a sequence of noindexed, geometric primitives of the specified type from the current set
// of data input stream.
_graphics.Get_Device_COM()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
// release texture
_graphics.Set_Texture(0, NULL);
// end the scene
_graphics.End_Scene();
}
// display video buffer
_graphics.Display();
return TRUE;
}
int PASCAL WinMain(HINSTANCE inst, HINSTANCE, LPSTR cmd_line, int cmd_show)
{
APP app;
return app.Run();
}
运行截图: