模型类是世界空间中的表示物体的类,那么他的所做的事就是加载模型,移动模型,渲染模型
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():
这两个方法只是作用于世界转换矩阵,没什么好说的,他们就是用来将模型翻转或平移的
原文链接: https://www.cnblogs.com/woody-245/p/5598571.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/235527
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!