1 // =============================================================
2 // Sean Smith
3 // Part 3: Project 3 - 3D Lighting
4 // CSC465 - Johnathan Harbour
5 // Main.cpp
6 // =============================================================
7
8
9 #include <windows.h>
10 #include <windowsx.h>
11 #include <d3d9.h>
12 #include <d3dx9.h>
13 #include <dinput.h>
14
15 // Include the Direct3D Library files
16 #pragma comment (lib, "d3d9.lib")
17 #pragma comment (lib, "d3dx9.lib")
18 #pragma comment (lib, "dinput8.lib")
19 #pragma comment (lib, "dxguid.lib")
20
21 // Defining Screen Res
22 #define SCREEN_WIDTH 1024
23 #define SCREEN_HEIGHT 768
24
25 // ======================[ Global Declarations ]================================
26 bool exitprog = false; // value to exit program
27 int i = 0; // default iterator
28 float yAxisMovement = 0; // moving left and right
29 float xAxisMovement = 0; // moving up and down
30 bool lightDirectional = false; // directional light enable
31 bool lightPoint = false; // point light enable
32 bool lightSpot = false; // spot light enable
33
34 LPDIRECT3D9 d3d = NULL; // pointer to the Direct3D interface
35 LPDIRECT3DDEVICE9 d3ddev = NULL; // pointer to the device class
36
37 LPDIRECTINPUT8 din; // the pointer to our DirectInput interface
38 LPDIRECTINPUTDEVICE8 dinKeyboard; // the pointer to the keyboard device
39
40
41 // ======================[ Function Declarations ]===============================
42 // Direct3D Prototypes
43 void Direct3D_Init(HWND hWnd); // sets up and initializes Direct3D
44 void Direct3D_RenderFrame(void); // renders a single frame
45 void Direct3D_Close(void); // closes Direct3D and releases memory
46
47 // DirectInput Prototypes
48 void DInput_Init(HINSTANCE hInstance, HWND hWnd); // sets up and initializes DirectInput
49 void DInput_DetectKeys(void); // gets the current keys being pressed
50 void DInput_Close(void); // closes DirectInput and releases memory
51
52 // Camera Matricies Prototype
53 void Camera_Setup(void);
54
55 // 3D Object Prototype
56 void Graphics_Init(void); // 3D declarations
57
58 // Light and Material Prototype
59 void Lights_Init(void);
60
61
62 // Model definition
63 struct MODEL
64 {
65 LPD3DXMESH mesh; //the vertices stored in a mesh
66 D3DMATERIAL9* materials; //materials applied to polygons
67 LPDIRECT3DTEXTURE9* textures; //textures applied to polygons
68 DWORD material_count; //number of materials in mesh
69 };
70 //allocate the mesh buffer in memory
71 MODEL *model = (MODEL*)malloc(sizeof(MODEL));
72
73
74 // ====================================================================
75 // DIRECT3D FUNCTIONS
76 // ====================================================================
77
78 // ----------------------[Initialize]----------------------------
79 void Direct3D_Init(HWND hWnd)
80 {
81 d3d = Direct3DCreate9(D3D_SDK_VERSION); // create the Direct3D interface
82
83 D3DPRESENT_PARAMETERS d3dpp; // struct to hold various device information
84
85 ZeroMemory(&d3dpp, sizeof(d3dpp)); // clear out the struct for use
86 d3dpp.Windowed = true; // program windowed or fullscreen
87 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; // clear old frames
88 d3dpp.hDeviceWindow = hWnd; // set the window to be used by Direct3D
89 d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; // set the back buffer format to 32-bit
90 d3dpp.BackBufferWidth = SCREEN_WIDTH; // set the width of the buffer
91 d3dpp.BackBufferHeight = SCREEN_HEIGHT; // set the height of the buffer
92 d3dpp.EnableAutoDepthStencil = TRUE; // automatically run the z-buffer for us
93 d3dpp.AutoDepthStencilFormat = D3DFMT_D16; // 16-bit pixel format for the z-buffer
94
95 // create a device class using this information and information from the d3dpp stuct
96 d3d->CreateDevice(D3DADAPTER_DEFAULT,
97 D3DDEVTYPE_HAL,
98 hWnd,
99 D3DCREATE_SOFTWARE_VERTEXPROCESSING,
100 &d3dpp,
101 &d3ddev);
102
103 Graphics_Init(); // calls graphics initializing function
104 //Lights_Init(); // calls lighting and materials initializing function
105
106 return;
107 }
108
109 // ----------------------[Frame Render]----------------------------
110 void Direct3D_RenderFrame(void)
111 {
112 // clear the window & set color
113 d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(50, 50, 50), 1.0f, 0);
114 d3ddev->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
115
116 d3ddev->BeginScene(); // begins the D3D scene
117
118 if (d3ddev->BeginScene())
119 {
120 Lights_Init(); // calls lighting and materials initializing function
121
122 // Set up world, view, and projection matricies
123 Camera_Setup();
124
125 // Draw the Mesh
126 for(i=0; i < model->material_count; i++) // loop through each material subset
127 {
128 d3ddev->SetMaterial(&model->materials[i]);
129 d3ddev->SetTexture(0, model->textures[i]);
130 model->mesh->DrawSubset(i);
131 }
132
133 d3ddev->EndScene(); // ends the D3D scene
134 }
135
136 d3ddev->Present(NULL, NULL, NULL, NULL); // displays the created frame
137
138 return;
139 }
140
141 // ----------------------[Clean Up]----------------------------
142 void Direct3D_Close(void)
143 {
144 if( model->materials != NULL )
145 delete[] model->materials;
146
147 if( model->textures )
148 {
149 for( DWORD i = 0; i < model->material_count; i++ )
150 {
151 if( model->textures[i] )
152 model->textures[i]->Release();
153 }
154 delete[] model->textures;
155 }
156 if( model->mesh != NULL )
157 model->mesh->Release(); // close and release the mesh
158
159 if( d3ddev != NULL )
160 d3ddev->Release(); // close and release the 3D device
161
162 if( d3d != NULL )
163 d3d->Release(); // close and release Direct3D
164
165 return;
166 }
167 // ====================================================================
168 // ====================================================================
169
170
171 // ====================================================================
172 // DIRECTINPUT FUNCTIONS
173 // ====================================================================
174
175 // ----------------------[Initialize]----------------------------
176 void DInput_Init(HINSTANCE hInstance, HWND hWnd)
177 {
178 // create the DirectInput interface
179 DirectInput8Create(hInstance, // the handle to the application
180 DIRECTINPUT_VERSION, // the compatible version
181 IID_IDirectInput8, // the DirectInput interface version
182 (void**)&din, // the pointer to the interface
183 NULL);
184
185 // create the keyboard device
186 din->CreateDevice(GUID_SysKeyboard, // the default keyboard ID being used
187 &dinKeyboard, // the pointer to the device interface
188 NULL);
189
190 dinKeyboard->SetDataFormat(&c_dfDIKeyboard); // set the data format to keyboard format
191
192 // set the control you will have over the keyboard
193 dinKeyboard->SetCooperativeLevel(hWnd, DISCL_NONEXCLUSIVE | DISCL_BACKGROUND);
194
195 return;
196 }
197
198 // ----------------------[Detect Keys]----------------------------
199 void DInput_DetectKeys(void)
200 {
201 static BYTE keystate[256]; // create a static storage for the key-states
202
203 dinKeyboard->Acquire(); // get access to the keyboard device
204
205 dinKeyboard->GetDeviceState(sizeof(keystate), (LPVOID)&keystate); // fill keystate with values
206
207 if (keystate[DIK_ESCAPE] & 0x80)
208 exitprog = true; // exit program
209
210 if ((keystate[DIK_A] & 0x80) || (keystate[DIK_LEFT] & 0x80))
211 yAxisMovement += 0.1f; // move left
212 if (keystate[DIK_D] & 0x80 || (keystate[DIK_RIGHT] & 0x80))
213 yAxisMovement -= 0.1f; // move right
214 if (keystate[DIK_W] & 0x80 || (keystate[DIK_UP] & 0x80))
215 xAxisMovement += 0.1f; // move up
216 if (keystate[DIK_S] & 0x80 || (keystate[DIK_DOWN] & 0x80))
217 xAxisMovement -= 0.1f; // move down
218
219 if (keystate[DIK_1] & 0x80)
220 {
221 lightDirectional = true; // directional light enable
222 lightPoint = false;
223 lightSpot = false;
224 }
225 else if (keystate[DIK_2] & 0x80)
226 {
227 lightPoint = true; // point light enable
228 lightDirectional = false;
229 lightSpot = false;
230 }
231 else if (keystate[DIK_3] & 0x80)
232 {
233 lightSpot = true; // spot light enable
234 lightDirectional = false;
235 lightPoint = false;
236 }
237
238 return;
239 }
240
241 // ----------------------[Clean Up]----------------------------
242 void DInput_Close(void)
243 {
244 dinKeyboard->Unacquire(); // gives up access to the keyboard
245 din->Release(); // closes DirectInput before exiting
246 }
247 // ====================================================================
248 // ====================================================================
249
250
251 // ====================================================================
252 // CAMERA SETUP
253 // ====================================================================
254 void Camera_Setup()
255 {
256 // Set up world matrix
257 D3DXMATRIX matYRotation;
258 D3DXMATRIX matXRotation;
259 D3DXMATRIX matScale;
260 D3DXMatrixRotationY( &matYRotation, yAxisMovement );
261 D3DXMatrixRotationX( &matXRotation, xAxisMovement );
262 D3DXMatrixScaling(&matScale, 0.1f, 0.1f, 0.1f);
263 d3ddev->SetTransform( D3DTS_WORLD, &(matYRotation * matXRotation * matScale) );
264
265 // Set up view matrix
266 D3DXVECTOR3 vEyePt( 0.0f, 30.0f, -75.0f );
267 D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
268 D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
269 D3DXMATRIX matView;
270 D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
271 d3ddev->SetTransform( D3DTS_VIEW, &matView );
272
273 // Set up projection matrix
274 D3DXMATRIX matProj;
275 D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI / 4, 1.0f, 1.0f, 100.0f );
276 d3ddev->SetTransform( D3DTS_PROJECTION, &matProj );
277 }
278 // ====================================================================
279 // ====================================================================
280
281
282 // ====================================================================
283 // GRAPHIC FUNCTIONS
284 // ====================================================================
285
286 // ----------------------[Initialize]----------------------------
287 void Graphics_Init(void)
288 {
289 //define the material buffer
290 LPD3DXBUFFER matBuffer;
291
292 D3DXLoadMeshFromX(
293 L"LandShark.x", //.X file
294 D3DXMESH_SYSTEMMEM, //mesh options
295 d3ddev, //D3D device object
296 NULL, //adjacency buffer
297 &matBuffer, //material buffer
298 NULL, //special effects
299 &model->material_count, //number of materials
300 &model->mesh); //mesh object
301
302 // retrieve the pointer to the buffer containing the material information
303 D3DXMATERIAL* d3dxMaterials = (LPD3DXMATERIAL)matBuffer->GetBufferPointer();
304
305 model->materials = new D3DMATERIAL9[model->material_count]; // the materials array
306 model->textures = new LPDIRECT3DTEXTURE9[model->material_count]; // the textures array
307
308 for(i=0; i < model->material_count; i++)
309 {
310 //grab the material
311 model->materials[i] = d3dxMaterials[i].MatD3D;
312
313 //set ambient color for material
314 model->materials[i].Ambient = model->materials[i].Diffuse;
315
316 model->textures[i] = NULL;
317 if( d3dxMaterials[i].pTextureFilename != NULL &&
318 lstrlenA(d3dxMaterials[i].pTextureFilename) > 0 )
319 {
320 //load texture file specified in .x file
321 D3DXCreateTextureFromFileA(d3ddev,
322 d3dxMaterials[i].pTextureFilename,
323 &model->textures[i]);
324 }
325 }
326
327 matBuffer->Release();
328
329 return;
330 }
331 // ====================================================================
332 // ====================================================================
333
334
335 // ====================================================================
336 // LIGHT FUNCTIONS
337 // ====================================================================
338
339 // ----------------------[Initialize]----------------------------
340 void Lights_Init(void)
341 {
342 D3DLIGHT9 light; // create the light struct
343 D3DXVECTOR3 vecDirection;
344 D3DXVECTOR3 vecPosition;
345 ZeroMemory(&light, sizeof(light)); // clear out the struct for use
346 light.Range = 100.0f;
347
348 if (lightDirectional)
349 {
350 lightPoint = false;
351 lightSpot = false;
352 light.Type = D3DLIGHT_DIRECTIONAL; // sets the light type
353 light.Diffuse.r = 0.5f; // red
354 light.Diffuse.g = 0.5f; // green
355 light.Diffuse.b = 0.9f; // blue
356 light.Diffuse.a = 1.0f; // full alpha
357
358 vecDirection = D3DXVECTOR3(-2.0f, -2.0f, -1.0f); // the direction of the light
359 D3DXVec3Normalize((D3DXVECTOR3*)&light.Direction, &vecDirection); // applying the light direction
360 }
361 else if (lightPoint)
362 {
363 lightDirectional = false;
364 lightSpot = false;
365 light.Type = D3DLIGHT_POINT; // sets the light type
366 light.Diffuse.r = 0.9f; // red
367 light.Diffuse.g = 0.5f; // green
368 light.Diffuse.b = 0.5f; // blue
369 light.Diffuse.a = 1.0f; // full alpha
370
371 vecPosition = D3DXVECTOR3(0.0f, -10.0f, 0.0f); // the position of the light
372 light.Position = vecPosition; // position of light
373 light.Attenuation0 = 0.1f; //brightness
374 }
375 else if (lightSpot)
376 {
377 lightPoint = false;
378 lightDirectional = false;
379 light.Type = D3DLIGHT_SPOT; // sets the light type
380 light.Diffuse.r = 0.5f; // red
381 light.Diffuse.g = 0.9f; // green
382 light.Diffuse.b = 0.5f; // blue
383 light.Diffuse.a = 1.0f; // full alpha
384
385 vecPosition = D3DXVECTOR3(10.0f, 20.0f, 0.0f); // the position of the light
386 vecDirection = D3DXVECTOR3(-2.0f, -2.0f, 0.0f); // the direction of the light
387 light.Position = vecPosition;
388 light.Direction = vecDirection;
389 light.Theta = 0.5f; // inner cone
390 light.Phi = 1.0f; // outer cone
391 light.Falloff = 1.0f; // light range falloff
392 light.Attenuation0 = 1.0f; // light strength
393 }
394
395 d3ddev->SetLight(0, &light); // send the light struct properties to light #0
396 d3ddev->LightEnable(0, TRUE); // turn on light #0
397 d3ddev->SetRenderState(D3DRS_LIGHTING, true); // turns off 3D lighting
398 d3ddev->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(50, 50, 50)); // ambient light
399
400 return;
401 }
402 // ====================================================================
403 // ====================================================================
404
405
406 // ====================================================================
407 // MESSAGE HANDLER
408 // ====================================================================
409 LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
410 {
411 switch(message)
412 {
413 case WM_DESTROY:
414 {
415 PostQuitMessage(0);
416 return 0;
417 } break;
418 }
419
420 return DefWindowProc (hWnd, message, wParam, lParam);
421 }
422 // ====================================================================
423 // ====================================================================
424
425
426 // ====================================================================
427 // PROGRAM ENTRY POINT
428 // ====================================================================
429 int WINAPI WinMain(HINSTANCE hInstance,
430 HINSTANCE hPrevInstance,
431 LPSTR lpCmdLine,
432 int nCmdShow)
433 {
434 HWND hWnd;
435 WNDCLASSEX wc;
436
437 ZeroMemory(&wc, sizeof(WNDCLASSEX));
438
439 wc.cbSize = sizeof(WNDCLASSEX);
440 wc.style = CS_HREDRAW | CS_VREDRAW;
441 wc.lpfnWndProc = (WNDPROC)WindowProc;
442 wc.hInstance = hInstance;
443 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
444 //wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
445 wc.lpszClassName = L"WindowClass";
446
447 RegisterClassEx(&wc);
448
449 hWnd = CreateWindowEx(NULL,
450 L"WindowClass",
451 L"Assignment 8 - D3DX_3DLights",
452 WS_OVERLAPPEDWINDOW,
453 300, 300,
454 SCREEN_WIDTH, SCREEN_HEIGHT,
455 NULL,
456 NULL,
457 hInstance,
458 NULL);
459
460 ShowWindow(hWnd, nCmdShow);
461
462 // set up and initialize Direct3D
463 Direct3D_Init(hWnd);
464
465 // set up and initialize DirectInput
466 DInput_Init(hInstance, hWnd);
467
468 MSG msg;
469
470 while(TRUE)
471 {
472 DWORD starting_point = GetTickCount();
473
474 if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
475 {
476 if (msg.message == WM_QUIT)
477 break;
478
479 TranslateMessage(&msg);
480 DispatchMessage(&msg);
481 }
482
483 Direct3D_RenderFrame();
484 DInput_DetectKeys();
485
486 if (exitprog)
487 break;
488
489 while ((GetTickCount() - starting_point) < 25);
490 }
491
492 // clean up DInput
493 DInput_Close();
494
495 // clean up objects
496 Direct3D_Close();
497
498 return msg.wParam;
499 }
500 // ====================================================================
501 // ====================================================================