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 // ====================================================================