(DX繪製旋轉正方形) 龍書 第三章 Direct3D中的繪製

來源:互聯網
上載者:User

#include "d3dUtility.h"</p><p>//<br />// Globals//全域變數<br />//</p><p>IDirect3DDevice9* Device = 0;<br />//<br />//介面IDirect3D9的指標.該介面用於擷取系統中物理硬體裝置的資訊並建立介面IDirect3DDevice9<br />//該介面是一個C++對象,代表我們用來顯示3D圖形的物理硬體裝置<br />//<br />const int Width = 640;//視窗的寬<br />const int Height = 480;//高</p><p>IDirect3DVertexBuffer9* VB = 0;//頂點緩衝指標<br />IDirect3DIndexBuffer9* IB = 0;//索引緩衝指標</p><p>//<br />// Classes and Structures<br />//<br />//為建立自訂的頂點格式,我們需要建立一個包含了我們所希望具有頂點資料的結構體。<br />//</p><p>struct Vertex<br />//頂點結構定義好之後,就需要用靈活頂點格式(Flexible Vertex Format,FVF)標記的組合來描述頂點組織圖<br />{<br />Vertex(){}<br />Vertex(float x, float y, float z)<br />{<br />_x = x; _y = y; _z = z;<br />}<br />float _x, _y, _z;<br />static const DWORD FVF;<br />};</p><p>//<br />//定義靈活頂點格式時需要遵循一個約定是:靈活頂點格式標記的指定順序必須與頂點結構中相應類型資料定義順序保持一致<br />//</p><p>const DWORD Vertex::FVF = D3DFVF_XYZ;</p><p>//<br />// Framework Functions<br />//<br />bool Setup()<br />{<br />//<br />// Create vertex and index buffers.<br />//<br />//建立一個可容納8個vertex類型的頂點的靜態頂點緩衝<br />Device->CreateVertexBuffer(<br />8 * sizeof(Vertex),<br />D3DUSAGE_WRITEONLY,//規定應用程式對快取作業模式為“唯寫”<br />Vertex::FVF,//儲存在頂點緩衝中頂點的靈活頂點格式<br />D3DPOOL_MANAGED,<br />//<br />//放入該託管記憶體池中的資源將交Direct3D管理(即,這些資源將根據需要被裝置自動轉移到顯存或AGP儲存區中)。<br />//此外,這些資源將在系統儲存區中保留一個備份。這樣,必要時Direct3D會將這些資源自動更新到顯存中。<br />//<br />&VB, //接受建立的頂點緩衝的指標<br />0); //pSharedHandle 不適用,改值設為0。<br />//<br />//建立動態緩衝,可容納36個16位索引<br />//<br />Device->CreateIndexBuffer(<br />36 * sizeof(WORD),<br />D3DUSAGE_WRITEONLY,<br />D3DFMT_INDEX16,//指定索引的大小。D3DFMT_INDEX16表示16位索引,D3DFMT_INDEX32表示32位索引。<br />//注意並非所有的圖形裝置都支援32位索引,如需使用,請檢查硬體的效能。<br />D3DPOOL_MANAGED,<br />&IB,<br />0);</p><p>//<br />// Fill the buffers with the cube data.<br />//</p><p>// define unique vertices:<br />Vertex* vertices;//頂點指標<br />//藉助方法Lock來擷取指向緩衝內容的執政。當訪問完畢後,必須對緩衝進行解鎖(unlock)。<br />//只要擷取了指向緩衝內容的指標,我們就可對其內容進行讀寫操作<br />//<br />// HRESULT IDrect3DIndexBuffer9::Lock{<br />// UINT OffsetToLock, 自緩衝的起始點到開始鎖定的位置的位移量,單位:位元組<br />// UINT SizeToLock, 所要鎖定的位元組數<br />// BYTE** ppbData, 指向所鎖定的儲存區起始位置的指標<br />// Flags 鎖定的方式,可以是0,也可以是下列標記之一或某種組合;Link:<br />// };<br />//前兩個參數為0,表示鎖定整個緩衝<br />//<br />VB->Lock(0, 0, (void**)&vertices, 0);</p><p>// vertices of a unit cube<br />vertices[0] = Vertex(-1.0f, -1.0f, -1.0f);<br />vertices[1] = Vertex(-1.0f, 1.0f, -1.0f);<br />vertices[2] = Vertex( 1.0f, 1.0f, -1.0f);<br />vertices[3] = Vertex( 1.0f, -1.0f, -1.0f);<br />vertices[4] = Vertex(-1.0f, -1.0f, 1.0f);<br />vertices[5] = Vertex(-1.0f, 1.0f, 1.0f);<br />vertices[6] = Vertex( 1.0f, 1.0f, 1.0f);<br />vertices[7] = Vertex( 1.0f, -1.0f, 1.0f);</p><p>VB->Unlock();</p><p>// define the triangles of the cube:<br />WORD* indices = 0;<br />IB->Lock(0, 0, (void**)&indices, 0);</p><p>// front side<br />indices[0] = 0; indices[1] = 1; indices[2] = 2;<br />indices[3] = 0; indices[4] = 2; indices[5] = 3;</p><p>// back side<br />indices[6] = 4; indices[7] = 6; indices[8] = 5;<br />indices[9] = 4; indices[10] = 7; indices[11] = 6;</p><p>// left side<br />indices[12] = 4; indices[13] = 5; indices[14] = 1;<br />indices[15] = 4; indices[16] = 1; indices[17] = 0;</p><p>// right side<br />indices[18] = 3; indices[19] = 2; indices[20] = 6;<br />indices[21] = 3; indices[22] = 6; indices[23] = 7;</p><p>// top<br />indices[24] = 1; indices[25] = 5; indices[26] = 6;<br />indices[27] = 1; indices[28] = 6; indices[29] = 2;</p><p>// bottom<br />indices[30] = 4; indices[31] = 0; indices[32] = 3;<br />indices[33] = 4; indices[34] = 3; indices[35] = 7;</p><p>IB->Unlock();</p><p>//<br />// Position and aim the camera.<br />//</p><p>D3DXVECTOR3 position(0.0f, 0.0f, -5.0f);//攝影機的位置<br />D3DXVECTOR3 target(0.0f, 0.0f, 0.0f); //觀察點在全局座標系的位置<br />D3DXVECTOR3 up(0.0f, 1.0f, 0.0f); //全局座標系中表示向上的方向的向量<br /> D3DXMATRIX V;<br />//<br />//取景變換矩陣(觀察矩陣)計算函數<br />//就是將攝影機平移到全局座標的原點<br />//<br />D3DXMatrixLookAtLH(&V, &position, &target, &up);<br />//<br /> //取景變換需要以下函數設定,其中對應變換類型的參數需要制定為D3DTS_VIEW<br />//<br />Device->SetTransform(D3DTS_VIEW, &V);</p><p>//<br />// Set the projection matrix.<br />//<br />//投影矩陣<br />//<br />D3DXMATRIX proj;<br />D3DXMatrixPerspectiveFovLH(<br />&proj,//<br />D3DX_PI * 0.5f, // 90 - degree視域體的視域角</p><p>(float)Width / (float)Height, //縱橫比(aspect ratio)=螢幕寬度/螢幕高度<br />1.0f, //近裁剪圖到座標原點的距離<br />1000.0f); //遠剪圖到座標原點的距離<br />//<br />//投影應用方法用下函數實現,對應變換類型的參數需指定D3DTS_PROJECTION<br />//<br />Device->SetTransform(D3DTS_PROJECTION, &proj);</p><p>//<br />// Switch to wireframe mode.<br />//<br />//繪製狀態 D3DFILL_WIREFRAME線框模式<br />//<br />Device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);</p><p>return true;<br />}</p><p>void Cleanup()<br />{<br />d3d::Release<IDirect3DVertexBuffer9*>(VB);<br />d3d::Release<IDirect3DIndexBuffer9*>(IB);<br />}</p><p>bool Display(float timeDelta)<br />{<br />if( Device )<br />{<br />//<br />// spin the cube:<br />//<br />D3DXMATRIX Rx, Ry;</p><p>// rotate 45 degrees on x-axis<br />//旋轉矩陣 PI/4<br />D3DXMatrixRotationX(&Rx, 3.14f / 4.0f);</p><p>// incremement y-rotation angle each frame<br />static float y = 0.0f;<br />D3DXMatrixRotationY(&Ry, y);<br />y += timeDelta;</p><p>// reset angle to zero when angle reaches 2*PI<br />if( y >= 6.28f )<br />y = 0.0f;</p><p>// combine x- and y-axis rotation transformations.<br />D3DXMATRIX p = Rx * Ry;<br />//<br />//矩陣的優點:可藉助矩陣乘法將幾種變換組合為一個變換矩陣<br />//各個變換矩陣相乘的次序與實施變換的次序一致,D3DTS_WORLD全局座標系<br />//<br />Device->SetTransform(D3DTS_WORLD, &p);</p><p>//<br />// draw the scene:<br />//<br />// HRESULT IDirect3DDevice9::Clear(<br />//DWORD Count,//數組中的矩陣的數目<br />//const D3DRECT* pRects,//所要執行清除操作的螢幕矩陣數組。該參數允許我們只對錶面的部分地區進行清除操作<br />//DWORD Flags,//D3DCLEAR_TARGET—繪製目標表面,通常指後台緩衝<br />////D3DCLEAR_ZBUFFER—深度緩衝<br />////D3DCLEAR_STENCIL—模板緩衝<br />//D3DCOLOR Color,//繪製目標體為何種顏色<br />//float Z, //深度緩衝<br />//DWORD Stencil //模板緩衝值<br />//);</p><p>Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);<br />//<br />//如果該方法失敗,則裝置無法開始情境,因此也就無需調用 EndScene。<br />//如果前面對 BeginScene 的調用失敗,則對 EndScene 的調用也會失敗<br />//<br />Device->BeginScene();</p><p>//<br />//HRESULT IDirect3DDevice9::SetStreamSource(<br />//UINT StreamNumber, //標識與頂點緩衝建立連結的資料流。不使用多個流,參數設為0<br />//IDirect3DVertexBuffer9* pStreamData,//給定資料流建立連結的頂點緩衝的指標<br />//UINT OffsetInBytes, //自資料流起始點算起的一個位移量,單位位元組<br />//UINT Stride//將要串連到資料流的頂點緩衝中每個元素的大小,單位位元組<br />//);<br />//<br />Device->SetStreamSource(0, VB, 0, sizeof(Vertex));<br />Device->SetIndices(IB); //設定緩衝<br />Device->SetFVF(Vertex::FVF);//設定頂點格式</p><p>// Draw cube.<br />//HRESULT IDirect3DDevice9::DrawPrimitive(<br />//D3DPRIMITIVETYPE PrimitiveType,//所要繪製的圖元類型。<br />//UINT StartVertex, //頂點資料流中標示頂點資料的讀取起點的元素索引。該參數賦予我們一定的自由度,<br />//使得我們可以只對頂點緩衝中某一部分進行繪製<br />//UINT PrimitiveCount //所要繪製的圖元數量<br />//);</p><p>//HRESULT IDirect3DDevice9::DrawIndexedPrimitive(<br />//D3DPRIMITIVETYPE Type,//繪製圖元類型<br />//INT BaseVertexIndex, //為索引增加一個基數<br />//UINT MinIndex, //引用的最小索引值<br />//UINT NumVertices, //本次條用的頂點總數<br />//UINT StartIndex,//頂點資料流中標示頂點資料的讀取起點的元素索引<br />//UINT PrimitiveCount //所要繪製的圖元數量<br />//);<br />Device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 8, 0, 12);</p><p>Device->EndScene();<br />Device->Present(0, 0, 0, 0);//按照裝置擁有的背景緩衝區的順序,在顯示器上呈現下一個緩衝區的內容。<br />}<br />return true;<br />}</p><p>//<br />// WndProc<br />//<br />LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)<br />{<br />switch( msg )<br />{<br />case WM_DESTROY:<br />::PostQuitMessage(0);<br />break;</p><p>case WM_KEYDOWN:<br />if( wParam == VK_ESCAPE )<br />::DestroyWindow(hwnd);<br />break;<br />}<br />return ::DefWindowProc(hwnd, msg, wParam, lParam);<br />}</p><p>//<br />// WinMain<br />//<br />int WINAPI WinMain(HINSTANCE hinstance,<br /> HINSTANCE prevInstance,<br /> PSTR cmdLine,<br /> int showCmd)<br />{<br />if(!d3d::InitD3D(hinstance,<br />Width, Height, true, D3DDEVTYPE_HAL, &Device))<br />{<br />::MessageBox(0, "InitD3D() - FAILED", 0, 0);<br />return 0;<br />}</p><p>if(!Setup())<br />{<br />::MessageBox(0, "Setup() - FAILED", 0, 0);<br />return 0;<br />}</p><p>d3d::EnterMsgLoop( Display );</p><p>Cleanup();</p><p>Device->Release();</p><p>return 0;<br />}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.