玩了2天NBA live08,最后一场和网友打了4个加时,还是输了。吃完饭时在想,我玩NBA到底收获了什么,感觉虚度了2天光阴啊~ 好好学习吧!我如是想到。
今天看书写了第一个D3D的例子,写篇博客以示纪念,一个旋转的立方体,没什么技术含量,无非是调用一些MS的API,可是内部怎么执行的我还是不知道,打算这学期看完LaMothe的<<3D游戏编程大师技巧>>搞清楚相关数学原理,任重而道远啊!
代码清单:
- //
- //
- // File: cube.cpp
- // by tianzhihen
- // 2008.10.12
- // MSVC++ 8.0
- //
- #include "d3dUtility.h"
- //
- // 全局变量
- //
- IDirect3DDevice9* Device = 0;
- const int Width = 640;
- const int Height = 480;
- IDirect3DVertexBuffer9* VB = 0;
- IDirect3DIndexBuffer9* IB = 0;
- //
- // 类和结构体
- //
- struct Vertex
- {
- Vertex(){}
- Vertex(float x,float y,float z)
- {
- _x = x; _y = y; _z = z;
- }
- float _x,_y,_z;
- static const DWORD FVF;
- };
- const DWORD Vertex::FVF = D3DFVF_XYZ;
- //
- // 框架函数
- //
- bool Setup()
- {
- //
- // 创建顶点/索引缓存
- //
- Device->CreateVertexBuffer(
- 8*sizeof(Vertex),
- D3DUSAGE_WRITEONLY, // 只写
- Vertex::FVF,
- D3DPOOL_MANAGED,
- &VB,
- 0);
- Device->CreateIndexBuffer(
- 36*sizeof(WORD),
- D3DUSAGE_WRITEONLY,
- D3DFMT_INDEX16,
- D3DPOOL_MANAGED,
- &IB,
- 0);
- //
- // 用立方体数据填充缓存
- //
- Vertex* vertices;
- VB->Lock(0,0,(void**)&vertices,0);
- vertices[0] = Vertex(-1.0f, -1.0f, -1.0f);
- vertices[1] = Vertex(-1.0f, 1.0f, -1.0f);
- vertices[2] = Vertex( 1.0f, 1.0f, -1.0f);
- vertices[3] = Vertex( 1.0f, -1.0f, -1.0f);
- vertices[4] = Vertex(-1.0f, -1.0f, 1.0f);
- vertices[5] = Vertex(-1.0f, 1.0f, 1.0f);
- vertices[6] = Vertex( 1.0f, 1.0f, 1.0f);
- vertices[7] = Vertex( 1.0f, -1.0f, 1.0f);
- VB->Unlock();
- WORD* indices = 0;
- IB->Lock(0,0,(void**)&indices,0);
- // front side
- indices[0] = 0; indices[1] = 1; indices[2] = 2;
- indices[3] = 0; indices[4] = 2; indices[5] = 3;
- // back side
- indices[6] = 4; indices[7] = 6; indices[8] = 5;
- indices[9] = 4; indices[10] = 7; indices[11] = 6;
- // left side
- indices[12] = 4; indices[13] = 5; indices[14] = 1;
- indices[15] = 4; indices[16] = 1; indices[17] = 0;
- // right side
- indices[18] = 3; indices[19] = 2; indices[20] = 6;
- indices[21] = 3; indices[22] = 6; indices[23] = 7;
- // top
- indices[24] = 1; indices[25] = 5; indices[26] = 6;
- indices[27] = 1; indices[28] = 6; indices[29] = 2;
- // bottom
- indices[30] = 4; indices[31] = 0; indices[32] = 3;
- indices[33] = 4; indices[34] = 3; indices[35] = 7;
- IB->Unlock();
- //
- // 创建取景变换矩阵
- //
- D3DXVECTOR3 position(0.0f,0.0f,-5.0f);
- D3DXVECTOR3 target(0.0f,0.0f,0.0f);
- D3DXVECTOR3 up(0.0f,1.0f,0.0f);
- D3DXMATRIX V;
- D3DXMatrixLookAtLH(&V,&position,&target,&up);
- Device->SetTransform(D3DTS_VIEW,&V);
- //
- // 设置投影矩阵
- //
- D3DXMATRIX proj;
- D3DXMatrixPerspectiveFovLH(
- &proj,
- D3DX_PI*0.5f,
- (float)Width/(float)Height,
- 1.0f,
- 1000.0f);
- Device->SetTransform(D3DTS_PROJECTION,&proj);
- //
- // 选择绘制状态(线框状态)
- //
- Device->SetRenderState(D3DRS_FILLMODE,D3DFILL_WIREFRAME);
- return true;
- }
- void Cleanup()
- {
- d3d::Release<IDirect3DVertexBuffer9*>(VB);
- d3d::Release<IDirect3DIndexBuffer9*>(IB);
- }
- bool Display(float timeDelta)
- {
- if (Device)
- {
- //
- // 旋转矩阵
- //
- D3DXMATRIX Rx,Ry;
- // 绕 x 方向每帧转45度
- D3DXMatrixRotationX(&Rx,3.14f/4.0f);
- // 绕 y 方向每帧递增角度
- static float y = 0.0f;
- D3DXMatrixRotationY(&Ry,y);
- y += timeDelta;
- // 角度达到360度后归零
- if (y>=6.28f)
- {
- y = 0.0f;
- }
- // 结合x and y 方向的旋转角度
- D3DXMATRIX p = Rx * Ry;
- Device->SetTransform(D3DTS_WORLD,&p);
- //
- // 绘制场景
- //
- Device->Clear(0,0,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER , 0xffffffff,1.0f,0);
- Device->BeginScene();
- Device->SetStreamSource(0,VB,0,sizeof(Vertex));
- Device->SetIndices(IB);
- Device->SetFVF(Vertex::FVF);
- // 绘制立方体
- Device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,8,0,12);
- Device->EndScene();
- Device->Present(0,0,0,0);
- }
- return true;
- }
- //
- // WndProc
- //
- 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);
- }
- //
- // WinMain
- //
- int WINAPI WinMain(HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- LPSTR lpCmdLine,
- int nShowCmd )
- {
- //程序入口地址
- //初始化D3D
- if (!d3d::InitD3D(hInstance,640,480,true,D3DDEVTYPE_HAL,&Device))
- {
- ::MessageBox(0, "InitD3D() - FAILED", 0, 0);
- return 0;
- }
- //分配资源
- if (!Setup())
- {
- ::MessageBox(0, "Setup() - FAILED", 0, 0);
- return 0;
- }
- //进入消息循环
- d3d::EnterMsgLoop(Display);
- //清理资源
- Cleanup();
- Device->Release();
- return 0;
- }
需要注意的一点是: 本例中是用世界变换来指定立方体的方向。因为设置顶点格式时将顶点的位置属性设置为不能改变。
const DWORD Vertex::FVF = D3DFVF_XYZ;
用的是上一篇文章中的框架,只是修改了d3dUtility.cpp里面的三个函数:Setup() Display() Clean() ,框架确实好用。过段时间研究下MS的DXUT。附图: