DirectX 中的光照

来源:互联网 发布:macbook windows快捷键 编辑:程序博客网 时间:2024/05/11 05:19

          DirectX 中的光照

给一个场景添加光照的步骤为:
(1)激活光照模型
(2)为每一个物体创建材质,并在渲染前设置相应的材质
(3)创建光源
(4)打开光照状态,如镜面高光等。
源代码:
litPyramid.cpp

Code:
  1. #include "d3dUtility.h"   
  2.   
  3. //   
  4. //  Globals   
  5. //   
  6.   
  7. IDirect3DDevice9* Device = 0;   
  8. const int Width  =  640;   
  9. const int Height = 480;   
  10. IDirect3DVertexBuffer9* Pyramid = 0;   
  11. /*  
  12.   Classes  and structures  
  13. */  
  14.   
  15. //定义Vertex 类型   
  16.   
  17. struct  Vertex   
  18. {   
  19.     Vertex(){}   
  20.   
  21.     Vertex(float x,float y,float z,   
  22.         float nx,float ny,float nz)   
  23.     {   
  24.         _x = x ; _y = y ;_z= z;   
  25.         _nx = nx;_ny = ny; _nz = nz;   
  26.     }   
  27.     float _x,_y,_z;   
  28.     float _nx,_ny,_nz;   
  29.   
  30.     static const DWORD FVF;   
  31. };   
  32. const DWORD Vertex::FVF =D3DFVF_XYZ|D3DFVF_NORMAL;   
  33.   
  34. //   
  35. //  Framework Functions   
  36. //   
  37.   
  38. bool Setup()   
  39. {   
  40.     //开启光照   
  41.     Device->SetRenderState(D3DRS_LIGHTING,true);   
  42.     //为Pyramid创建vertex buffer   
  43.     Device->CreateVertexBuffer(   
  44.         12*sizeof(Vertex),   
  45.         D3DUSAGE_WRITEONLY,   
  46.         Vertex::FVF,   
  47.         D3DPOOL_MANAGED,   
  48.         &Pyramid,   
  49.         0);   
  50.     //用Pyramid数据填充vertex buffer   
  51.   
  52.     Vertex*  v;   
  53.     Pyramid->Lock(0,0,(void**)&v,0);   
  54.     v[0] = Vertex(-1.0f, 0.0f, -1.0f, 0.0f, 0.707f, -0.707f);   
  55.     v[1] = Vertex( 0.0f, 1.0f,  0.0f, 0.0f, 0.707f, -0.707f);   
  56.     v[2] = Vertex( 1.0f, 0.0f, -1.0f, 0.0f, 0.707f, -0.707f);   
  57.   
  58.     // left face   
  59.     v[3] = Vertex(-1.0f, 0.0f,  1.0f, -0.707f, 0.707f, 0.0f);   
  60.     v[4] = Vertex( 0.0f, 1.0f,  0.0f, -0.707f, 0.707f, 0.0f);   
  61.     v[5] = Vertex(-1.0f, 0.0f, -1.0f, -0.707f, 0.707f, 0.0f);   
  62.   
  63.     // right face   
  64.     v[6] = Vertex( 1.0f, 0.0f, -1.0f, 0.707f, 0.707f, 0.0f);   
  65.     v[7] = Vertex( 0.0f, 1.0f,  0.0f, 0.707f, 0.707f, 0.0f);   
  66.     v[8] = Vertex( 1.0f, 0.0f,  1.0f, 0.707f, 0.707f, 0.0f);   
  67.   
  68.     // back face   
  69.     v[9]  = Vertex( 1.0f, 0.0f,  1.0f, 0.0f, 0.707f, 0.707f);   
  70.     v[10] = Vertex( 0.0f, 1.0f,  0.0f, 0.0f, 0.707f, 0.707f);   
  71.     v[11] = Vertex(-1.0f, 0.0f,  1.0f, 0.0f, 0.707f, 0.707f);   
  72.   
  73.     Pyramid->Unlock();   
  74.   
  75.     // 创建和设置材质   
  76.     D3DMATERIAL9 mtrl;   
  77.     mtrl.Ambient = d3d::WHITE;   
  78.     mtrl.Diffuse = d3d::WHITE;   
  79.     mtrl.Specular = d3d::WHITE;   
  80.     mtrl.Emissive = d3d::BLACK;   
  81.     mtrl.Power = 5.0f;   
  82.   
  83.     Device->SetMaterial(&mtrl);   
  84.     //设置一个直线光源   
  85.     D3DLIGHT9 dir;   
  86.     ::ZeroMemory(&dir,sizeof(dir));   
  87.     dir.Type = D3DLIGHT_DIRECTIONAL;   
  88.     dir.Diffuse = d3d::WHITE;   
  89.     dir.Ambient = d3d::WHITE*0.6f;   
  90.     dir.Specular = d3d::WHITE*0.3f;   
  91.     dir.Direction = D3DXVECTOR3(1.0f,0,0);   
  92.   
  93.     //设置,开放 灯光,使用灯光   
  94.     Device->SetLight(0,&dir);   
  95.     Device->LightEnable(0,true);   
  96.   
  97.     //设置渲染状态,重新计算法线方向,打开镜面光   
  98.     Device->SetRenderState(D3DRS_NORMALIZENORMALS,true);   
  99.     Device->SetRenderState(D3DRS_SPECULARENABLE,true);   
  100.        
  101.     //设置camera 位置   
  102.     D3DXVECTOR3 pos(0.0f,1.0f,-3.0f);   
  103.     D3DXVECTOR3 target(0.0f,0.0f,0.0f);   
  104.     D3DXVECTOR3 up(0.0f,1.0f,0.0f);   
  105.   
  106.     D3DXMATRIX View;   
  107.     D3DXMatrixLookAtLH(&View,&pos,&target,&up);   
  108.     Device->SetTransform(D3DTS_VIEW,&View);   
  109.     //设置投影矩阵   
  110.     D3DXMATRIX proj;   
  111.     D3DXMatrixPerspectiveFovLH(   
  112.         &proj,   
  113.         D3DX_PI *0.5f,   
  114.         (float)Width/(float)Height,   
  115.         1.0f,   
  116.         1000.0f);   
  117.     Device->SetTransform(D3DTS_PROJECTION,&proj);   
  118.   
  119.     return true;   
  120. }   
  121.   
  122. void Cleanup()   
  123. {   
  124.     //清理创建的buffer   
  125.     d3d::Release<IDirect3DVertexBuffer9* >(Pyramid);   
  126. }   
  127.   
  128. bool Display(float timeDelta)   
  129. {   
  130.     if (Device)   
  131.     {   
  132.         D3DXMATRIX yRot;   
  133.   
  134.         static float y = 0.0f;   
  135.   
  136.         D3DXMatrixRotationY(&yRot,y);   
  137.         y+= timeDelta;   
  138.         if (y>6.28f)   
  139.         {   
  140.             y = 0.0f;   
  141.         }   
  142.         Device->SetTransform(D3DTS_WORLD,&yRot);   
  143.         // 绘制场景   
  144.         Device->Clear(0, 0, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,   
  145.                 0x00000000,1.0f,0);   
  146.         Device->BeginScene();   
  147.   
  148.         Device->SetStreamSource(0,Pyramid, 0, sizeof(Vertex));   
  149.         Device->SetFVF(Vertex::FVF);   
  150.         Device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 4);   
  151.   
  152.         Device->EndScene();   
  153.         Device->Present(0,0,0,0);   
  154.     }   
  155.   
  156.     return true;   
  157. }   
  158.   
  159. //回调函数   
  160.   
  161. LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)   
  162. {   
  163.     switch( msg )   
  164.     {   
  165.     case WM_DESTROY:   
  166.         ::PostQuitMessage(0);   
  167.         break;   
  168.   
  169.     case WM_KEYDOWN:   
  170.         if( wParam == VK_ESCAPE )   
  171.             ::DestroyWindow(hwnd);   
  172.         break;   
  173.     }   
  174.     return ::DefWindowProc(hwnd, msg, wParam, lParam);   
  175. }   
  176.   
  177.   
  178. //   
  179. // 主函数   
  180. //   
  181. int WINAPI WinMain(HINSTANCE hinstance,   
  182.                    HINSTANCE prevInstance,    
  183.                    PSTR cmdLine,   
  184.                    int showCmd)   
  185. {   
  186.     if(!d3d::InitD3D(hinstance,   
  187.         Width, Height, true, D3DDEVTYPE_HAL, &Device))   
  188.     {   
  189.         ::MessageBox(0, _T("InitD3D() - FAILED"), 0, 0);   
  190.         return 0;   
  191.     }   
  192.   
  193.     if(!Setup())   
  194.     {   
  195.         ::MessageBox(0, _T("Setup() - FAILED"), 0, 0);   
  196.         return 0;   
  197.     }   
  198.   
  199.     d3d::EnterMsgLoop( Display );   
  200.   
  201.     Cleanup();   
  202.   
  203.     Device->Release();   
  204.   
  205.     return 0;   
  206. }  

d3dUtility.h

Code:
  1.  
  2. #include "d3dx9.h"  
  3. #include "d3d9.h"  
  4. #include <tchar.h>  
  5. #include <iostream>  
  6. #include <vector>  
  7. #include<Windows.h>  
  8.  
  9. #pragma comment(lib,"d3dx9.lib")  
  10. #pragma comment(lib,"d3d9.lib")  
  11. #pragma comment(lib,"winmm.lib")   
  12.   
  13. namespace d3d   
  14. {   
  15.     bool InitD3D(   
  16.         HINSTANCE hInstance,       // [in] Application instance.   
  17.         int width, int height,     // [in] Backbuffer dimensions.   
  18.         bool windowed,             // [in] Windowed (true)or full screen (false).   
  19.         D3DDEVTYPE deviceType,     // [in] HAL or REF   
  20.         IDirect3DDevice9** device);// [out]The created device.   
  21.   
  22.     int EnterMsgLoop(    
  23.         bool (*ptr_display)(float timeDelta));   
  24.   
  25.     LRESULT CALLBACK WndProc(   
  26.         HWND hwnd,   
  27.         UINT msg,    
  28.         WPARAM wParam,   
  29.         LPARAM lParam);   
  30.   
  31.     template<class T> void Release(T t)   
  32.     {   
  33.         if( t )   
  34.         {   
  35.             t->Release();   
  36.             t = 0;   
  37.         }   
  38.     }   
  39.   
  40.     template<class T> void Delete(T t)   
  41.     {   
  42.         if( t )   
  43.         {   
  44.             delete t;   
  45.             t = 0;   
  46.         }   
  47.     }   
  48.   
  49.     const D3DXCOLOR      WHITE( D3DCOLOR_XRGB(255, 255, 255) );   
  50.     const D3DXCOLOR      BLACK( D3DCOLOR_XRGB(  0,   0,   0) );   
  51.     const D3DXCOLOR        RED( D3DCOLOR_XRGB(255,   0,   0) );   
  52.     const D3DXCOLOR      GREEN( D3DCOLOR_XRGB(  0, 255,   0) );   
  53.     const D3DXCOLOR       BLUE( D3DCOLOR_XRGB(  0,   0, 255) );   
  54.     const D3DXCOLOR     YELLOW( D3DCOLOR_XRGB(255, 255,   0) );   
  55.     const D3DXCOLOR       CYAN( D3DCOLOR_XRGB(  0, 255, 255) );   
  56.     const D3DXCOLOR    MAGENTA( D3DCOLOR_XRGB(255,   0, 255) );   
  57.   
  58.     //   
  59.     // Lights   
  60.     //   
  61.   
  62.     D3DLIGHT9 InitDirectionalLight(D3DXVECTOR3* direction, D3DXCOLOR* color);   
  63.     D3DLIGHT9 InitPointLight(D3DXVECTOR3* position, D3DXCOLOR* color);   
  64.     D3DLIGHT9 InitSpotLight(D3DXVECTOR3* position, D3DXVECTOR3* direction, D3DXCOLOR* color);   
  65.   
  66.     //   
  67.     // Materials   
  68.     //   
  69.   
  70.     D3DMATERIAL9 InitMtrl(D3DXCOLOR a, D3DXCOLOR d, D3DXCOLOR s, D3DXCOLOR e, float p);   
  71.   
  72.     const D3DMATERIAL9 WHITE_MTRL  = InitMtrl(WHITE, WHITE, WHITE, BLACK, 2.0f);   
  73.     const D3DMATERIAL9 RED_MTRL    = InitMtrl(RED, RED, RED, BLACK, 2.0f);   
  74.     const D3DMATERIAL9 GREEN_MTRL  = InitMtrl(GREEN, GREEN, GREEN, BLACK, 2.0f);   
  75.     const D3DMATERIAL9 BLUE_MTRL   = InitMtrl(BLUE, BLUE, BLUE, BLACK, 2.0f);   
  76.     const D3DMATERIAL9 YELLOW_MTRL = InitMtrl(YELLOW, YELLOW, YELLOW, BLACK, 2.0f);   
  77. }  


d3dUtility.cpp

Code:
  1.   
  2. #include "d3dutility.h"   
  3.   
  4. bool d3d::InitD3D(HINSTANCE hInstance,    
  5.                   int width,   
  6.                   int height,    
  7.                   bool windowed,    
  8.                   D3DDEVTYPE deviceType,    
  9.                   IDirect3DDevice9 ** device)   
  10. {   
  11.     //创建应用程序主窗口   
  12.     WNDCLASS wc;   
  13.     wc.style         = CS_HREDRAW | CS_VREDRAW;   
  14.     wc.lpfnWndProc   = (WNDPROC)d3d::WndProc;    
  15.     wc.cbClsExtra    = 0;   
  16.     wc.cbWndExtra    = 0;   
  17.     wc.hInstance     = hInstance;   
  18.     wc.hIcon         = LoadIcon(0, IDI_APPLICATION);   
  19.     wc.hCursor       = LoadCursor(0, IDC_ARROW);   
  20.     wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);   
  21.     wc.lpszMenuName  = 0;   
  22.     wc.lpszClassName = _T("Direct3D9App");   
  23.   
  24.     if (!RegisterClass(&wc))   
  25.     {   
  26.         ::MessageBox(0,_T("RegisterClass() ---error"),0,0);   
  27.         return false;   
  28.     }   
  29.   
  30.     HWND hwnd = 0;   
  31.     hwnd = ::CreateWindow(_T("Direct3D9App"), _T("Direct3D9App"),    
  32.         WS_EX_TOPMOST,   
  33.         0, 0, width, height,   
  34.         0 /*parent hwnd*/, 0 /* menu */, hInstance, 0 /*extra*/);    
  35.     if (!hwnd)   
  36.     {   
  37.         ::MessageBox(0,_T("CreateWindow()--error"),0,0);   
  38.         return false;   
  39.     }   
  40.     ::ShowWindow(hwnd,SW_SHOW);   
  41.     ::UpdateWindow(hwnd);   
  42.   
  43.     //初始化 D3D   
  44.     HRESULT hr  = 0;   
  45.     //创建IDirect3D9 对象   
  46.     IDirect3D9 *d3d9 = 0;   
  47.     d3d9 =  Direct3DCreate9(D3D_SDK_VERSION);   
  48.     if (!d3d9)   
  49.     {   
  50.         ::MessageBox(0,_T("error"),0,0);   
  51.         return false;   
  52.     }   
  53.        
  54.     // 检测硬件支持   
  55.     D3DCAPS9 caps ;   
  56.     d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT,deviceType,&caps);   
  57.   
  58.     int vp= 0;   
  59.     if (caps.DeviceType & D3DDEVCAPS_HWTRANSFORMANDLIGHT)   
  60.     {   
  61.         vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;   
  62.     }   
  63.     else  
  64.     {   
  65.         vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;   
  66.     }   
  67.   
  68.     // 填充D3DPRESENT_PARAMETERS  struct   
  69.     D3DPRESENT_PARAMETERS d3dpp;   
  70.     d3dpp.BackBufferWidth            = width;   
  71.     d3dpp.BackBufferHeight           = height;   
  72.     d3dpp.BackBufferFormat           = D3DFMT_A8R8G8B8;   
  73.     d3dpp.BackBufferCount            = 1;   
  74.     d3dpp.MultiSampleType            = D3DMULTISAMPLE_NONE;   
  75.     d3dpp.MultiSampleQuality         = 0;   
  76.     d3dpp.SwapEffect                 = D3DSWAPEFFECT_DISCARD;    
  77.     d3dpp.hDeviceWindow              = hwnd;   
  78.     d3dpp.Windowed                   = windowed;   
  79.     d3dpp.EnableAutoDepthStencil     = true;    
  80.     d3dpp.AutoDepthStencilFormat     = D3DFMT_D24S8;   
  81.     d3dpp.Flags                      = 0;   
  82.     d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;   
  83.     d3dpp.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE;   
  84.   
  85.     //创建设备   
  86.   
  87.     hr = d3d9->CreateDevice(   
  88.         D3DADAPTER_DEFAULT, // primary adapter   
  89.         deviceType,         // device type   
  90.         hwnd,               // window associated with device   
  91.         vp,                 // vertex processing   
  92.         &d3dpp,             // present parameters   
  93.         device);     
  94.     if( FAILED(hr) )   
  95.     {   
  96.         // try again using a 16-bit depth buffer   
  97.         d3dpp.AutoDepthStencilFormat = D3DFMT_D16;   
  98.   
  99.         hr = d3d9->CreateDevice(   
  100.             D3DADAPTER_DEFAULT,   
  101.             deviceType,   
  102.             hwnd,   
  103.             vp,   
  104.             &d3dpp,   
  105.             device);   
  106.   
  107.         if( FAILED(hr) )   
  108.         {   
  109.             d3d9->Release(); // done with d3d9 object   
  110.             ::MessageBox(0, _T("CreateDevice() - FAILED"), 0, 0);   
  111.             return false;   
  112.         }   
  113.     }   
  114.   
  115.     d3d9->Release(); // done with d3d9 object   
  116.   
  117.     return true;   
  118.   
  119. }   
  120.   
  121. int d3d::EnterMsgLoop( bool (*ptr_display)(float timeDelta) )   
  122. {   
  123.     MSG msg;   
  124.     ::ZeroMemory(&msg, sizeof(MSG));   
  125.   
  126.     static float lastTime = (float)timeGetTime();    
  127.   
  128.     while(msg.message != WM_QUIT)   
  129.     {   
  130.         if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))   
  131.         {   
  132.             ::TranslateMessage(&msg);   
  133.             ::DispatchMessage(&msg);   
  134.         }   
  135.         else  
  136.         {      
  137.             float currTime  = (float)timeGetTime();   
  138.             float timeDelta = (currTime - lastTime)*0.001f;   
  139.   
  140.             ptr_display(timeDelta);   
  141.   
  142.             lastTime = currTime;   
  143.         }   
  144.     }   
  145.     return msg.wParam;   
  146. }   
  147.   
  148. D3DLIGHT9 d3d::InitDirectionalLight(D3DXVECTOR3* direction ,D3DXCOLOR* color)   
  149. {   
  150.     D3DLIGHT9 light;   
  151.     ::ZeroMemory(&light,sizeof(light));   
  152.   
  153.     light.Type = D3DLIGHT_DIRECTIONAL;   
  154.     light.Ambient = *color*0.6f;   
  155.     light.Diffuse = *color;   
  156.     light.Specular = *color*0.0f;   
  157.     light.Direction = *direction;   
  158.   
  159.     return light;   
  160. }   
  161.   
  162. D3DLIGHT9 d3d::InitPointLight(D3DXVECTOR3* position ,D3DXCOLOR* color)   
  163. {   
  164.     D3DLIGHT9 light;   
  165.     ::ZeroMemory(&light,sizeof(light));   
  166.   
  167.     light.Type = D3DLIGHT_POINT;   
  168.     light.Ambient = *color*0.6f;   
  169.     light.Diffuse = *color;   
  170.     light.Specular = *color*0.6f;   
  171.     light.Position = *position;   
  172.     light.Range = 1000.0f;   
  173.     light.Falloff = 1.0f;   
  174.     light.Attenuation0 =1.0f;   
  175.     light.Attenuation1 = 0.0f;   
  176.     light.Attenuation2 = 0.0f;   
  177.   
  178.     return light;   
  179. }   
  180. D3DLIGHT9 d3d::InitSpotLight(D3DXVECTOR3* position, D3DXVECTOR3* direction, D3DXCOLOR* color)   
  181. {   
  182.     D3DLIGHT9 light;   
  183.     ::ZeroMemory(&light, sizeof(light));   
  184.   
  185.     light.Type      = D3DLIGHT_SPOT;   
  186.     light.Ambient   = *color * 0.0f;   
  187.     light.Diffuse   = *color;   
  188.     light.Specular  = *color * 0.6f;   
  189.     light.Position  = *position;   
  190.     light.Direction = *direction;   
  191.     light.Range        = 1000.0f;   
  192.     light.Falloff      = 1.0f;   
  193.     light.Attenuation0 = 1.0f;   
  194.     light.Attenuation1 = 0.0f;   
  195.     light.Attenuation2 = 0.0f;   
  196.     light.Theta        = 0.4f;   
  197.     light.Phi          = 0.9f;   
  198.   
  199.     return light;   
  200. }   
  201.   
  202. D3DMATERIAL9 d3d::InitMtrl(D3DXCOLOR a, D3DXCOLOR d, D3DXCOLOR s, D3DXCOLOR e, float p)   
  203. {   
  204.     D3DMATERIAL9 mtrl;   
  205.     mtrl.Ambient  = a;   
  206.     mtrl.Diffuse  = d;   
  207.     mtrl.Specular = s;   
  208.     mtrl.Emissive = e;   
  209.     mtrl.Power    = p;   
  210.     return mtrl;   
  211. }  

原创粉丝点击