首先,我们必须了解DirectX的定义。
DirectX,(Direct eXtension,简称DX)是由微软公司创建的多媒体编程接口。由C++编程语言实现,遵循COM。被广泛使用于Microsoft Windows、Microsoft Xbox和Microsoft Xbox 360电子游戏开发,并且只能支持这些平台。最新版本为DirectX 11,创建在最新的Windows 7上。
Microsoft DirectX 是这样一组技术:它们旨在使基于Windows 的计算机成为运行和显示具有丰富多媒体元素(例如全色图形、视频、3D 动画和丰富音频)的应用程序的理想平台。
DirectX 包括安全和性能更新程序,以及许多涵盖所有技术的新功能。应用程序可以通过使用DirectX API 来访问这些新功能。
Direct X主要用于游戏开发,但其中部分用于开发其他类型的软件,包括游戏虚拟角色、网络软件、与游戏无关的图形软件。
Direct X通过和底层硬件打交道,从而获取软件的最大性能。
要进行游戏的开发,我们必须拥有一套最新的DirectX SDK(软件开发包)。我们可以从微软的官方下载站进行下载然后安装,这里贴出地址,http://msdn.microsoft.com/zh-cn/directx/aa937788.aspx。当然我们还要拥有开发环境,我们选择Microsoft公司的Visual Studio 2010。
C:\Program Files (x86)\Microsoft DirectX SDK (February 2010)\Include
C:\Program Files (x86)\Microsoft DirectX SDK (February 2010)\Lib\x86
dxerr.lib
dxguid.lib
d3dx9d.lib
d3dx10d.lib
d3d9.lib
winmm.lib
comctl32.lib
游戏引擎是一系列高级代码,我们可以以它为基础开发自己的游戏。现代的游戏引擎已经对使用他的人隐藏了底层实现的细节和规范。例如,可以在OpenGL和Direct3D的基础上开发渲染引擎,这样,引擎用户就不需要知道使用的是哪一个渲染引擎,尽管也用到了一些底层的东西。
游戏引擎包括:渲染引擎,物理引擎,声音引擎等。游戏引擎本身只是一个由更小的引擎组成的集合。游戏引擎或它涵盖的内容并没有一个精确的定义。
对于视频游戏而言,它的游戏引擎至少要包含渲染引擎和输入引擎,这是必须的,否则,就不能称其为交互式游戏。
游戏程序员和游戏引擎程序员完成的是两种不同的工作。游戏程序员只与开发游戏的游戏引擎打交道,而游戏引擎程序员要开发出其他人用于开发游戏的引擎。
游戏引擎中的几个关键系统有:游戏渲染系统,输入系统,声音系统,物理系统,动画系统,人工智能(AI)系统等。
DirectX的API主要由DirectGraphics,DirectInput,DirectPlay,DirectMusic,DirectSound组成。每个API之间相互独立,负责完成DirectX内核中不同的功能。DirectX中每个API都可以通过硬件加速,这意味着这些API可以直接和运行软件的底层硬件对话。下面是各种API函数的概要解释。
DirectGraphics:
DirectGraphics为负责向屏幕渲染二维图形和三维图形的DirectX API,也就是众所周知的Direct3D。
DirectInput:
DirectInput是可以直接使用所有与计算机关联的输入设备的DirectX API。这些设备包括键盘,鼠标和游戏控制器设备。
DirectPlay:
DirectPlay是控制Direct中网络功能的Direct API。DirectPlay可以让应用程序对机器进行网络功能设置,从而可以通过和其他网络玩家交流。
DirectMusic:
DirectMusic是负责普通声音处理的DirectX API。
DirectSound:
DirectSound是负责高级声音处理的DirectX API。
在Windows中使用Direct3D创建Win32窗口非常简单。要创建一个Win32窗口就必须拥有一个WinMain()函数(这不是废话是什么)。我们可以在MSDN中查到WinMain()的标准句法
//空的WinMain()函数
#include
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstanace,
PSTR szCmdLine,
int iCmdShow)
{
return 0;
}
/*
WinMain函数包括4个参数:
1.程序实例的句柄(类似追踪定位的指针)
2.程序先前的实例
3.传递给程序的命令行参数指针
4.窗口的显示方式
*/
显示结果:一闪而过(正常现象)
//WinMain()函数内部创建窗口
#include
//消息过程函数
LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){
switch (msg)
{
//销毁信息
case WM_DESTROY:
//让程序知道要退出
PostQuitMessage(0);
return 0;
break;
}
//为所有信息提供默认处理机制
return DefWindowProc(hWnd, msg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstanace,
PSTR szCmdLine,int iCmdShow)
{
//创建类型为WEDCLASSEX的窗口类对象
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0, 0, hInstance, NULL,
NULL, NULL, NULL, "AppClass", NULL };
//注册窗口类
RegisterClassEx(&wc);
//创建窗口
HWND hWnd = CreateWindow("AppClass", "Window Title", WS_OVERLAPPEDWINDOW,
100, 100, 640, 480, NULL, NULL, hInstance, NULL);
//初始化D3D对象
if(InitializeD3D(hWnd, false))
{
//在屏幕上显示该窗口
ShowWindow(hWnd, SW_SHOWDEFAULT);
//更新窗口
UpdateWindow(hWnd);
//声明消息
MSG msg;
//清空消息缓存
ZeroMemory(&msg, sizeof(msg));
//消息循环直到退出
while (msg.message != WM_QUIT)
{
//从消息队列中获取下一条消息
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
//获取消息,并将其转换成字符消息
TranslateMessage(&msg);
//将转换的消息发送给消息过程函数
DispatchMessage(&msg);
}
else
{
//渲染
RenderScene();
}
}
}
//释放D3D对象
Shutdown();
//取消对窗口类的注册
UnregisterClass(WINDOW_CLASS, wc.hInstance);
return 0;
}
//初始化Direct3D
//InitializeD3D()函数的参数:1.窗口句柄 2.标识窗口是否全屏的标识符
bool InitializeD3D(HWND hWnd, bool fullscreen)
{
//声明显卡信息变量
D3DDISPLAYMODE displayMode;
//Direct3DCreate9()函数:创建一个Direct3D接口对象,并返回该对象
g_D3D = Direct3DCreate9(D3D_SDK_VERSION);
if (g_D3D == NULL)return false;
//GetAdapterDisplayMode()函数:返回当前显卡信息
if (FAILED(g_D3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &displayMode)))
return false;
//D3DPRESENT_PARAMETERS:用于定义Direct3D窗口的显示信息
D3DPRESENT_PARAMETERS d3dpp;
//清空显示信息
ZeroMemory(&d3dpp, sizeof(d3dpp));
//是否全屏
if (fullscreen)
{
//全屏非窗口
d3dpp.Windowed = FALSE;
//窗口宽度
d3dpp.BackBufferWidth = 640;
//窗口高度
d3dpp.BackBufferHeight = 480;
}
else
//窗口非全屏
d3dpp.Windowed = TRUE;
//处理交换结果
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
//管理缓存深度or模板缓存
d3dpp.BackBufferFormat = displayMode.Format;
//CreateDevice()函数:1.正在使用的显卡 2.设备类型 3.当前窗口 4.顶点运算类型 5.指定到一个 D3DPRESENT_PARAMETERS的结构体 6.返回设备的指针
if (FAILED(g_D3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp,
&g_D3DDevice)))return false;
return true;
}
//在屏幕上绘制一个空白屏
void RenderScene()
{
//清空后台缓存
g_D3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
//开始渲染
g_D3DDevice->BeginScene();
//结束渲染
g_D3DDevice->EndScene();
//显示渲染结果
g_D3DDevice->Present(NULL, NULL, NULL, NULL);
}
//释放所有Direct3D对象
void Shutdown()
{
//释放Direct3D设备对象
if (g_D3DDevice != NULL)g_D3DDevice->Release();
//释放Direct3D对象
if (g_D3D != NULL)g_D3D->Release();
//分别将两个对象指向空
g_D3DDevice = NULL;
g_D3D = NULL;
}
//完整代码如下:
#include
#include
#pragma comment (lib,"d3d9.lib")
#pragma comment (lib,"d3dx9.lib")
#define WINDOW_CLASS "UGPDX"
#define WINDOW_NAME "Blank D3D Window"
bool InitializeD3D(HWND hWnd, bool fullscreen);
void RenderScene();
void Shutdown();
LPDIRECT3D9 g_D3D = NULL;
LPDIRECT3DDEVICE9 g_D3DDevice = NULL;
LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){
switch (msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
break;
case WM_KEYUP:
if (wParam == VK_ESCAPE)
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstanace,
PSTR szCmdLine, int iCmdShow)
{
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0, 0, hInstance, NULL,
NULL, NULL, NULL, WINDOW_CLASS, NULL };
RegisterClassEx(&wc);
HWND hWnd = CreateWindow(WINDOW_CLASS, WINDOW_NAME, WS_OVERLAPPEDWINDOW,
100, 100, 640, 480, NULL, NULL, hInstance, NULL);
if (InitializeD3D(hWnd, false)){
ShowWindow(hWnd, SW_SHOWDEFAULT);
UpdateWindow(hWnd);
MSG msg;
ZeroMemory(&msg, sizeof(msg));
while (msg.message != WM_QUIT)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
RenderScene();
}
}
}
Shutdown();
UnregisterClass(WINDOW_CLASS, wc.hInstance);
return 0;
}
bool InitializeD3D(HWND hWnd, bool fullscreen)
{
D3DDISPLAYMODE displayMode;
g_D3D = Direct3DCreate9(D3D_SDK_VERSION);
if (g_D3D == NULL)return false;
if (FAILED(g_D3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &displayMode)))
return false;
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
if (fullscreen)
{
d3dpp.Windowed = FALSE;
d3dpp.BackBufferWidth = 640;
d3dpp.BackBufferHeight = 480;
}
else
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = displayMode.Format;
if (FAILED(g_D3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp,
&g_D3DDevice)))return false;
return true;
}
void RenderScene()
{
g_D3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
g_D3DDevice->BeginScene();
g_D3DDevice->EndScene();
g_D3DDevice->Present(NULL, NULL, NULL, NULL);
}
void Shutdown()
{
if (g_D3DDevice != NULL)g_D3DDevice->Release();
if (g_D3D != NULL)g_D3D->Release();
g_D3DDevice = NULL;
g_D3D = NULL;
}
运行结果: