Game Programming with DirectX -- 01[初识Direct3D]
第一卷 朦胧的3D世界
第一集 初识Direct3D
简介
我们通过2个例子来简单的认识3D
1.1 接口和数据结构
我们首先来看看我们以后用的比较多的接口,
a. IDirect3D9
b. IDirect3DDevice9
c. IDirect3DVertexBuffer9
d. IDirect3DIndexBuffer9
e. IDirect3DSurface9
f. IDirect3DTexture9
g. ID3DXMesh
再看看我们以后用的比较多的数据结构,
a. D3DDISPLAYMODE
b. D3DPRESENT_PARAMETERS
c. D3DXMATRIX
d. D3DLIGHT9
e. D3DMATERIAL9
我们现在不解释它们的用途, 在接下来的很多地方会用到的, 之后大家就会自己掌握了.
1.2 第一个例子
1.2.1万事总有开头的地方, 这里我们就简单的实现一个.
假设我现在是个画家, 那么画家的画是怎么出来的呢?
a. 需要一个工作的地方, 也就是工作室.
Direct3D也需要工作的地方, 这个地方称为 -- IDirect3D9, 如同画家的工作室.
b. 我是个全能的画家, 能画油画, 水墨画..., 每种风格的画派都有它独特的工作的办公桌在工作室里;
IDirect3D9这个工作室也可能是多才多艺的, 也就是说它可能也有很多不同的办公桌 -- IDirect3DDevice9,
IDirect3DDevice9的多少其实可等同与你的主板上有多少块能被使用的显卡, 一般有只有一块;
所以一般的工作室(IDirect3D9)只有一张特定的办公桌(IDirect3DDevice9), 这时的IDirect3DDevice9可称谓默认的adapter.
c. 画不是画在办公桌上的, 而是办公桌上的画纸上的, 同样有很多相同的画纸, 也有很多不同的画纸.
IDirect3DDevice9办公桌上的画纸是 -- IDirect3DSurface9; 现在的IDirect3DDevice9一般都会默认为你准备1张画纸
(IDirect3DSurface9), 全屏模式下是最少2张.
1.2.2 好的, 现在我这个天才画家要开始画画了,
首先得创建一个Windows SDK 程序, 因为所有的Windows游戏是通过Windows的窗口消息循环来工作的.
Visual Studio 200X -->File --> Project... --> Win32 Project, 选默认的生成.
我比较喜欢自己的SDK风格, 所以对默认的生成进行了少许的改动, 以后的例子都使用同样的框架.
暂定为game0, 我们来看看game0的主要代码(下载game0 project),
-------------------------------------------------------------------------
#include "stdafx.h"
#include "game0.h"
// Global Variables:
LPDIRECT3D9 g_pD3D = NULL;
LPDIRECT3DDEVICE9 g_pD3DDevice = NULL;
LPCTSTR szClass = _T("Game0");
LPCTSTR szTitle = _T("Demo0");
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE);
HRESULT Init3D(HWND);
INT MsgLoop();
VOID Render();
VOID Term3D();
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
// WinMain
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
int nRet = 0;
MyRegisterClass(hInstance);
if (InitInstance(hInstance))
{
nRet = MsgLoop();
}
Term3D();
UnregisterClass(szClass, hInstance);
return nRet;
}
// MyRegisterClass
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground= (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName= szClass;
wcex.hIconSm = wcex.hIcon;
return RegisterClassEx(&wcex);
}
// InitInstance
BOOL InitInstance(HINSTANCE hInstance)
{
HWND hWnd = CreateWindow(szClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
NULL, NULL, hInstance, NULL);
if (hWnd == NULL)
{
return FALSE;
}
if (FAILED(Init3D(hWnd)))
{
DestroyWindow(hWnd);
return FALSE;
}
ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
return TRUE;