1 /*---------------------------------------------------------------------------*
2
3 Copyright (C) 2010-2012 Nintendo. All rights reserved.
4
5 These coded instructions, statements, and computer programs contain
6 proprietary information of Nintendo of America Inc. and/or Nintendo
7 Company Ltd., and are protected by Federal copyright law. They may
8 not be disclosed to third parties or copied or duplicated in any form,
9 in whole or in part, without the prior written consent of Nintendo.
10
11 *---------------------------------------------------------------------------*/
12
13 #include "windows.h"
14
15 #include <iostream>
16 #include <fstream>
17
18 #include <d3dx9.h>
19 #pragma comment(lib, "d3d9.lib")
20 #pragma comment(lib, "d3dx9.lib")
21
22 #pragma comment(lib, "gdi32.lib")
23 #pragma comment(lib, "user32.lib")
24
25 // GLOBALS ///////////////////////////////////////////////////////////////////
26
27 HWND hWnd;
28
29 unsigned width = 1280;
30 unsigned height = 720;
31
32 LPDIRECT3DSURFACE9 diffuseSurface = NULL;
33 LPDIRECT3DSURFACE9 normalSurface = NULL;
34 LPDIRECT3DSURFACE9 positionSurface = NULL;
35
36 LPDIRECT3DTEXTURE9 diffuseTex = NULL;
37 LPDIRECT3DTEXTURE9 normalTex = NULL;
38 LPDIRECT3DTEXTURE9 positionTex = NULL;
39
40 D3DXVECTOR3 cameraPos;
41 D3DXMATRIX modelMtx;
42 D3DXMATRIX viewProjMtx;
43
44 LPDIRECT3DDEVICE9 pDevice = NULL;
45 LPD3DXEFFECT pEffect = NULL;
46 LPDIRECT3DSURFACE9 pBackBuffer = NULL;
47
48 D3DPRESENT_PARAMETERS presentParameters;
49
50 #define POSTEX_FVF (D3DFVF_XYZRHW | D3DFVF_TEX1)
51
52 struct PosTexVertex
53 {
54 float pos[4];
55 float tex[2];
56 };
57
58 PosTexVertex posTexQuad[] =
59 {
60 { 0.0f, 0.0f, 0.5f, 1.0f, 0.0f + 0.5f / float(width), 0.0f + 0.5f / float(height) },
61 { float(width), 0.0f, 0.5f, 1.0f, 1.0f + 0.5f / float(width), 0.0f + 0.5f / float(height) },
62 { 0.0f, float(height), 0.5f, 1.0f, 0.0f + 0.5f / float(width), 1.0f + 0.5f / float(height) },
63 { float(width), float(height), 0.5f, 1.0f, 1.0f + 0.5f / float(width), 1.0f + 0.5f / float(height) },
64 };
65
66 #define POSNORM_FVF (D3DFVF_XYZ | D3DFVF_NORMAL)
67
68 struct PosNormVertex
69 {
70 float pos[3];
71 float norm[3];
72 };
73
74 const char* MODEL_FILES[3] =
75 {
76 "teapotPosition.dat",
77 "teapotNormal.dat",
78 "teapotIdx.dat",
79 };
80
81 unsigned numVerts, numTris;
82 LPDIRECT3DVERTEXBUFFER9 vertexBuffer;
83 LPDIRECT3DINDEXBUFFER9 indexBuffer;
84
85 bool quit = false;
86
87 #define PI 3.14159f
88
89 // FUNCTIONS /////////////////////////////////////////////////////////////////
90
LoadModel()91 void LoadModel()
92 {
93 std::ifstream posFile, normFile;
94 posFile.open(MODEL_FILES[0], std::ios::binary);
95 normFile.open(MODEL_FILES[1], std::ios::binary);
96
97 posFile.seekg(0, std::ios::end);
98 numVerts = (unsigned)posFile.tellg() / (3*sizeof(float));
99 posFile.seekg(0, std::ios::beg);
100
101 pDevice->CreateVertexBuffer(numVerts * sizeof(PosNormVertex), D3DUSAGE_WRITEONLY, POSNORM_FVF, D3DPOOL_MANAGED, &vertexBuffer, NULL);
102
103 PosNormVertex* copyTo;
104 vertexBuffer->Lock(0, numVerts * sizeof(PosNormVertex), (void**)©To, 0);
105
106 float x = 141.8f;
107
108 for(unsigned i = 0; i < numVerts; ++i)
109 {
110 for(unsigned j = 0; j < 3; ++j)
111 {
112 char temp[4];
113 posFile.read((char*)&temp, sizeof(temp));
114 ((char*)©To[i].pos[j])[0] = temp[3];
115 ((char*)©To[i].pos[j])[1] = temp[2];
116 ((char*)©To[i].pos[j])[2] = temp[1];
117 ((char*)©To[i].pos[j])[3] = temp[0];
118 }
119 for(unsigned j = 0; j < 3; ++j)
120 {
121 char temp[4];
122 normFile.read((char*)&temp, sizeof(temp));
123 ((char*)©To[i].norm[j])[0] = temp[3];
124 ((char*)©To[i].norm[j])[1] = temp[2];
125 ((char*)©To[i].norm[j])[2] = temp[1];
126 ((char*)©To[i].norm[j])[3] = temp[0];
127 }
128 }
129
130 vertexBuffer->Unlock();
131
132 posFile.close();
133 normFile.close();
134
135 std::ifstream idxFile;
136 idxFile.open(MODEL_FILES[2], std::ios::binary);
137
138 idxFile.seekg(0, std::ios::end);
139 unsigned idxSize = (unsigned)idxFile.tellg();
140 idxFile.seekg(0, std::ios::beg);
141
142 pDevice->CreateIndexBuffer(idxSize, D3DUSAGE_WRITEONLY, D3DFMT_INDEX32, D3DPOOL_MANAGED, &indexBuffer, NULL);
143
144 unsigned* idxCopyTo;
145 indexBuffer->Lock(0, numVerts * sizeof(PosNormVertex), (void**)&idxCopyTo, 0);
146
147 for(unsigned i = 0; i < idxSize / 4; ++i)
148 {
149 char temp[4];
150 idxFile.read((char*)&temp, sizeof(temp));
151 ((char*)&idxCopyTo[i])[0] = temp[3];
152 ((char*)&idxCopyTo[i])[1] = temp[2];
153 ((char*)&idxCopyTo[i])[2] = temp[1];
154 ((char*)&idxCopyTo[i])[3] = temp[0];
155 }
156
157 indexBuffer->Unlock();
158
159 numTris = idxSize / sizeof(unsigned) / 3;
160
161 idxFile.close();
162 }
163
InitGlobals()164 bool InitGlobals()
165 {
166 LoadModel();
167
168 pDevice->CreateTexture(width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &diffuseTex, NULL);
169 diffuseTex->GetSurfaceLevel(0, &diffuseSurface);
170
171 pDevice->CreateTexture(width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A16B16G16R16F, D3DPOOL_DEFAULT, &normalTex, NULL);
172 normalTex->GetSurfaceLevel(0, &normalSurface);
173
174 pDevice->CreateTexture(width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A16B16G16R16F, D3DPOOL_DEFAULT, &positionTex, NULL);
175 positionTex->GetSurfaceLevel(0, &positionSurface);
176
177 D3DXMATRIX matProjection;
178 D3DXMatrixPerspectiveFovRH(&matProjection,
179 30.0f * PI / 180.0f,
180 (float)width / (float)height,
181 50.0f,
182 2000.0f);
183
184 cameraPos = D3DXVECTOR3(0.0f, 0.0f, 300.0f);
185
186 D3DXMATRIX matView;
187 D3DXMatrixLookAtRH(&matView,
188 &cameraPos,
189 &D3DXVECTOR3(0.0f, 0.0f, 0.0f),
190 &D3DXVECTOR3(0.0f, 1.0f, 0.0f));
191
192 D3DXMatrixMultiply(&viewProjMtx, &matView, &matProjection);
193
194 return true;
195 }
196
Animate()197 void Animate()
198 {
199 static float rotateY = 0.0f;
200
201 D3DXMATRIX matYAxisRotation, matScaling;
202 D3DXMatrixScaling(&matScaling, 1.0f, 1.0f, 1.0f);
203 D3DXMatrixRotationY(&matYAxisRotation, rotateY);
204 D3DXMatrixMultiply(&modelMtx, &matYAxisRotation, &matScaling);
205
206 rotateY += 0.015f;
207 if(rotateY > PI*2.0f)
208 {
209 rotateY -= PI*2.0f;
210 }
211
212 pEffect->SetVector("u_cameraPosition",(D3DXVECTOR4*)&cameraPos);
213 pEffect->SetMatrix("u_viewprojMtx",&viewProjMtx);
214 }
215
SetupPass()216 void SetupPass()
217 {
218 pDevice->SetRenderTarget(0, diffuseSurface);
219 pDevice->SetRenderTarget(1, normalSurface);
220 pDevice->SetRenderTarget(2, positionSurface);
221
222 pDevice->Clear(0, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0);
223
224 pEffect->SetTechnique("setup");
225 pEffect->SetMatrix("u_modelMtx", &modelMtx);
226
227 pEffect->Begin(NULL, 0);
228
229 D3DXVECTOR4 color(1.0f, 0.0f, 0.0f, 80.0f / 255.0f); // shininess / 255.0f
230 pEffect->SetVector("u_color", &color);
231
232 pEffect->BeginPass(0);
233
234 pDevice->SetFVF(POSNORM_FVF);
235 pDevice->SetIndices(indexBuffer);
236 pDevice->SetStreamSource(0, vertexBuffer, 0, sizeof(PosNormVertex));
237 pDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, numVerts, 0, numTris);
238
239 pEffect->EndPass();
240
241 pEffect->End();
242
243 pDevice->SetRenderTarget(0,pBackBuffer);
244 pDevice->SetRenderTarget(1,NULL);
245 pDevice->SetRenderTarget(2,NULL);
246 pDevice->SetRenderTarget(3,NULL);
247 }
248
LightingPass()249 void LightingPass()
250 {
251 pDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00888888, 1.0f, 0);
252
253 pEffect->SetTechnique("lighting");
254
255 D3DXVECTOR4 lightPos(40.0f, 30.0f, 40.0f, 1.0f);
256 pEffect->SetVector("u_lightPosition", &lightPos);
257 D3DXVECTOR4 ambientColor(0.3f, 0.3f, 0.3f, 1.0f);
258 pEffect->SetVector("u_ambientColor", &ambientColor);
259 D3DXVECTOR4 lightColor(1.0f, 1.0f, 1.0f, 10.0f / 255.0f); // attenuation / 255.0f
260 pEffect->SetVector("u_lightColor", &lightColor);
261
262 pEffect->SetTexture("t_diffuse", diffuseTex);
263 pEffect->SetTexture("t_normal", normalTex);
264 pEffect->SetTexture("t_position", positionTex);
265
266 pEffect->Begin(NULL, 0);
267
268 pEffect->BeginPass(0);
269 pDevice->SetFVF(POSTEX_FVF);
270 pDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, posTexQuad, sizeof(PosTexVertex));
271 pEffect->EndPass();
272
273 pEffect->End();
274 }
275
WndProc(HWND hWnd,unsigned int uMsg,WPARAM wParam,LPARAM lParam)276 LRESULT CALLBACK WndProc(HWND hWnd, unsigned int uMsg, WPARAM wParam, LPARAM lParam)
277 {
278 switch(uMsg)
279 {
280 case WM_SYSCOMMAND:
281 switch (wParam)
282 {
283 case SC_CLOSE:
284 quit = true;
285 return 0;
286 }
287 break;
288
289 case WM_PAINT:
290 pDevice->Present( NULL, NULL, NULL, NULL );
291 break;
292 }
293
294 return DefWindowProc(hWnd, uMsg, wParam, lParam);
295 }
296
InitWindow()297 bool InitWindow()
298 {
299 HINSTANCE hInstance = GetModuleHandle(NULL);
300
301 WNDCLASS wc;
302 SecureZeroMemory(&wc, sizeof(wc));
303 wc.style = CS_HREDRAW | CS_VREDRAW;
304 wc.lpfnWndProc = WndProc;
305 wc.hInstance = hInstance;
306 wc.lpszClassName = (LPCSTR)"GameWindow";
307
308 RegisterClass(&wc);
309
310 RECT WindowRect;
311 DWORD dwExStyle;
312 DWORD dwStyle;
313
314 WindowRect.left = GetSystemMetrics(SM_CXSCREEN)/2 - width/2;
315 WindowRect.right = GetSystemMetrics(SM_CXSCREEN)/2 + width/2;
316 WindowRect.top = GetSystemMetrics(SM_CYSCREEN)/2 - height/2;
317 WindowRect.bottom = GetSystemMetrics(SM_CYSCREEN)/2 + height/2;
318
319 dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE | WS_EX_NOPARENTNOTIFY;
320 dwStyle = WS_OVERLAPPEDWINDOW;
321
322 AdjustWindowRectEx(&WindowRect, dwStyle, false, dwExStyle);
323
324 hWnd = CreateWindowEx( dwExStyle, (LPCSTR)"GameWindow", (LPCSTR)"deferredTest",
325 WS_CLIPSIBLINGS | WS_CLIPCHILDREN | dwStyle,
326 WindowRect.left, WindowRect.top, WindowRect.right - WindowRect.left, WindowRect.bottom - WindowRect.top,
327 NULL, NULL, hInstance, NULL);
328
329 ShowWindow(hWnd, SW_SHOW);
330 SetForegroundWindow(hWnd);
331 SetFocus(hWnd);
332
333 return true;
334 }
335
InitDX9()336 bool InitDX9()
337 {
338 LPDIRECT3D9 pObject = Direct3DCreate9(D3D_SDK_VERSION);
339
340 D3DDISPLAYMODE d3ddm;
341 pObject->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm);
342
343 SecureZeroMemory(&presentParameters, sizeof(presentParameters));
344 presentParameters.Windowed = TRUE;
345 presentParameters.BackBufferWidth = width;
346 presentParameters.BackBufferHeight = height;
347 presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
348 presentParameters.BackBufferFormat = d3ddm.Format;
349 presentParameters.EnableAutoDepthStencil = TRUE;
350 presentParameters.AutoDepthStencilFormat = D3DFMT_D24S8;
351 presentParameters.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
352
353 pObject->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &presentParameters, &pDevice);
354
355 D3DCAPS9 deviceCaps;
356 ZeroMemory(&deviceCaps, sizeof(deviceCaps));
357
358 pDevice->GetDeviceCaps(&deviceCaps);
359
360 D3DXCreateEffectFromFile(pDevice, "deferredTest.fx", NULL, NULL, 0, NULL, &pEffect, NULL);
361
362 pDevice->GetRenderTarget(0, &pBackBuffer);
363
364 return true;
365 }
366
WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)367 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
368 {
369 if(!InitWindow()) return 1;
370 if(!InitDX9()) return 2;
371 if(!InitGlobals()) return 3;
372
373 while(quit == false)
374 {
375 MSG msg;
376 while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
377 {
378 if(msg.message == WM_QUIT)
379 {
380 quit = true;
381 break;
382 }
383
384 TranslateMessage(&msg);
385 DispatchMessage(&msg);
386 }
387
388 if(SUCCEEDED(pDevice->BeginScene()))
389 {
390 Animate();
391 SetupPass();
392 LightingPass();
393
394 pDevice->EndScene();
395 }
396 pDevice->Present(NULL, NULL, NULL, NULL);
397 }
398
399 return 0;
400 }
401