天天看點

Direct3D中繪制立方體

索引緩存

一個索引緩存是一塊連續的存儲了索引資料的記憶體。

Direct3D中繪制立方體

Length 配置設定給緩存的位元組大小。假如想得到一個能存儲3個頂點的頂點緩存,那麼我們就要在頂點結構中設定這個參數為3 * sizeof ( Vertex ) 。

Usage 指定關于怎樣使用緩存的額外資訊,可以為0,也可為一下幾個參數的一個或多個組合:

D3DUSAGE_DYNAMIC——設定這個參數可以使緩存是動态的。在下一頁說明靜态和動态緩存。

D3DUSAGE_POINTS——這個參數指定緩存存儲原始點。原始點将在第14章粒子系統中介紹。這個參數僅僅用在頂點緩沖中。

D3DUSAGE_SOFTWAREPROCESSING——使用軟體頂點處理。

D3DUSAGE_WRITEONLY——指定應用程式隻能寫緩存。它允許驅動程式配置設定最适合的記憶體位址作為寫緩存。注意如果從建立好的這種緩存中讀資料,将會傳回錯誤資訊。

FVF 存儲在緩存中的頂點格式。

Pool 緩存放置在哪一個記憶體池中。

ppIndexBuffer 傳回建立好的索引緩存的指針。

pShareHandle  目前沒有使用,一般傳NULL。

通路索引緩存

為了通路索引緩存,我們需要得到一個指針,是以我們需要使用IDirect3DIndexBuffer9::Lock與IDirect3DIndexBuffer9:: Unlock。

Direct3D中繪制立方體

OffsetToLock 偏移量,以位元組為機關,從緩存開始位置到鎖定開始位置的距離。

SizeToLock 鎖定的位元組數。

Flags 标記描述怎樣鎖定記憶體。它可能是0 或者是下面參數中的1 個或多個的組合:

D3DLOCK_DISCARD——這個參數僅僅會在動态緩存時被使用。它訓示硬體丢棄緩存并傳回一個指向新配置設定的緩存的指針。這是很有用,因為當我們存取一個新配置設定的緩存時它允許硬體繼續從丢棄的緩存渲染。這防止了硬體延遲。

D3DLOCK_NOO VERWRITE——這個參數僅僅會在動态緩存時被使用。它聲明你将向緩存中添加資料。即,你不能向已經渲染的記憶體中寫資料。這是有好處的因為他允許你在添加新資料到緩存的同時讓硬體繼續渲染。

D3DLOCK_READONLY——這個參數聲明你鎖定的緩存隻能從中讀取資料而不能寫資料。這允許一些内在的優化。

視圖變換

把實體從世界空間轉換到視角空間,這個坐标變換被稱為視圖變換(View Transformation)。

Direct3D中繪制立方體

pOut 指向傳回的視圖矩陣。

pEye 照相機在世界坐标系的位置。

pAt  照相機在世界坐标系的目标點。

pUp  世界坐标系的上方向。

繪制圖元(使用索引資訊)

Direct3D中繪制立方體

    Type 我們繪制的圖元類型。比如,我們能繪制點和線以及三角形。以後我們使用三角形用D3DPT_TRIANGLELIST參數。

    BaseVertexIndex 一個基本數字,在調用中用它去加上索引。參看下面的說明。

    MinIndex 将被引用的最小索引值。

    NumVertices 在此調用中将被引用的頂點數。

    StartIndex 索引到索引緩存中的某個位置,它标記開始渲染的開始索引點。

    PrimitiveCount 繪制圖元的個數。

  1. #include <d3dx9.h> 
  2. #include <string.h> 
  3. #include <Windows.h> 
  4. #define WINDOWNAME TEXT("D3DGameFrame") 
  5. #define WINDOWCLASS TEXT("The GameFrame of Dull") 
  6. #define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0) 
  7. #define KEYUP(vk_code)   ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1) 
  8. const int Width  = 640; 
  9. const int Height = 480; 
  10. HWND      mainWindowHandle = NULL;  
  11. HINSTANCE hinstanceApp     = NULL;  
  12. bool      ESC              = true; 
  13. IDirect3DDevice9* Device = NULL;  
  14. IDirect3D9* d3d9 = NULL; 
  15. HRESULT hr = NULL; 
  16. IDirect3DVertexBuffer9* VB = NULL; 
  17. IDirect3DIndexBuffer9*  IB = NULL; 
  18. struct Vertex 
  19.     float x,y,z; 
  20. }; 
  21. #define D3DFVF (D3DFVF_XYZ) 
  22. LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) 
  23.     PAINTSTRUCT     ps;  
  24.     HDC             hdc;     
  25.     switch( msg ) 
  26.     { 
  27.         case WM_PAINT:  
  28.             { 
  29.                 hdc = BeginPaint(hWnd,&ps);   
  30.                 EndPaint(hWnd,&ps); 
  31.             }  
  32.             break; 
  33.         case WM_DESTROY: 
  34.             { 
  35.                 ::PostQuitMessage(0); 
  36.             }            
  37.             break;       
  38.     } 
  39.     return ::DefWindowProc(hWnd, msg, wParam, lParam); 
  40. int GameInit(void *parms = NULL, int num_parms = 0) 
  41.     ESC = false; 
  42.     Device->CreateVertexBuffer(8*sizeof(Vertex),D3DUSAGE_WRITEONLY,D3DFVF,D3DPOOL_MANAGED,&VB,NULL); 
  43.     Device->CreateIndexBuffer(36*sizeof(WORD),D3DUSAGE_WRITEONLY,D3DFMT_INDEX16,D3DPOOL_MANAGED,&IB,NULL); 
  44.     Vertex Vertices[8] =  
  45.     { 
  46.         {-1.0f, -1.0f, -1.0f}, 
  47.         {-1.0f,  1.0f, -1.0f}, 
  48.         { 1.0f,  1.0f, -1.0f}, 
  49.         { 1.0f, -1.0f, -1.0f}, 
  50.         {-1.0f, -1.0f,  1.0f}, 
  51.         {-1.0f,  1.0f,  1.0f}, 
  52.         { 1.0f,  1.0f,  1.0f}, 
  53.         { 1.0f, -1.0f,  1.0f} 
  54.     }; 
  55.     void* pVertices;  
  56.     VB->Lock(0,0,(void**)&pVertices,NULL); 
  57.     memcpy(pVertices,Vertices,sizeof(Vertices)); 
  58.     VB->Unlock(); 
  59.     WORD* pIndices = NULL; 
  60.     IB->Lock(0,0,(void**)&pIndices,NULL); 
  61.     // 前面 
  62.     pIndices[0]  = 0; pIndices[1]  = 1; pIndices[2]  = 2; 
  63.     pIndices[3]  = 0; pIndices[4]  = 2; pIndices[5]  = 3; 
  64.     //後面 
  65.     pIndices[6]  = 4; pIndices[7]  = 6; pIndices[8]  = 5; 
  66.     pIndices[9]  = 4; pIndices[10] = 7; pIndices[11] = 6; 
  67.     //左面 
  68.     pIndices[12] = 4; pIndices[13] = 5; pIndices[14] = 1; 
  69.     pIndices[15] = 4; pIndices[16] = 1; pIndices[17] = 0; 
  70.     //右面 
  71.     pIndices[18] = 3; pIndices[19] = 2; pIndices[20] = 6; 
  72.     pIndices[21] = 3; pIndices[22] = 6; pIndices[23] = 7; 
  73.     //上面 
  74.     pIndices[24] = 1; pIndices[25] = 5; pIndices[26] = 6; 
  75.     pIndices[27] = 1; pIndices[28] = 6; pIndices[29] = 2; 
  76.     //下面 
  77.     pIndices[30] = 4; pIndices[31] = 0; pIndices[32] = 3; 
  78.     pIndices[33] = 4; pIndices[34] = 3; pIndices[35] = 7; 
  79.     IB->Unlock(); 
  80.     //TODO:視圖變換 
  81.     D3DXMATRIX out; 
  82.     D3DXVECTOR3 eye(0.0f,0.0f,-5.0f); 
  83.     D3DXVECTOR3 at(0.0f,0.0f,0.0f); 
  84.     D3DXVECTOR3 up(0.0f,1.0f,0.0f); 
  85.     D3DXMatrixLookAtLH(&out,&eye,&at,&up); 
  86.     Device->SetTransform(D3DTS_VIEW, &out); 
  87.     //TODO:投影變換 
  88.     D3DXMATRIX proj; 
  89.     D3DXMatrixPerspectiveFovLH(&proj,D3DX_PI*0.5f,(float)Width/(float)Height,1.0f,1000.0f); 
  90.     Device->SetTransform(D3DTS_PROJECTION,&proj); 
  91.     //TODO:設定渲染狀态 
  92.     Device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); 
  93.     return 1; 
  94. }  
  95. int GameMain(void *parms = NULL, int num_parms = 0) 
  96.     if(ESC) return 0; 
  97. //==========此處目前不必關心,隻知道是旋轉圖形即可==============      
  98.     D3DXMATRIX Rx, Ry;                           
  99.     D3DXMatrixRotationX(&Rx, 3.14f / 4.0f);      
  100.     static float y = 0.0f; 
  101.     D3DXMatrixRotationY(&Ry, y); 
  102.     y += 0.0001f; 
  103.     if( y >= 6.28f ) 
  104.         y = 0.0f; 
  105.     D3DXMATRIX p = Rx * Ry; 
  106.     Device->SetTransform(D3DTS_WORLD, &p); 
  107. //=========================================================
  108.     Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f , 0); 
  109.     //TODO:繪制圖形 
  110.     Device->BeginScene(); 
  111.     Device->SetStreamSource( 0 , VB , 0 , sizeof(Vertex) ); 
  112.     Device->SetIndices(IB); 
  113.     Device->SetFVF(D3DFVF); 
  114.     Device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 8, 0, 12); 
  115.     Device->EndScene(); 
  116.     Device->Present(NULL,NULL,NULL,NULL); 
  117.     if (KEYDOWN(VK_ESCAPE)) 
  118.     { 
  119.         ESC = true; 
  120.         SendMessage(mainWindowHandle,WM_CLOSE,0,0); 
  121.     } 
  122.     return 1; 
  123. }  
  124. int GameShutdown(void *parms = NULL, int num_parms = 0) 
  125.     if( NULL != IB) 
  126.     { 
  127.         IB->Release(); 
  128.         IB = NULL; 
  129.     } 
  130.     if( NULL != VB) 
  131.     { 
  132.         VB->Release(); 
  133.         VB = NULL; 
  134.     } 
  135.     if( NULL != d3d9) 
  136.     { 
  137.         d3d9->Release(); 
  138.         d3d9 = NULL; 
  139.     } 
  140.     if( NULL != Device) 
  141.     { 
  142.         Device->Release(); 
  143.         Device = NULL; 
  144.     } 
  145.     return 1; 
  146. }    
  147. int WINAPI WinMain(HINSTANCE hInstance, 
  148.                    HINSTANCE prevInstance,  
  149.                    PSTR cmdLine, 
  150.                    int showCmd) 
  151.     HWND hWnd; 
  152.     MSG msg; 
  153.     WNDCLASS wndClass; 
  154.     wndClass.style         = CS_HREDRAW | CS_VREDRAW; 
  155.     wndClass.lpfnWndProc   = (WNDPROC)WndProc;  
  156.     wndClass.cbClsExtra    = NULL; 
  157.     wndClass.cbWndExtra    = NULL; 
  158.     wndClass.hInstance     = hInstance; 
  159.     wndClass.hIcon         = LoadIcon(0, IDI_APPLICATION); 
  160.     wndClass.hCursor       = LoadCursor(0, IDC_ARROW); 
  161.     wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); 
  162.     wndClass.lpszMenuName  = NULL; 
  163.     wndClass.lpszClassName = WINDOWCLASS; 
  164.     if( !RegisterClass(&wndClass) )  
  165.     { 
  166.         ::MessageBox(NULL, TEXT("RegisterClass() - FAILED"), NULL, NULL); 
  167.         return false; 
  168.     } 
  169.     hWnd = CreateWindow(WINDOWCLASS, 
  170.                         WINDOWNAME,  
  171.                         WS_OVERLAPPEDWINDOW | WS_VISIBLE, 
  172.                         0, 0,  
  173.                         Width,  
  174.                         Height, 
  175.                         NULL, 
  176.                         NULL, 
  177.                         hInstance, 
  178.                         NULL);  
  179.     if( !hWnd ) 
  180.     { 
  181.         ::MessageBox(NULL,TEXT( "CreateWindow() - FAILED"), NULL, NULL); 
  182.         return false; 
  183.     } 
  184.     hinstanceApp = hInstance; 
  185.     mainWindowHandle = hWnd; 
  186.     ::ShowWindow(hWnd, SW_SHOW); 
  187.     ::UpdateWindow(hWnd); 
  188.     //1: 獲得一個IDirect3D9接口指針。 
  189.     d3d9 = Direct3DCreate9(D3D_SDK_VERSION); 
  190.     /*Direct3DCreate9 的唯一一個參數總是D3D_SDK_VERSION, 
  191.     這可以保證應用程式通過正确的頭檔案被生成。如果函數調用失敗, 
  192.     那麼它将傳回一個空指針。*/ 
  193.     if( !d3d9 ) 
  194.     { 
  195.         ::MessageBox(NULL, TEXT("Direct3DCreate9() - FAILED"), NULL, NULL); 
  196.         return false; 
  197.     } 
  198.     //2:檢查裝置能力(D3DCAPS9),搞清楚主顯示卡是否支援硬體頂點處理。. 
  199.     //當我們建立一個IDirect3DDevice9對象來表示主顯示裝置時,必須要設定其頂點處理的類型。 
  200.     D3DCAPS9 caps; 
  201.     d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps);// 填充主顯示裝置的能力(D3DCAPS9結構) 
  202.     int vp = 0; 
  203.     if( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ) 
  204.         vp = D3DCREATE_HARDWARE_VERTEXPROCESSING; 
  205.     else 
  206.         vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING; 
  207.     //3: 初始化一個D3DPRESENT _PARAMETERS結構執行個體。 
  208.     D3DPRESENT_PARAMETERS d3dpp; 
  209.     d3dpp.BackBufferWidth            = Width; 
  210.     d3dpp.BackBufferHeight           = Height; 
  211.     d3dpp.BackBufferFormat           = D3DFMT_A8R8G8B8; 
  212.     d3dpp.BackBufferCount            = 1; 
  213.     d3dpp.MultiSampleType            = D3DMULTISAMPLE_NONE; 
  214.     d3dpp.MultiSampleQuality         = 0; 
  215.     d3dpp.SwapEffect                 = D3DSWAPEFFECT_DISCARD;  
  216.     d3dpp.hDeviceWindow              = hWnd; 
  217.     d3dpp.Windowed                   = true;  
  218.     d3dpp.EnableAutoDepthStencil     = true;  
  219.     d3dpp.AutoDepthStencilFormat     = D3DFMT_D24S8; 
  220.     d3dpp.Flags                      = 0; 
  221.     d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; 
  222.     d3dpp.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE; 
  223.     //4:建立一個基于已經初始化好的D3DPRESENT _PARAMETERS結構的IDirect3DDevice9對象。 
  224.     hr = d3d9->CreateDevice(//Creates a device to represent the display adapter. 
  225.         D3DADAPTER_DEFAULT, // primary adapter 
  226.         D3DDEVTYPE_HAL,     // device type 
  227.         hWnd,               // window associated with device 
  228.         vp,                 // vertex processing 
  229.         &d3dpp,             // present parameters 
  230.         &Device);           // return created device 
  231.     if( FAILED(hr) ) 
  232.     { 
  233.         d3dpp.AutoDepthStencilFormat = D3DFMT_D16; 
  234.         hr = d3d9->CreateDevice( 
  235.             D3DADAPTER_DEFAULT, 
  236.             D3DDEVTYPE_HAL, 
  237.             hWnd, 
  238.             vp, 
  239.             &d3dpp, 
  240.             &Device); 
  241.         if( FAILED(hr) ) 
  242.         { 
  243.             d3d9->Release(); //釋放d3d9 
  244.             ::MessageBox(NULL, TEXT("CreateDevice() - FAILED"), NULL, NULL); 
  245.             return false; 
  246.         } 
  247.     } 
  248.     GameInit(); 
  249.     while(TRUE) 
  250.     { 
  251.         if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) 
  252.         {  
  253.             if (msg.message == WM_QUIT) 
  254.                 break;   
  255.             TranslateMessage(&msg); 
  256.             DispatchMessage(&msg); 
  257.         } 
  258.         GameMain(); 
  259.     }  
  260.     GameShutdown(); 
  261.     return 0; 

繼續閱讀