DirectX教程繪制D模型_第1頁
DirectX教程繪制D模型_第2頁
DirectX教程繪制D模型_第3頁
DirectX教程繪制D模型_第4頁
DirectX教程繪制D模型_第5頁
已閱讀5頁,還剩14頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、DirectX 10教程7:繪制3D模型原文地址: HYPERLINK /dx10tut07.html Tutorial 7: 3D Model Rendering。本教程介紹在DirectX 10中使用HLSL繪制3D模型,代碼基于上一個(gè)漫反射光照的教程。在上一個(gè)教程中我們繪制了一個(gè)3D模型,只是一個(gè)簡(jiǎn)單的三角形很容易理解。本教程我們要繪制一個(gè)更復(fù)雜的對(duì)象立方體,但在這之前需要討論一下模型格式。有很多工具可以創(chuàng)建3D模型,Maya和3D Studio Max是兩個(gè)較為流行的建模工具,其他的工具功能弱一點(diǎn),但都能完成基本的工作。無論使用的是何種工具,你總要將做好的模型導(dǎo)出為不同的格式。建議你定

2、義自己的模型格式,然后編寫一個(gè)轉(zhuǎn)換程序?qū)⑤敵龈袷睫D(zhuǎn)換為自己的格式。因?yàn)槟阌锌赡芨淖兪褂玫?D建模工具,模型格式也會(huì)隨之改變,因此會(huì)處理不同的格式。如果你使用自己的格式,并將不同的其他格式轉(zhuǎn)換為自己的格式,那么你的程序就無需進(jìn)行修改,只需修改你的格式轉(zhuǎn)換程序即可。而且大多數(shù)3D建模工具會(huì)導(dǎo)出只適用于它們的無關(guān)數(shù)據(jù),在你的模型格式中無需使用這些數(shù)據(jù)。使用自己的格式最重要的就是格式是否滿足你的需要,使用起來是否簡(jiǎn)便。你也可以考慮對(duì)不同的對(duì)象使用不同的格式,例如有些模型包含動(dòng)畫,而有些模型是靜態(tài)的。我要介紹的模型格式非?;尽C啃袑?duì)應(yīng)一個(gè)頂點(diǎn),包含位置矢量(x, y, z),紋理坐標(biāo)(tu, tv)和

3、法線矢量(nx, ny, nz)。在文件頂部還包含頂點(diǎn)的數(shù)量,你可以在第一行就讀取這個(gè)信息,這樣在讀取頂點(diǎn)數(shù)據(jù)之前就可以分配大小正確的內(nèi)存用于數(shù)組。此文件格式每三行數(shù)據(jù)構(gòu)成一個(gè)三角形,頂點(diǎn)的排列順序是是順時(shí)針方向。下面是模型文件的內(nèi)容:Cube.txtVertex Count: 36Data:-1.0 1.0 -1.0 0.0 0.0 0.0 0.0 -1.0 1.0 1.0 -1.0 1.0 0.0 0.0 0.0 -1.0-1.0 -1.0 -1.0 0.0 1.0 0.0 0.0 -1.0-1.0 -1.0 -1.0 0.0 1.0 0.0 0.0 -1.0 1.0 1.0 -1.0 1

4、.0 0.0 0.0 0.0 -1.0 1.0 -1.0 -1.0 1.0 1.0 0.0 0.0 -1.0 1.0 1.0 -1.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 1.0 1.0 0.0 1.0 0.0 0.0 1.0 -1.0 -1.0 0.0 1.0 1.0 0.0 0.0 1.0 -1.0 -1.0 0.0 1.0 1.0 0.0 0.0 1.0 1.0 1.0 1.0 0.0 1.0 0.0 0.0 1.0 -1.0 1.0 1.0 1.0 1.0 0.0 0.0 1.0 1.0 1.0 0.0 0.0 0.0 0.0 1.0-1.0 1.0 1.0 1.0

5、 0.0 0.0 0.0 1.0 1.0 -1.0 1.0 0.0 1.0 0.0 0.0 1.0 1.0 -1.0 1.0 0.0 1.0 0.0 0.0 1.0-1.0 1.0 1.0 1.0 0.0 0.0 0.0 1.0-1.0 -1.0 1.0 1.0 1.0 0.0 0.0 1.0-1.0 1.0 1.0 0.0 0.0 -1.0 0.0 0.0-1.0 1.0 -1.0 1.0 0.0 -1.0 0.0 0.0-1.0 -1.0 1.0 0.0 1.0 -1.0 0.0 0.0-1.0 -1.0 1.0 0.0 1.0 -1.0 0.0 0.0-1.0 1.0 -1.0 1.0

6、0.0 -1.0 0.0 0.0-1.0 -1.0 -1.0 1.0 1.0 -1.0 0.0 0.0-1.0 1.0 1.0 0.0 0.0 0.0 1.0 0.0 1.0 1.0 1.0 1.0 0.0 0.0 1.0 0.0-1.0 1.0 -1.0 0.0 1.0 0.0 1.0 0.0-1.0 1.0 -1.0 0.0 1.0 0.0 1.0 0.0 1.0 1.0 1.0 1.0 0.0 0.0 1.0 0.0 1.0 1.0 -1.0 1.0 1.0 0.0 1.0 0.0-1.0 -1.0 -1.0 0.0 0.0 0.0 -1.0 0.0 1.0 -1.0 -1.0 1.0

7、0.0 0.0 -1.0 0.0-1.0 -1.0 1.0 0.0 1.0 0.0 -1.0 0.0-1.0 -1.0 1.0 0.0 1.0 0.0 -1.0 0.0 1.0 -1.0 -1.0 1.0 0.0 0.0 -1.0 0.0 1.0 -1.0 1.0 1.0 1.0 0.0 -1.0 0.0你可以看到有36行x,y,z,tu,tv,nx,ny,nz數(shù)據(jù)。每三行構(gòu)成一個(gè)三角形,一共12個(gè)三角形構(gòu)成一個(gè)立方體。數(shù)據(jù)格式非常簡(jiǎn)單,可以不加修改被讀取到頂點(diǎn)緩存。值得注意的是,有些3D建模工具以不同的順序輸出數(shù)據(jù),例如順時(shí)針方向和逆時(shí)針方向坐標(biāo)系統(tǒng),你需要記住DirectX 10默認(rèn)為左手

8、坐標(biāo)系,所以模型數(shù)據(jù)也必須加以匹配。留心這些區(qū)別,確保你的轉(zhuǎn)換程序?qū)?shù)據(jù)轉(zhuǎn)換為正確的格式/順序。Modelclass.h本教程中我們需要對(duì)ModelClass做一點(diǎn)小的修改使之可以繪制來自于文本文件中的3D模型。/ Filename: modelclass.h/#ifndef _MODELCLASS_H_#define _MODELCLASS_H_需要包含fstream庫處理模型文本文件的讀取。/ INCLUDES /#include using namespace std;/ MY CLASS INCLUDES /#include textureclass.h/ Class name: Mo

9、delClass/class ModelClassprivate:struct VertexTypeD3DXVECTOR3 position;D3DXVECTOR2 texture;D3DXVECTOR3 normal;下一個(gè)變化是添加了一個(gè)新結(jié)構(gòu)表示模型格式,名稱為ModelType。它包含了位置,紋理坐標(biāo)和法線矢量。struct ModelTypefloat x, y, z;float tu, tv;float nx, ny, nz;public:ModelClass();ModelClass(const ModelClass&);ModelClass();Initialize方法的一個(gè)參

10、數(shù)為要加載的模型的文件名稱。bool Initialize(ID3D10Device*, char*, WCHAR*);void Shutdown();void Render(ID3D10Device*);int GetIndexCount();ID3D10ShaderResourceView* GetTexture();private:bool InitializeBuffers(ID3D10Device*);void ShutdownBuffers();void RenderBuffers(ID3D10Device*);bool LoadTexture(ID3D10Device*, WCH

11、AR*);void ReleaseTexture();還添加了兩個(gè)新方法加載和卸載來自于文本文件的模型數(shù)據(jù)。bool LoadModel(char*);void ReleaseModel();private:ID3D10Buffer *m_vertexBuffer, *m_indexBuffer;int m_vertexCount, m_indexCount;TextureClass* m_Texture;最后的變化是一個(gè)叫做m_model的私有變量,對(duì)應(yīng)新的結(jié)構(gòu)體ModelType的數(shù)組。這個(gè)變量用來在發(fā)送到頂點(diǎn)緩存之前讀取和保存模型數(shù)據(jù)。ModelType* m_model;#endifM

12、odelclass.cpp/ Filename: modelclass.cpp/#include modelclass.hModelClass:ModelClass()m_vertexBuffer = 0;m_indexBuffer = 0;m_Texture = 0;在構(gòu)造函數(shù)中將模型結(jié)構(gòu)體設(shè)置為null。m_model = 0;ModelClass:ModelClass(const ModelClass& other)ModelClass:ModelClass()Initialize方法的一個(gè)參數(shù)為模型文件的名稱。bool ModelClass:Initialize(ID3D10Devic

13、e* device, char* modelFilename, WCHAR* textureFilename)bool result;在Initialize方法中我們首先調(diào)用LoadModel方法,這個(gè)方法將模型數(shù)據(jù)加載到m_model數(shù)組中。填充了這個(gè)數(shù)組后,我們就可以基于它創(chuàng)建頂點(diǎn)和索引緩存了。因?yàn)镮nitializeBuffers方法需要使用模型數(shù)據(jù),所以你需要確保以正確的順序調(diào)用這個(gè)方法。/ Load in the model data.result = LoadModel(modelFilename);if(!result)return false;/ Initialize the

14、vertex and index buffers.result = InitializeBuffers(device);if(!result)return false;/ Load the texture for this model.result = LoadTexture(device, textureFilename);if(!result)return false;return true;void ModelClass:Shutdown()/ Release the model texture.ReleaseTexture();/ Shutdown the vertex and ind

15、ex buffers.ShutdownBuffers();在Shutdown方法中,我們添加了調(diào)用ReleaseModel方法,用來清除m_model數(shù)組數(shù)據(jù)。/ Release the model data.ReleaseModel();return;void ModelClass:Render(ID3D10Device* device)/ Put the vertex and index buffers on the graphics pipeline to prepare them for drawing.RenderBuffers(device);return;int ModelCla

16、ss:GetIndexCount()return m_indexCount;ID3D10ShaderResourceView* ModelClass:GetTexture()return m_Texture-GetTexture();bool ModelClass:InitializeBuffers(ID3D10Device* device)VertexType* vertices;unsigned long* indices;D3D10_BUFFER_DESC vertexBufferDesc, indexBufferDesc;D3D10_SUBRESOURCE_DATA vertexDat

17、a, indexData;HRESULT result;int i;注意我們現(xiàn)在不需要手動(dòng)設(shè)置頂點(diǎn)和索引數(shù)量,我們可以在ModelClass:LoadModel方法中讀取頂點(diǎn)和索引數(shù)量。/ Create the vertex array.vertices = new VertexTypem_vertexCount;if(!vertices)return false;/ Create the index array.indices = new unsigned longm_indexCount;if(!indices)return false;加載頂點(diǎn)和索引數(shù)組有一點(diǎn)變化。現(xiàn)在不需要手動(dòng)設(shè)置,而

18、是遍歷m_model數(shù)組中的數(shù)據(jù),將它們復(fù)制到頂點(diǎn)數(shù)組中。索引數(shù)組很容易創(chuàng)建,因?yàn)槊總€(gè)頂點(diǎn)的索引值與數(shù)組中的索引值相同。/ Load the vertex array and index array with data.for(i=0; iCreateBuffer(&vertexBufferDesc, &vertexData, &m_vertexBuffer);if(FAILED(result)return false;/ Set up the description of the index buffer.indexBufferDesc.Usage = D3D10_USAGE_DEFAULT

19、;indexBufferDesc.ByteWidth = sizeof(unsigned long) * m_indexCount;indexBufferDesc.BindFlags = D3D10_BIND_INDEX_BUFFER;indexBufferDesc.CPUAccessFlags = 0;indexBufferDesc.MiscFlags = 0;/ Give the subresource structure a pointer to the index data.indexData.pSysMem = indices;/ Create the index buffer.re

20、sult = device-CreateBuffer(&indexBufferDesc, &indexData, &m_indexBuffer);if(FAILED(result)return false;/ Release the arrays now that the vertex and index buffers have been created and loaded.delete vertices;vertices = 0;delete indices;indices = 0;return true;void ModelClass:ShutdownBuffers()/ Releas

21、e the index buffer.if(m_indexBuffer)m_indexBuffer-Release();m_indexBuffer = 0;/ Release the vertex buffer.if(m_vertexBuffer)m_vertexBuffer-Release();m_vertexBuffer = 0;return;void ModelClass:RenderBuffers(ID3D10Device* device)unsigned int stride;unsigned int offset;/ Set vertex buffer stride and off

22、set.stride = sizeof(VertexType); offset = 0; / Set the vertex buffer to active in the input assembler so it can be rendered.device-IASetVertexBuffers(0, 1, &m_vertexBuffer, &stride, &offset);/ Set the index buffer to active in the input assembler so it can be rendered.device-IASetIndexBuffer(m_index

23、Buffer, DXGI_FORMAT_R32_UINT, 0);/ Set the type of primitive that should be rendered from this vertex buffer, in this case triangles.device-IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);return;bool ModelClass:LoadTexture(ID3D10Device* device, WCHAR* filename)bool result;/ Create the

24、texture object.m_Texture = new TextureClass;if(!m_Texture)return false;/ Initialize the texture object.result = m_Texture-Initialize(device, filename);if(!result)return false;return true;void ModelClass:ReleaseTexture()/ Release the texture object.if(m_Texture)m_Texture-Shutdown();delete m_Texture;m

25、_Texture = 0;return;新的LoadModel方法處理從文本文件中將模型數(shù)據(jù)加載到m_model數(shù)組變量中。首先打開文本文件讀取頂點(diǎn)數(shù)量,之后創(chuàng)建ModelType數(shù)組并讀取每一行的數(shù)據(jù)到這個(gè)數(shù)組中。頂點(diǎn)或索引數(shù)量也是在這個(gè)方法中設(shè)置的。bool ModelClass:LoadModel(char* filename)ifstream fin;char input;int i;/ Open the model file.fin.open(filename);/ If it could not open the file then exit.if(fin.fail()return

26、 false;/ Read up to the value of vertex count.fin.get(input);while(input != :)fin.get(input);/ Read in the vertex count.fin m_vertexCount;/ Set the number of indices to be the same as the vertex count.m_indexCount = m_vertexCount;/ Create the model using the vertex count that was read in.m_model = n

27、ew ModelTypem_vertexCount;if(!m_model)return false;/ Read up to the beginning of the data.fin.get(input);while(input != :)fin.get(input);fin.get(input);fin.get(input);/ Read in the vertex data.for(i=0; i m_modeli.x m_modeli.y m_modeli.z;fin m_modeli.tu m_modeli.tv;fin m_modeli.nx m_modeli.ny m_model

28、i.nz;/ Close the model file.fin.close();return true;ReleaseModel方法刪除模型數(shù)據(jù)數(shù)組。void ModelClass:ReleaseModel()if(m_model)delete m_model;m_model = 0;return;Graphicsclass.hGraphicsClass的頭文件與上一個(gè)教程一樣。/ Filename: graphicsclass.h/#ifndef _GRAPHICSCLASS_H_#define _GRAPHICSCLASS_H_/ MY CLASS INCLUDES /#include d

29、3dclass.h#include cameraclass.h#include modelclass.h#include lightshaderclass.h#include lightclass.h/ GLOBALS /const bool FULL_SCREEN = true;const bool VSYNC_ENABLED = true;const float SCREEN_DEPTH = 1000.0f;const float SCREEN_NEAR = 0.1f;/ Class name: GraphicsClass/class GraphicsClasspublic:Graphic

30、sClass();GraphicsClass(const GraphicsClass&);GraphicsClass();bool Initialize(int, int, HWND);void Shutdown();bool Frame();private:bool Render(float);private:D3DClass* m_D3D;CameraClass* m_Camera;ModelClass* m_Model;LightShaderClass* m_LightShader;LightClass* m_Light;#endifGraphicsclass.cpp/ Filename

31、: graphicsclass.cpp/#include graphicsclass.hGraphicsClass:GraphicsClass()m_D3D = 0;m_Camera = 0;m_Model = 0;m_LightShader = 0;m_Light = 0;GraphicsClass:GraphicsClass(const GraphicsClass& other)GraphicsClass:GraphicsClass()bool GraphicsClass:Initialize(int screenWidth, int screenHeight, HWND hwnd)boo

32、l result;/ Create the Direct3D object.m_D3D = new D3DClass;if(!m_D3D)return false;/ Initialize the Direct3D object.result = m_D3D-Initialize(screenWidth, screenHeight, VSYNC_ENABLED, hwnd, FULL_SCREEN, SCREEN_DEPTH, SCREEN_NEAR);if(!result)MessageBox(hwnd, LCould not initialize Direct3D, LError, MB_

33、OK);return false;/ Create the camera object.m_Camera = new CameraClass;if(!m_Camera)return false;/ Create the model object.m_Model = new ModelClass;if(!m_Model)return false;模型的初始化方法的參數(shù)包含要加載的模型文件名稱,本教程中我用的是cube.txt。/ Initialize the model object.result = m_Model-Initialize(m_D3D-GetDevice(), ./Engine/

34、data/cube.txt, L./Engine/data/seafloor.dds);if(!result)MessageBox(hwnd, LCould not initialize the model object., LError, MB_OK);return false;/ Create the light shader object.m_LightShader = new LightShaderClass;if(!m_LightShader)return false;/ Initialize the light shader object.result = m_LightShade

35、r-Initialize(m_D3D-GetDevice(), hwnd);if(!result)MessageBox(hwnd, LCould not initialize the light shader object., LError, MB_OK);return false;/ Create the light object.m_Light = new LightClass;if(!m_Light)return false;本教程中我將光線顏色變?yōu)榘咨? Initialize the light object.m_Light-SetDiffuseColor(1.0f, 1.0f, 1

36、.0f, 1.0f);m_Light-SetDirection(0.0f, 0.0f, 1.0f);return true;void GraphicsClass:Shutdown()/ Release the light object.if(m_Light)delete m_Light;m_Light = 0;/ Release the light shader object.if(m_LightShader)m_LightShader-Shutdown();delete m_LightShader;m_LightShader = 0;/ Release the model object.if

37、(m_Model)m_Model-Shutdown();delete m_Model;m_Model = 0;/ Release the camera object.if(m_Camera)delete m_Camera;m_Camera = 0;/ Release the D3D object.if(m_D3D)m_D3D-Shutdown();delete m_D3D;m_D3D = 0;return;bool GraphicsClass:Frame()bool result;static float rotation = 0.0f;/ Update the rotation variable each frame.rotation += (float)D3DX_PI * 0.01f;if(rotation 360.0f)rotation -= 360.0f;/ Render the graphics scene.result = Render(ro

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論