首先申明这个程序是根据翁云兵 翻译的<<3D游戏程序设计入门(DirectX® 9.0)>>修改的;
下面那个程序什么都没有完成,就是创建一个窗口.但是麻雀虽小,里面的所有的D3D基本功能都包含了.
不怕笑话,这个程序我研究了2天.
把这个坎过去了就好办了,接下来要学的东西就应该轻松点了.起码理解起来没什么问题了.
利用D3D做程序无非是两步:
1)创建设备
2)利用创建的设备来完成要做的任务,然后释放设备
还有下面的程序主要是研究这样创建设备的,至于利用这样利用设备是下次文章的主题了;
-----------------------------------------------------------------------------------------------------------------------test.cpp
#include "d3dUtility.h"
//全局变量,定义设备
IDirect3DDevice9* Device = 0;
//在这个程序中,我们不需要使用任何资源或触发任何事件,所以这两个函数都为空
bool Setup()
{
return true;
}
void Cleanup()
{
}
//HRESULT IDirect3DDevice9::Clear(DWORD Count,const D3DRECT* pRects,DWORD Flags,D3DCOLOR Color,float Z,DWORD Stencil);
//IDirect3DDevice9::Clear函数的声名
/*下面是对CLEAR的各个参数的说明
Count——pRects组中的矩形的个数;
pRects——将要清除的屏幕矩形的数组,这使我们可以清除屏幕的某一部分;
Flags——指定在哪些表面上执行清除表面的操作;
D3DCLEAR_TARGET——目的表面,通常为后备表面;
D3DCLEAR_ZBUFFER——深度缓冲;
D3DCLEAR_STENCIL——模版缓冲;
Color——使用什么颜色填充清除的表面;
Z——设置深度缓冲的值;
Stencil——设置模版缓冲的值*/
//屏幕被填充后,要调用IDirecte3DDevice9::Present方法进行后备表面的交换
bool Display(float timeDelta)
{
if( Device )
{
Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
Device->Present(0, 0, 0, 0);// present backbuffer
}
return true;
}
LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch( msg )
{
case WM_DESTROY:
::PostQuitMessage(0);
break;
case WM_KEYDOWN:
if( wParam == VK_ESCAPE )
::DestroyWindow(hwnd);
break;
}
return ::DefWindowProc(hwnd, msg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hinstance,HINSTANCE prevInstance,PSTR cmdLine,int showCmd)
{
//初始化主显示窗口和Direct3D
if(!d3d::InitD3D(hinstance, 800, 600, true, D3DDEVTYPE_HAL, &Device))
{
::MessageBox(0, "InitD3D() - FAILED", 0, 0);
return 0;
}
//调用Setup进行程序的准备工作
if(!Setup())
{
::MessageBox(0, "Setup() - FAILED", 0, 0);
return 0;
}
//使用Display函数作为参数进入消息循环
d3d::EnterMsgLoop( Display );
//清除应用程序最后释放IDirecte3DDevice9对象
Cleanup();
Device->Release();
return 0;
}
----------------------------------------------------------------------------------------------------------------------
//d3dUtility.h
#ifndef __d3dUtilityH__
#define __d3dUtilityH__
#include <d3dx9.h>
#include <string>
namespace d3d
{
bool InitD3D(
HINSTANCE hInstance, // [in] Application instance.
int width, int height, // [in] Backbuffer dimensions.
bool windowed, // [in] Windowed (true)or full screen (false).
D3DDEVTYPE deviceType, // [in] HAL or REF
IDirect3DDevice9** device);// [out]The created device.
int EnterMsgLoop(
bool (*ptr_display)(float timeDelta));
LRESULT CALLBACK WndProc(
HWND hwnd,
UINT msg,
WPARAM wParam,
LPARAM lParam);
template<class T> void Release(T t)
{
if( t )
{
t->Release();
t = 0;
}
}
template<class T> void Delete(T t)
{
if( t )
{
delete t;
t = 0;
}
}
}
#endif // __d3dUtilityH__
#include "d3dUtility.h"
//InitD3D主要功能是注册和创建主窗口,检查设备的兼容性,决定是用硬件支持方式还是软件支持方式
//
bool d3d::InitD3D(
HINSTANCE hInstance,
int width, int height,
bool windowed,
D3DDEVTYPE deviceType,
IDirect3DDevice9** device)
{
//
// Create the main application window.
//
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)d3d::WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(0, IDI_APPLICATION);
wc.hCursor = LoadCursor(0, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = 0;
wc.lpszClassName = "Direct3D9App";
if( !RegisterClass(&wc) )
{
::MessageBox(0, "RegisterClass() - FAILED", 0, 0);
return false;
}
HWND hwnd = 0;
hwnd = ::CreateWindow("Direct3D9App", "Direct3D9App",
WS_EX_TOPMOST,
0, 0, width, height,
0 /*parent hwnd*/,
0 /* menu */,
hInstance,
0 /*extra*/);
if( !hwnd )
{
::MessageBox(0, "CreateWindow() - FAILED", 0, 0);
return false;
}
::ShowWindow(hwnd, SW_SHOW);
::UpdateWindow(hwnd);
//
// Init D3D:
//
HRESULT hr = 0;
// Step 1: Create the IDirect3D9 object.
//1. 获得一个IDirect3D9接口指针。
//这个接口用于获得物理设备的信息和创建一个IDirect3DDevice9接口,
//它是一个代表我们显示3D图形的物理设备的C++对象。
IDirect3D9* d3d9 = 0;
d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
if( !d3d9 )
{
::MessageBox(0, "Direct3DCreate9() - FAILED", 0, 0);
return false;
}
// Step 2: Check for hardware vp.
//检查硬件是否支持,要是不支持那么使用软件方式,并且得到硬件信息
//deviceType 来记录DeviceType的类型
D3DCAPS9 caps;
d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, deviceType, &caps);
int vp = 0;
if( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )
vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
else
vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
// Step 3: Fill out the D3DPRESENT_PARAMETERS structure.
//填充D3DPRESENT_PARAMETERS结构
D3DPRESENT_PARAMETERS d3dpp;
d3dpp.BackBufferWidth = width;
d3dpp.BackBufferHeight = height;
d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
d3dpp.BackBufferCount = 1;
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
d3dpp.MultiSampleQuality = 0;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = hwnd;
d3dpp.Windowed = windowed;
d3dpp.EnableAutoDepthStencil = true;
d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
d3dpp.Flags = 0;
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
// Step 4: Create the device.
//创建设备
hr = d3d9->CreateDevice(
D3DADAPTER_DEFAULT, // primary adapter主显卡
deviceType, // device type
hwnd, // window associated with device邦定的窗口
vp, // vertex processing顶点处理方式
&d3dpp, // present parameters
device); // return created device返回的设备
if( FAILED(hr) )
{
// try again using a 16-bit depth buffer
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
hr = d3d9->CreateDevice(
D3DADAPTER_DEFAULT,
deviceType,
hwnd,
vp,
&d3dpp,
device);
if( FAILED(hr) )
{
d3d9->Release(); // done with d3d9 object
::MessageBox(0, "CreateDevice() - FAILED", 0, 0);
return false;
}
}
d3d9->Release(); // done with d3d9 object
return true;
}
int d3d::EnterMsgLoop( bool (*ptr_display)(float timeDelta) )
{
MSG msg;
::ZeroMemory(&msg, sizeof(MSG));
static float lastTime = (float)timeGetTime();
while(msg.message != WM_QUIT)
{
if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
else
{
float currTime = (float)timeGetTime();
float timeDelta = (currTime - lastTime)*0.001f;
ptr_display(timeDelta);
lastTime = currTime;
}
}
return msg.wParam;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~