DirectX并不是一个单纯的图形API,它是由微软公司开发的用途广泛的API,它包含有Direct Graphics(Direct 3D+Direct Draw)、Direct Input、Direct Play、Direct Sound、Direct Show、Direct Setup、Direct Media Objects等多个组件,它提供了一整套的多媒体接口方案。
DirectX是一系列的COM对象或接口,Direct 3D只是DirectX的一个部分,Direct3D是一个相当高级的类,它封装了你运行2D和3D图形所需要的全部硬件啊,软件啊,以及其他。
COM
COM对象实际就是C++类,或者说是供你调用以实现一定目标的类内的函数。每个类都可以单独而不是相互间配合才能进行工作,而且可以作为一个单独组件卸载或加载而不影响程序的运行。独立性是COM的最大特性之一。
COM的特点,让DirectX 独立于语言而向下兼容。
一般将COM对象作为接口,将其视为C++类使用,我们所必须知道的仅是通过某个特定函数或另一个COM接口来获取指向某一个COM接口的指针。通常使用CreateX()函数。获得指针后就可以该接口的功能(接口内的方法)。
网络教程:
DirectXTutorial.com
书籍:
《DIRECTX 9.0 3D 游戏开发编程基础》 Frank D.Luna 清华大学出版社
《Windows程序设计第五版》
DirectX是一系列的COM对象或接口,Direct 3D只是DirectX的一个部分,Direct3D是一个相当高级的类,它封装了你运行2D和3D图形所需要的全部硬件啊,软件啊,以及其他。
COM
COM对象实际就是C++类,或者说是供你调用以实现一定目标的类内的函数。每个类都可以单独而不是相互间配合才能进行工作,而且可以作为一个单独组件卸载或加载而不影响程序的运行。独立性是COM的最大特性之一。
COM的特点,让DirectX 独立于语言而向下兼容。
一般将COM对象作为接口,将其视为C++类使用,我们所必须知道的仅是通过某个特定函数或另一个COM接口来获取指向某一个COM接口的指针。通常使用CreateX()函数。获得指针后就可以该接口的功能(接口内的方法)。
注意到创建COM接口不可使用C++的关键字new,而是特定的函数,同时使用完一个接口,应该地调用接口对应的Release方法而不是delete。
这是因为每一个对象都有其的应用计数(Reference Counter),当创建对象时,为该计数初始为1,当使用该对象时进行AddRef(),递增计数,每次试图删除进行Release(),只有当引用计数为0,表明该对象正式删除,进行delete操作。
这样保证了当我们进行一次Create操作时,我们获得的是该对象指针,至于该指针是在哪里new出来的我们不在需要关注,而只需要Release,就能使该对象准确的时机被delete:
LPDIRECT3D9 d3d;
d3d = Direct3DCreate9(D3D_SDK_VERSION); // create the Direct3D interface
d3d->Release(); // close and release Direct3D
在D3D学习的过程我们需要的NEED:
- Visual Studio 2010 以及以上版本
- The DirectX SDK June 2010
- C++基础知识
- 开发游戏的强烈热情
WIN32基础
游戏基本流程
1 Initialize the program:初始化程序如创建窗口,初始化Direct3D
2 Start the game:启动游戏
3 Get input from the player:获取输入,是游戏与玩家的交互部分
4 Run the game logic, such as physics and AI:运行游戏物理引擎、逻辑AI等
5 Render graphics:渲染图形
6 Loop:进入游戏循环
7 Cleanup:资源的释放
游戏基本流程
1 Initialize the program:初始化程序如创建窗口,初始化Direct3D
2 Start the game:启动游戏
3 Get input from the player:获取输入,是游戏与玩家的交互部分
4 Run the game logic, such as physics and AI:运行游戏物理引擎、逻辑AI等
5 Render graphics:渲染图形
6 Loop:进入游戏循环
7 Cleanup:资源的释放
WIN32窗口程序
1 注册窗口类 RegisterClassEx
2 创建窗口 CreateWindowEx
3 显示窗口 ShowWindow
4 消息循环 Loop GetMessage
以下为完整的WIN32窗口程序代码
1 注册窗口类 RegisterClassEx
2 创建窗口 CreateWindowEx
3 显示窗口 ShowWindow
4 消息循环 Loop GetMessage
以下为完整的WIN32窗口程序代码
// include the basic windows header file
#include <windows.h>
// the WindowProc function prototype
LRESULT CALLBACK WindowProc(HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam);
// the entry point for any Windows program
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// the handle for the window, filled by a function
HWND hWnd;
// this struct holds information for the window class
WNDCLASSEX wc;
// clear out the window class for use
ZeroMemory(&wc, sizeof(WNDCLASSEX));
// fill in the struct with the needed information
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
wc.lpszClassName = L"WindowClass";
// register the window class
RegisterClassEx(&wc);
// create the window and use the result as the handle
hWnd = CreateWindowEx(NULL,
L"WindowClass", // name of the window class
L"First Window", // title of the window
WS_OVERLAPPEDWINDOW, // window style
300, // x-position of the window
300, // y-position of the window
500, // width of the window
400, // height of the window
NULL, // we have no parent window, NULL
NULL, // we aren't using menus, NULL
hInstance, // application handle
NULL); // used with multiple windows, NULL
// display the window on the screen
ShowWindow(hWnd, nCmdShow);
// enter the main loop:
// this struct holds Windows event messages
MSG msg;
// wait for the next message in the queue, store the result in 'msg'
while(GetMessage(&msg, NULL, 0, 0))
{
// translate keystroke messages into the right format
TranslateMessage(&msg);
// send the message to the WindowProc function
DispatchMessage(&msg);
}
// return this part of the WM_QUIT message to Windows
return msg.wParam;
}
// this is the main message handler for the program
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
// sort through and find what code to run for the message given
switch(message)
{
// this message is read when the window is closed
case WM_DESTROY:
{
// close the application entirely
PostQuitMessage(0);
return 0;
} break;
}
// Handle any messages the switch statement didn't
return DefWindowProc (hWnd, message, wParam, lParam);
}
游戏循环消息处理函数PeekMessage与GetMessage的区别之处:它不在等待消息,相当于对窗口消息队列消息进行检查而已,所以我们必须另外处理循环的退出情况。
while(TRUE)
{
// Check to see if any messages are waiting in the queue
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
// translate keystroke messages into the right format
TranslateMessage(&msg);
// send the message to the WindowProc function
DispatchMessage(&msg);
}
// If the message is WM_QUIT, exit the while loop
if(msg.message == WM_QUIT)
break;
// Run game code here
// ...
// ...
}
Direct3D程序
- 创建全局变量与函数原型
- 写初始化Direct3D函数,创建Direct3D Device
- 写渲染函数
- 关闭与释放Direct3D资源的函数
1 创建全局变量与函数原型
#include <windows.h>
#include <d3d9.h>
// include the Direct3D Library file
#pragma comment (lib, "d3d9.lib")
// global declarations
LPDIRECT3D9 d3d; // the pointer to our Direct3D interface
LPDIRECT3DDEVICE9 d3ddev; // the pointer to the device class
// function prototypes
void initD3D(HWND hWnd); // sets up and initializes Direct3D
void render_frame(void); // renders a single frame
void cleanD3D(void); // closes Direct3D and releases memory
// the WindowProc function prototype
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
2 写初始化Direct3D函数,创建Direct3D Device
初始化Direct3D的步骤:
- 获取IDirect3D9指针(Direct3DCreate9)
- 检查设备性能(D3DCAPS9 -Device Capabilities)
- 填充D3DPRESENT_PARAMETERS结构,该结构用于指定创建IDirect3DDevice9对象的特性
- 创建IDirect3DDevice9对象,其代表了我们显示图像的物理设备
// this function initializes and prepares Direct3D for use
void initD3D(HWND hWnd)
{
d3d = Direct3DCreate9(D3D_SDK_VERSION); // create the Direct3D interface
D3DPRESENT_PARAMETERS d3dpp; // create a struct to hold various device information
ZeroMemory(&d3dpp, sizeof(d3dpp)); // clear out the struct for use
d3dpp.Windowed = TRUE; // program windowed, not fullscreen
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; // discard old frames
d3dpp.hDeviceWindow = hWnd; // set the window to be used by Direct3D
// create a device class using this information and information from the d3dpp stuct
d3d->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp,
&d3ddev);
}
3 写渲染函数
// this is the function used to render a single frame
void render_frame(void)
{
// clear the window to a deep blue
d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 40, 100), 1.0f, 0);
d3ddev->BeginScene(); // begins the 3D scene
// do 3D rendering on the back buffer here
d3ddev->EndScene(); // ends the 3D scene
d3ddev->Present(NULL, NULL, NULL, NULL); // displays the created frame
}
4 关闭与释放Direct3D资源的函数
// this is the function that cleans up Direct3D and COM
void cleanD3D(void)
{
d3ddev->Release(); // close and release the 3D device
d3d->Release(); // close and release Direct3D
}
REL
网络教程:
DirectXTutorial.com
书籍:
《DIRECTX 9.0 3D 游戏开发编程基础》 Frank D.Luna 清华大学出版社
《Windows程序设计第五版》