D3D中的 模板缓冲区 (c++源码)

                                 D3D中的 模板缓冲区

自己感觉自开始学习 D3D以来,D3D中的模板缓冲区技术 最难理解得了,

到现在自己还不敢说自己对模板缓冲区很理解,他的工作机制,以及如何创

模板缓冲区,还不是很了解。自己从加载纹理文件,到设置模板缓冲区,

费了好久才把它调试通过。

首先来看看工程结构:

运行效果为:

(注意只有在镜子前面的才会在镜子中成像)

前两个文件:

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. }  

stencilmirror.cpp 主要包括 渲染 镜子,茶壶,设置模板缓冲区。

Code:
  1. #include "d3dUtility.h"   
  2.   
  3. //   
  4. //  Globals   
  5. //   
  6.   
  7. IDirect3DDevice9* Device = 0;   
  8.   
  9. const int Width  =  640;   
  10. const int Height = 480;   
  11.   
  12. IDirect3DVertexBuffer9* VB = 0;   
  13.   
  14. IDirect3DTexture9*  FloorTex = 0;   
  15. IDirect3DTexture9* WallTex = 0;   
  16. IDirect3DTexture9 *MirrorTex = 0;   
  17.   
  18. D3DMATERIAL9 FloorMtrl = d3d::WHITE_MTRL;   
  19. D3DMATERIAL9 WallMtrl = d3d::WHITE_MTRL;   
  20. D3DMATERIAL9 MirrorMtrl = d3d::WHITE_MTRL;   
  21.   
  22. ID3DXMesh* Teapot = 0;   
  23. D3DXVECTOR3 TeapotPosition(0.0f,3.0f,-7.5f);   
  24. D3DMATERIAL9 TeapotMtrl = d3d::YELLOW_MTRL;   
  25.   
  26. void RenderScene();   
  27. void RenderMirror();   
  28.   
  29. /*  
  30.   Classes  and structures  
  31. */  
  32.   
  33. //定义Vertex 类型   
  34.   
  35. struct  Vertex   
  36. {   
  37.     Vertex(){}   
  38.   
  39.     Vertex(float x,float y,float z,   
  40.         float nx,float ny,float nz ,float u,float v)   
  41.     {   
  42.         _x = x ; _y = y ;_z= z;   
  43.         _nx = nx;_ny = ny; _nz = nz;   
  44.         _u = u; _v = v;   
  45.     }   
  46.     float _x,_y,_z;   
  47.     float _nx,_ny,_nz;   
  48.     float _u,_v;   
  49.   
  50.     static const DWORD FVF;   
  51. };   
  52. const DWORD Vertex::FVF =D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1;   
  53.   
  54. //   
  55. //  Framework Functions   
  56. //   
  57.   
  58. bool Setup()   
  59. {   
  60.     WallMtrl.Specular = d3d::WHITE*0.2f;   
  61.     //   
  62.     //Create the teapot   
  63.     //   
  64.   
  65.     D3DXCreateTeapot(Device,&Teapot,0);   
  66.   
  67.     Device->CreateVertexBuffer(   
  68.         24*sizeof(Vertex),   
  69.         D3DUSAGE_WRITEONLY,   
  70.         Vertex::FVF,   
  71.         D3DPOOL_MANAGED,   
  72.         &VB,   
  73.         0);   
  74.     //用Quad 数据填充vertex buffer   
  75.   
  76.     Vertex*  v = 0;   
  77.     VB->Lock(0,0,(void**)&v,0);   
  78.     // floor地面 UV都是在[0,1]之间   
  79.     v[0] = Vertex(-7.5f, 0.0f, -10.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f);   
  80.     v[1] = Vertex(-7.5f, 0.0f,   0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f);   
  81.     v[2] = Vertex( 7.5f, 0.0f,   0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f);   
  82.   
  83.     v[3] = Vertex(-7.5f, 0.0f, -10.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f);   
  84.     v[4] = Vertex( 7.5f, 0.0f,   0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f);   
  85.     v[5] = Vertex( 7.5f, 0.0f, -10.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f);   
  86.   
  87.     // wall墙体   
  88.     v[6]  = Vertex(-7.5f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f);   
  89.     v[7]  = Vertex(-7.5f, 5.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f);   
  90.     v[8]  = Vertex(-2.5f, 5.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f);   
  91.   
  92.     v[9]  = Vertex(-7.5f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f);   
  93.     v[10] = Vertex(-2.5f, 5.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f);   
  94.     v[11] = Vertex(-2.5f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f);   
  95.   
  96.     // 在墙体哈镜子之间留一些空隙   
  97.   
  98.     v[12] = Vertex(2.5f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f);   
  99.     v[13] = Vertex(2.5f, 5.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f);   
  100.     v[14] = Vertex(7.5f, 5.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f);   
  101.   
  102.     v[15] = Vertex(2.5f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f);   
  103.     v[16] = Vertex(7.5f, 5.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f);   
  104.     v[17] = Vertex(7.5f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f);   
  105.   
  106.     // mirror 镜子   
  107.     v[18] = Vertex(-2.5f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f);   
  108.     v[19] = Vertex(-2.5f, 5.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f);   
  109.     v[20] = Vertex( 2.5f, 5.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f);   
  110.   
  111.     v[21] = Vertex(-2.5f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f);   
  112.     v[22] = Vertex( 2.5f, 5.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f);   
  113.     v[23] = Vertex( 2.5f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f);       
  114.        
  115.     VB ->Unlock();   
  116.   
  117.     D3DXCreateTextureFromFile( //加载纹理:草   
  118.         Device,   
  119.         _T("grass.bmp"),   
  120.         &FloorTex);   
  121.     D3DXCreateTextureFromFile( //加载纹理:墙   
  122.         Device,   
  123.         _T("brick0.jpg"),   
  124.         &WallTex);   
  125.     D3DXCreateTextureFromFile( //加载纹理:镜面   
  126.         Device,   
  127.         _T("ice.bmp"),   
  128.         &MirrorTex);   
  129.   
  130.   
  131.   
  132.     Device->SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_ANISOTROPIC/*D3DTEXF_LINEAR*/);   
  133.     Device->SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_ANISOTROPIC/*D3DTEXF_LINEAR*/);   
  134.     Device->SetSamplerState(0,D3DSAMP_MIPFILTER,D3DTEXF_ANISOTROPIC);   
  135.        
  136.   
  137.     //设置,开放 灯光,使用灯光   
  138.     D3DXVECTOR3 lightDir(0.707f,-0.707f,0.707f);   
  139.     D3DXCOLOR color(1.0f,1.0f,1.0f,1.0f);   
  140.     D3DLIGHT9 light = d3d::InitDirectionalLight(&lightDir,&color);   
  141.   
  142.     Device->SetLight(0,&light);   
  143.     Device->LightEnable(0,true);   
  144.   
  145.     //设置渲染状态,重新计算法线方向,打开镜面光   
  146.     Device->SetRenderState(D3DRS_NORMALIZENORMALS,true);   
  147.     Device->SetRenderState(D3DRS_SPECULARENABLE,true);   
  148.        
  149.     //设置照相机   
  150.     D3DXVECTOR3 pos(-10.0f,3.0f,-15.0f);   
  151.     D3DXVECTOR3 target(0.0f,0.0f,0.0f);   
  152.     D3DXVECTOR3 up(0.0f,1.0f,0.0f);   
  153.     D3DXMATRIX  V;   
  154.     D3DXMatrixLookAtLH(&V,&pos,&target,&up);   
  155.     Device->SetTransform(D3DTS_VIEW,&V);   
  156.   
  157.     //设置投影矩阵   
  158.     D3DXMATRIX proj;   
  159.     D3DXMatrixPerspectiveFovLH(   
  160.         &proj,   
  161.         D3DX_PI /4.0f,   
  162.         (float)Width/(float)Height,   
  163.         1.0f,   
  164.         1000.0f);   
  165.     Device->SetTransform(D3DTS_PROJECTION,&proj);   
  166.   
  167.   
  168.     return true;   
  169. }   
  170.   
  171. void Cleanup()   
  172. {   
  173.     //清理创建的buffer   
  174.     d3d::Release<IDirect3DVertexBuffer9* >(VB);   
  175.     d3d::Release<IDirect3DTexture9*>(FloorTex);   
  176.     d3d::Release<IDirect3DTexture9*>(WallTex);   
  177.     d3d::Release<IDirect3DTexture9*>(MirrorTex);   
  178.     d3d::Release<ID3DXMesh*>(Teapot);   
  179. }   
  180.   
  181. bool Display(float timeDelta)   
  182. {   
  183.     if (Device)   
  184.     {   
  185.         //接收用户输入 更新场景   
  186.         static float radius = 20.0f;   
  187.         if (::GetAsyncKeyState(VK_LEFT)&0x8000f)   
  188.         {   
  189.             TeapotPosition.x -=3.0f*timeDelta;   
  190.         }   
  191.         if (::GetAsyncKeyState(VK_RIGHT)&0x8000f)   
  192.         {   
  193.             TeapotPosition.x +=3.0f*timeDelta;   
  194.         }   
  195.         if(::GetAsyncKeyState(VK_UP)& 0x8000f)   
  196.         {   
  197.             radius -=2.0f*timeDelta;   
  198.         }   
  199.         if (::GetAsyncKeyState(VK_DOWN)&0x8000)   
  200.         {   
  201.             radius +=2.0f*timeDelta;   
  202.         }   
  203.   
  204.         static float angle = (3.0f*D3DX_PI)/2.0f;   
  205.   
  206.         if (::GetAsyncKeyState('A')&0x8000f)   
  207.         {   
  208.             angle -=0.5f * timeDelta;   
  209.         }   
  210.   
  211.         if(::GetAsyncKeyState('S')&0x8000)   
  212.         {   
  213.             angle +=0.5f * timeDelta;   
  214.         }   
  215.   
  216.         D3DXVECTOR3 position(cosf(angle)*radius,3.0f,sinf(angle)*radius);   
  217.   
  218.         D3DXVECTOR3 target(0.0f,0.0f,0.0f);   
  219.   
  220.         D3DXVECTOR3 up(0.0f,1.0f,0.0f);   
  221.         D3DXMATRIX V;   
  222.   
  223.         D3DXMatrixLookAtLH(&V,&position,&target,&up);   
  224.   
  225.         Device->SetTransform(D3DTS_VIEW,&V);   
  226.   
  227.         Device->Clear(0, 0, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER|D3DCLEAR_STENCIL,   
  228.                 0x00000000,1.0f,0);   
  229.   
  230.         Device->BeginScene();   
  231.   
  232.         RenderScene();   
  233.         RenderMirror();   
  234.   
  235.         Device->EndScene();   
  236.         Device->Present(0,0,0,0);   
  237.     }   
  238.   
  239.     return true;   
  240. }   
  241.   
  242. void RenderScene()   
  243. {   
  244.     //  画茶壶   
  245.     Device->SetMaterial(&TeapotMtrl);   
  246.     Device->SetTexture(0, 0);   
  247.     D3DXMATRIX W;   
  248.     D3DXMatrixTranslation(&W,   
  249.         TeapotPosition.x,    
  250.         TeapotPosition.y,   
  251.         TeapotPosition.z);   
  252.   
  253.     Device->SetTransform(D3DTS_WORLD, &W);   
  254.     Teapot->DrawSubset(0);   
  255.   
  256.     D3DXMATRIX I;   
  257.     D3DXMatrixIdentity(&I);   
  258.     Device->SetTransform(D3DTS_WORLD, &I);   
  259.   
  260.     Device->SetStreamSource(0, VB, 0, sizeof(Vertex));   
  261.     Device->SetFVF(Vertex::FVF);   
  262.   
  263.     //  画地板   
  264.     Device->SetMaterial(&FloorMtrl);   
  265.     Device->SetTexture(0, FloorTex);   
  266.     Device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);   
  267.   
  268.     // 画墙体   
  269.     Device->SetMaterial(&WallMtrl);   
  270.     Device->SetTexture(0, WallTex);   
  271.     Device->DrawPrimitive(D3DPT_TRIANGLELIST, 6, 4);   
  272.   
  273.     // 画镜子   
  274.     Device->SetMaterial(&MirrorMtrl);   
  275.     Device->SetTexture(0, MirrorTex);   
  276.     Device->DrawPrimitive(D3DPT_TRIANGLELIST, 18, 2);   
  277. }      
  278.   
  279.   
  280. void RenderMirror()   
  281. {   
  282.     //渲染 镜子   
  283.   
  284.     Device->SetRenderState(D3DRS_STENCILENABLE,    true);//开启模板缓冲区   
  285.     Device->SetRenderState(D3DRS_STENCILFUNC,      D3DCMP_ALWAYS); //模板测试为 肯定通过   
  286.     Device->SetRenderState(D3DRS_STENCILREF,       0x1); //模板参考值 为1   
  287.     Device->SetRenderState(D3DRS_STENCILMASK,      0xffffffff);//模板掩码:用于设置模板参考值与模板缓冲区值value进行屏蔽操作   
  288.     Device->SetRenderState(D3DRS_STENCILWRITEMASK, 0xffffffff);   
  289.     Device->SetRenderState(D3DRS_STENCILZFAIL,     D3DSTENCILOP_KEEP);//不更改模板缓冲区的值   
  290.     Device->SetRenderState(D3DRS_STENCILFAIL,      D3DSTENCILOP_KEEP);   
  291.     Device->SetRenderState(D3DRS_STENCILPASS,      D3DSTENCILOP_REPLACE);//用模板缓冲区中的值代替原模板缓冲区的值   
  292.   
  293.     // 禁用向模板 深度(Z)缓冲区进行写   
  294.     Device->SetRenderState(D3DRS_ZWRITEENABLE, false);   
  295.     Device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);   
  296.   
  297.     //设置 原混合因子和 目标混合因子   
  298.     Device->SetRenderState(D3DRS_SRCBLEND,  D3DBLEND_ZERO);   
  299.     Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);   
  300.   
  301.     //  将镜子写入到模板缓冲区中   
  302.     Device->SetStreamSource(0, VB, 0, sizeof(Vertex));   
  303.     Device->SetFVF(Vertex::FVF);   
  304.     Device->SetMaterial(&MirrorMtrl);   
  305.     Device->SetTexture(0, MirrorTex);   
  306.     D3DXMATRIX I;   
  307.     D3DXMatrixIdentity(&I);   
  308.     Device->SetTransform(D3DTS_WORLD, &I);   
  309.     Device->DrawPrimitive(D3DPT_TRIANGLELIST, 18, 2);   
  310.   
  311.     //  开启深度 (Z)缓冲区进行写   
  312.     Device->SetRenderState( D3DRS_ZWRITEENABLE, true );   
  313.   
  314.     // only draw reflected teapot to the pixels where the mirror   
  315.     // was drawn to.当且仅当映射出 茶壶像素在镜子前的镜像   
  316.     Device->SetRenderState(D3DRS_STENCILFUNC,  D3DCMP_EQUAL);   
  317.     Device->SetRenderState(D3DRS_STENCILPASS,  D3DSTENCILOP_KEEP);   
  318.   
  319.     // position reflection   
  320.     D3DXMATRIX W, T, R;   
  321.     D3DXPLANE plane(0.0f, 0.0f, 1.0f, 0.0f); //xy平面   
  322.     D3DXMatrixReflect(&R, &plane);   
  323.   
  324.     D3DXMatrixTranslation(&T,   
  325.         TeapotPosition.x,    
  326.         TeapotPosition.y,   
  327.         TeapotPosition.z);    
  328.   
  329.     W = T * R;   
  330.   
  331.     //清空深度缓冲区,并且在镜子中投影茶壶   
  332.     Device->Clear(0, 0, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);   
  333.     Device->SetRenderState(D3DRS_SRCBLEND,  D3DBLEND_DESTCOLOR);   
  334.     Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);   
  335.   
  336.     // 最后绘制 茶壶在镜子中的镜像   
  337.     Device->SetTransform(D3DTS_WORLD, &W);   
  338.     Device->SetMaterial(&TeapotMtrl);   
  339.     Device->SetTexture(0, 0);   
  340.   
  341.     Device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);   
  342.     Teapot->DrawSubset(0);   
  343.   
  344.     // 存储渲染状态   
  345.     Device->SetRenderState(D3DRS_ALPHABLENDENABLE, false);   
  346.     Device->SetRenderState( D3DRS_STENCILENABLE, false);   
  347.     Device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);   
  348. }   
  349.   
  350.   
  351. //回调函数   
  352.   
  353. LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)   
  354. {   
  355.     switch( msg )   
  356.     {   
  357.     case WM_DESTROY:   
  358.         ::PostQuitMessage(0);   
  359.         break;   
  360.   
  361.     case WM_KEYDOWN:   
  362.         if( wParam == VK_ESCAPE )   
  363.             ::DestroyWindow(hwnd);   
  364.         break;   
  365.     }   
  366.     return ::DefWindowProc(hwnd, msg, wParam, lParam);   
  367. }   
  368.   
  369.   
  370. //   
  371. // 主函数   
  372. //   
  373. int WINAPI WinMain(HINSTANCE hinstance,   
  374.                    HINSTANCE prevInstance,    
  375.                    PSTR cmdLine,   
  376.                    int showCmd)   
  377. {   
  378.     if(!d3d::InitD3D(hinstance,   
  379.         Width, Height, true, D3DDEVTYPE_HAL, &Device))   
  380.     {   
  381.         ::MessageBox(0, _T("InitD3D() - FAILED"), 0, 0);   
  382.         return 0;   
  383.     }   
  384.   
  385.     if(!Setup())   
  386.     {   
  387.         ::MessageBox(0, _T("Setup() - FAILED"), 0, 0);   
  388.         return 0;   
  389.     }   
  390.   
  391.     d3d::EnterMsgLoop( Display );   
  392.   
  393.     Cleanup();   
  394.   
  395.     Device->Release();   
  396.   
  397.     return 0;   
  398. }  

欢迎大家跟帖说说 模板缓冲区的理解^---^

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值