1 /*
2 !d3d绘制流水线中的矩阵变换
3 !
4 */
5 #include <Windows.h>
6 #include <d3dx9.h>
7
8 #pragma comment(lib,"d3dx9.lib")
9 #pragma comment(lib,"d3d9.lib")
10 #pragma comment(lib,"winmm.lib")
11
12 //定义全局变量
13 LPDIRECT3D9 g_pD3D = NULL;
14 LPDIRECT3DDEVICE9 g_pDevice = NULL;
15 LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL; //顶点缓存
16
17 const int width = 800;
18 const int height = 600;
19
20 //定义灵活顶点格式
21 struct CUSTOMVERTEX
22 {
23 FLOAT x,y,z; //顶点的3d坐标
24 DWORD color; //定点颜色
25 };
26
27 //灵活顶点格式
28 #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE)
29
30 //初始化D3D
31 HRESULT InitD3D(HWND hwnd)
32 {
33 g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
34 if( !g_pD3D )
35 {
36 return S_FALSE;
37 }
38 D3DPRESENT_PARAMETERS d3dpp;
39 ZeroMemory(&d3dpp,sizeof(d3dpp));
40 d3dpp.Windowed = TRUE;
41 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
42 d3dpp.hDeviceWindow = hwnd;
43 d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
44
45 //创建设备
46 g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hwnd,D3DCREATE_HARDWARE_VERTEXPROCESSING,&d3dpp,&g_pDevice);
47 if ( !g_pDevice )
48 {
49 return S_FALSE;
50 }
51
52 //关闭裁剪,可以看见三角形的前面和后面
53 g_pDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE);
54
55 //因为要提供自定义颜色,所以关闭光线
56 g_pDevice->SetRenderState(D3DRS_LIGHTING,FALSE);
57
58 return S_OK;
59 }
60
61 //初始化顶点缓存
62 HRESULT InitVertex()
63 {
64 //初始化顶点,构造一个三角形
65 CUSTOMVERTEX Vertices[3] = {
66 { -1.0f,-1.0f, 0.0f, 0xffff0000, },
67 { 1.0f,-1.0f, 0.0f, 0xff0000ff, },
68 { 0.0f, 1.0f, 0.0f, 0xffffffff, },
69 };
70
71 //创建顶点缓存
72 HRESULT result = g_pDevice->CreateVertexBuffer(3*sizeof(CUSTOMVERTEX),0,D3DFVF_CUSTOMVERTEX,D3DPOOL_DEFAULT,&g_pVB,0);
73 if( FAILED( result))
74 {
75 return S_FALSE;
76 }
77
78 //填充顶点缓存
79 //获取缓存指针
80 VOID *pVertex;
81 result = g_pVB->Lock(0,sizeof(Vertices),(VOID **)&pVertex,0);
82 if( FAILED(result) )
83 {
84 return S_FALSE;
85 }
86 //复制内存
87 memcpy(pVertex,Vertices,sizeof(Vertices));
88 g_pVB->Unlock();
89 return S_OK;
90 }
91
92 void CleanUp()
93 {
94 if ( g_pVB) g_pVB->Release();
95 if (g_pDevice) g_pDevice->Release();
96 if (g_pD3D ) g_pD3D->Release();
97 }
98
99 //进行世界坐标系,取景变换,投影变换
100 VOID MatrixTransform()
101 {
102 //在世界坐标系中按Y轴旋转
103 D3DXMATRIXA16 matWorld; //世界矩阵
104 UINT iTime = timeGetTime()%1000; //防止精度丢失
105 FLOAT fAngle = iTime * (2.0f * D3DX_PI )/1000.0f; //旋转角度
106 //获取世界变换矩阵
107 D3DXMatrixRotationY(&matWorld,fAngle);
108 g_pDevice->SetTransform(D3DTS_WORLD,&matWorld); //进行世界转换
109
110 //进行取景变换
111 D3DXVECTOR3 vCameraPos( 0.0f, 3.0f,-5.0f ); //摄像机位置
112 D3DXVECTOR3 vLookat( 0.0f,0.0f,0.0f); //观察者位置
113 D3DXVECTOR3 vUp(0.0f, 1.0f, 0.0f ); //y轴向上
114
115 D3DXMATRIXA16 matView; //取景转换矩阵
116 //计算取景转换矩阵
117 D3DXMatrixLookAtLH(&matView,&vCameraPos,&vLookat,&vUp);
118 //进行取景转换
119 g_pDevice->SetTransform(D3DTS_VIEW,&matView);
120
121 //投影变换
122 D3DXMATRIXA16 matProj;
123 //计算投影矩阵
124 D3DXMatrixPerspectiveFovLH(&matProj,D3DX_PI /4.0f,1.0f,1.0f,100.0f);
125 //进行投影变换
126 g_pDevice->SetTransform(D3DTS_PROJECTION,&matProj);
127 }
128
129 VOID Render()
130 {
131 //清空屏幕为黑色
132 if (g_pDevice)
133 {
134 g_pDevice->Clear(0,0,D3DCLEAR_TARGET ,D3DCOLOR_XRGB(0,0,0),1.0f,0);
135
136 if( g_pDevice->BeginScene())
137 {
138 //进行矩阵变换
139 MatrixTransform();
140 //渲染顶点缓存
141 g_pDevice->SetStreamSource(0,g_pVB,0,sizeof(CUSTOMVERTEX));
142 //设置渲染的顶点格式
143 g_pDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
144 //绘制
145 g_pDevice->DrawPrimitive(D3DPT_TRIANGLELIST,0,1);
146
147 g_pDevice->EndScene();
148 }
149
150 g_pDevice->Present(0,0,0,0);
151 }
152 }
153
154 LRESULT WINAPI MgsProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam )
155 {
156 switch( msg )
157 {
158 case WM_DESTROY:
159 {
160 CleanUp();
161 PostQuitMessage(0);
162 return 0;
163 }
164 }
165
166 return DefWindowProc(hwnd,msg,wParam,lParam);
167 }
168
169 //WinMain
170 INT WINAPI WinMain(HINSTANCE hInst,HINSTANCE hInstPre,LPSTR lpcmdLine,INT nShow)
171 {
172 WNDCLASSEX wc =
173 {
174 sizeof( WNDCLASSEX ), CS_CLASSDC, MgsProc, 0L, 0L,
175 GetModuleHandle( NULL ), NULL, NULL, NULL, NULL,
176 "MATRIX", NULL
177 };
178 RegisterClassEx( &wc );
179
180 // Create the application's window
181 HWND hWnd = CreateWindow("MATRIX", "绘制流水线",
182 WS_OVERLAPPEDWINDOW, 100, 100, width, height,
183 NULL, NULL, wc.hInstance, NULL );
184
185 //初始化d3d
186 if(SUCCEEDED(InitD3D(hWnd)))
187 {
188 //初始化顶点缓存和索引缓存
189 if(SUCCEEDED(InitVertex()))
190 {
191 //显示窗口
192 ShowWindow(hWnd,SW_SHOWDEFAULT);
193 UpdateWindow(hWnd);
194
195 //消息循环
196 MSG msg;
197 ZeroMemory(&msg,sizeof(msg));
198
199 while(msg.message != WM_QUIT )
200 {
201 if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
202 {
203 TranslateMessage( &msg );
204 DispatchMessage( &msg );
205 }
206 else
207 {
208 Render();
209 }
210 }
211 }
212 }
213
214 UnregisterClass("MATRIX", wc.hInstance );
215 return 0;
216 }