模型类是世界空间中的表示物体的类,那么他的所做的事就是加载模型,移动模型,渲染模型

modelclass.h

 1 #pragma once
 2 
 3 #include <d3d11.h>
 4 #include <d3dcompiler.h>
 5 #include <D3DX11.h>
 6 #include <xnamath.h>
 7 #include<fstream>
 8 using namespace std;
 9 #pragma comment(lib,"d3dx11.lib")
10 #pragma comment(lib,"d3d11.lib")
11 #pragma comment(lib,"d3dcompiler.lib")
12 class modelclass
13 {
14 public:
15     modelclass();
16     ~modelclass();
17 
18     void Render(ID3D11DeviceContext* context,XMMATRIX& viewmatrix, XMMATRIX& promatrix, D3D11_PRIMITIVE_TOPOLOGY geometry,
19         ID3D11VertexShader* vertexshader, ID3D11PixelShader* pixelshader);
20     bool Initialize(ID3D11Device *device, LPCWSTR model, LPCWSTR texture);
21     void Setposition(float x, float y, float z);
22     void RotationAxis(XMVECTOR axis, float angle);
23     void Shutdown();
24 
25 private:
26     bool Loadmodel(LPCWSTR file);
27     bool Loadtexture(LPCWSTR file, ID3D11Device* device);
28 
29     struct vertex
30     {
31         XMFLOAT3 pos;
32         XMFLOAT2 tex;
33     };
34     
35     struct constantBuffer
36     {
37         XMMATRIX world;
38         XMMATRIX view;
39         XMMATRIX pro;
40     };
41 
42     ID3D11Buffer *m_vertexBuffer, *m_indexBuffer;
43     ID3D11Buffer *m_constantBuffer;
44     int m_vertexCount, m_indexCount;
45     ID3D11ShaderResourceView* m_Texture;
46     ID3D11SamplerState *m_samplerstate;
47     vertex* m_vertexlist;
48     XMMATRIX m_worldMatrix;
49 };

他的公共方法如前所述:Render()渲染模型,Initialize()初始化(加载模型),Setposition()移动模型,RotationAxis()绕轴旋转。

两个私有数据结构,顶点和常量缓存,分别是用来构造顶点缓存和常量缓存的。

私有成员:顶点缓存,索引缓存,常量缓存,顶点个数,索引个数,纹理源视图,取样器状态,顶点列表,及世界变换矩阵。

modelclass.cpp

  1 #include "modelclass.h"
  2 
  3 
  4 modelclass::modelclass()
  5 {
  6     m_worldMatrix = XMMatrixIdentity();
  7 }
  8 
  9 
 10 modelclass::~modelclass()
 11 {
 12 }
 13 
 14 
 15 bool modelclass::Initialize(ID3D11Device* device,LPCWSTR model,LPCWSTR texture)
 16 {
 17     HRESULT hr = S_OK;
 18     bool m=Loadmodel(model);
 19     bool t=Loadtexture(texture,device);    
 20 
 21     D3D11_BUFFER_DESC bd;
 22     ZeroMemory(&bd, sizeof(bd));
 23     bd.Usage = D3D11_USAGE_DEFAULT;
 24     bd.ByteWidth = sizeof(vertex)* m_vertexCount;
 25     bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
 26     bd.CPUAccessFlags = 0;
 27     D3D11_SUBRESOURCE_DATA InitData;
 28     InitData.pSysMem = m_vertexlist;
 29     hr = device->CreateBuffer(&bd, &InitData, &m_vertexBuffer);
 30     if (FAILED(hr))
 31     {
 32         return false;
 33     }
 34 
 35 
 36     WORD *indices = new WORD[m_indexCount];
 37     for (int i = 0; i < m_indexCount; i++)
 38     {
 39         indices[i] = i;
 40     }    
 41     D3D11_BUFFER_DESC bd1;
 42     ZeroMemory(&bd1, sizeof(bd1));
 43     bd1.Usage = D3D11_USAGE_DEFAULT;
 44     bd1.ByteWidth = sizeof(WORD)* m_indexCount;      
 45     bd1.BindFlags = D3D11_BIND_INDEX_BUFFER;
 46     bd1.CPUAccessFlags = 0;
 47     D3D11_SUBRESOURCE_DATA InitData1;
 48     InitData1.pSysMem = indices;
 49     hr = device->CreateBuffer(&bd1, &InitData1, &m_indexBuffer);    
 50     if (FAILED(hr))
 51     {
 52         return false;
 53     }
 54 
 55 
 56     D3D11_BUFFER_DESC bd2;
 57     ZeroMemory(&bd2, sizeof(bd2));
 58     bd2.Usage = D3D11_USAGE_DEFAULT;
 59     bd2.ByteWidth = sizeof(constantBuffer);
 60     bd2.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
 61     bd2.CPUAccessFlags = 0;
 62     hr = device->CreateBuffer(&bd2, NULL, &m_constantBuffer);
 63     if (FAILED(hr))
 64     {
 65         return false;
 66     }
 67 
 68 
 69     D3D11_SAMPLER_DESC sampDesc;
 70     ZeroMemory(&sampDesc, sizeof(sampDesc));
 71     sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
 72     sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
 73     sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
 74     sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
 75     sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
 76     sampDesc.MinLOD = 0;
 77     sampDesc.MaxLOD = D3D11_FLOAT32_MAX;
 78     device->CreateSamplerState(&sampDesc, &m_samplerstate);
 79 
 80     delete[] indices;
 81     indices = 0;
 82 
 83     return true;
 84 }
 85 
 86 
 87 bool modelclass::Loadmodel(LPCWSTR file)
 88 {
 89     ifstream fin;
 90     char input;
 91     
 92     fin.open(file);
 93     if (fin.fail())
 94     {
 95         return false;
 96     }
 97 
 98     fin.get(input);
 99     while (input != ':')
100     {
101         fin.get(input);
102     }
103 
104     fin >> m_vertexCount;
105     
106     m_indexCount = m_vertexCount;
107 
108     m_vertexlist = new vertex[m_vertexCount];
109     if (!m_vertexlist)
110     {
111         return false;
112     }
113 
114     fin.get(input);
115     while (input != ':')
116     {
117         fin.get(input);
118     }
119     fin.get(input);
120     fin.get(input);
121 
122     for (int i = 0; i<m_vertexCount; i++)
123     {
124         fin >> m_vertexlist[i].pos.x >> m_vertexlist[i].pos.y >> m_vertexlist[i].pos.z;
125         fin >> m_vertexlist[i].tex.x >> m_vertexlist[i].tex.y;        
126     }
127 
128     fin.close();
129     return true;
130 }
131 
132 
133 bool modelclass::Loadtexture(LPCWSTR file,ID3D11Device* device)
134 {
135     D3DX11CreateShaderResourceViewFromFile(device, file, NULL, NULL, &m_Texture, NULL);
136     return true;
137 }
138 
139 
140 void modelclass::Render(ID3D11DeviceContext* context, XMMATRIX& viewmatrix, XMMATRIX& pro, D3D11_PRIMITIVE_TOPOLOGY geometry,
141     ID3D11VertexShader* vertexshader,ID3D11PixelShader* pixelshader)
142 {
143     UINT stride = sizeof(vertex);
144     UINT offset = 0;
145     context->IASetVertexBuffers(0,1,&m_vertexBuffer,&stride,&offset);
146     context->IASetIndexBuffer(m_indexBuffer, DXGI_FORMAT_R16_UINT, 0);
147     context->IASetPrimitiveTopology(geometry);
148 
149     constantBuffer cb;
150     XMMATRIX worldmatrix = m_worldMatrix;
151     XMMATRIX promatrix = pro;
152     cb.world = XMMatrixTranspose(worldmatrix);
153     cb.view = XMMatrixTranspose(viewmatrix);
154     cb.pro = XMMatrixTranspose(promatrix);
155 
156     context->UpdateSubresource(m_constantBuffer, 0, NULL, &cb, 0, 0);
157 
158     context->VSSetShader(vertexshader, NULL, 0);
159     context->VSSetConstantBuffers(0, 1, &m_constantBuffer);
160     context->PSSetShader(pixelshader, NULL, 0);
161 
162     context->PSSetShaderResources(0, 1, &m_Texture);
163     context->PSSetSamplers(0, 1, &m_samplerstate);
164     context->DrawIndexed(m_vertexCount, 0, 0);    
165 }
166 
167 
168 void modelclass::Setposition(float x, float y, float z)
169 {
170     m_worldMatrix = XMMatrixTranslation(x, y, z);
171 }
172 
173 
174 void modelclass::RotationAxis(XMVECTOR axis, float angle)
175 {
176     m_worldMatrix *= XMMatrixRotationAxis(axis, angle);
177 }
178 
179 
180 void modelclass::Shutdown()
181 {
182     if (m_samplerstate)
183     {
184         m_samplerstate->Release();
185     }
186     if (m_constantBuffer)
187     {
188         m_constantBuffer->Release();
189     }
190     if (m_indexBuffer)
191     {
192         m_indexBuffer->Release();
193     }
194     if (m_vertexBuffer)
195     {
196         m_vertexBuffer->Release();
197     }
198     if (m_Texture)
199     {
200         m_Texture->Release();
201     }
202     if (m_vertexlist)
203     {
204         delete[] m_vertexlist;
205         m_vertexlist = 0;
206     }
207 }

initialize():

  • 调用私有方法加载模型和纹理。加载完模型后,顶点列表,顶点个数已经有值了;加载完纹理后,纹理资源视图也有值了。
  • 填充顶点缓存描述数据结构,将顶点列表填充到源数据数据结构的pSysmem字段,然后根据顶点描述数据结构和源数据数据结构创建顶点缓存
  • for循环填充索引,填充索引缓存描述数据结构,填充源数据数据结构,创建索引缓存
  • 填充常量缓存描述数据结构,并创建常量缓存
  • 填充取样器描述数据结构,并创建取样器状态

私有方法Loadmodel():

从磁盘读取一个文件,该文件包含顶点信息,顶点个数该文件如下

Vertex Count: 6

Data:

-1.0 -1.0 0.0 0.0 1.0
-1.0 1.0 0.0 0.0 0.0
1.0 -1.0 0.0 1.0 1.0
-1.0 1.0 0.0 0.0 0.0
1.0 1.0 0.0 1.0 0.0
1.0 -1.0 0.0 1.0 1.0

这是一个txt文件,有6个顶点,每个顶点有3个位置坐标信息和2个纹理坐标信息。

这个方法很简单,就不多做叙述了。

Render():

  • 设置创建好的顶点缓存
  • 设置创建好的索引缓存
  • 设置图形绘制方式
  • 将世界转换矩阵,观察矩阵,投影矩阵填充在常量缓存里的各个字段中,并更新常量缓存
  • 设置顶点着色器
  • 设置常量缓存
  • 设置像素着色器
  • 设置纹理源
  • 设置取样器的取样方式
  • 绘制各个顶点

Setposition(),RotationAxis():

这两个方法只是作用于世界转换矩阵,没什么好说的,他们就是用来将模型翻转或平移的

 

 posted on 2016-06-20 15:45  Woody_245  阅读(1175)  评论(0编辑  收藏  举报