C++小项目:directx11图形程序(七):modelclass
模型类是世界空间中的表示物体的类,那么他的所做的事就是加载模型,移动模型,渲染模型
modelclass.h
#pragma once #include <d3d11.h>
#include <d3dcompiler.h>
#include <D3DX11.h>
#include <xnamath.h>
#include<fstream>
using namespace std;
#pragma comment(lib,"d3dx11.lib")
#pragma comment(lib,"d3d11.lib")
#pragma comment(lib,"d3dcompiler.lib")
class modelclass
{
public:
modelclass();
~modelclass(); void Render(ID3D11DeviceContext* context,XMMATRIX& viewmatrix, XMMATRIX& promatrix, D3D11_PRIMITIVE_TOPOLOGY geometry,
ID3D11VertexShader* vertexshader, ID3D11PixelShader* pixelshader);
bool Initialize(ID3D11Device *device, LPCWSTR model, LPCWSTR texture);
void Setposition(float x, float y, float z);
void RotationAxis(XMVECTOR axis, float angle);
void Shutdown(); private:
bool Loadmodel(LPCWSTR file);
bool Loadtexture(LPCWSTR file, ID3D11Device* device); struct vertex
{
XMFLOAT3 pos;
XMFLOAT2 tex;
}; struct constantBuffer
{
XMMATRIX world;
XMMATRIX view;
XMMATRIX pro;
}; ID3D11Buffer *m_vertexBuffer, *m_indexBuffer;
ID3D11Buffer *m_constantBuffer;
int m_vertexCount, m_indexCount;
ID3D11ShaderResourceView* m_Texture;
ID3D11SamplerState *m_samplerstate;
vertex* m_vertexlist;
XMMATRIX m_worldMatrix;
};
他的公共方法如前所述:Render()渲染模型,Initialize()初始化(加载模型),Setposition()移动模型,RotationAxis()绕轴旋转。
两个私有数据结构,顶点和常量缓存,分别是用来构造顶点缓存和常量缓存的。
私有成员:顶点缓存,索引缓存,常量缓存,顶点个数,索引个数,纹理源视图,取样器状态,顶点列表,及世界变换矩阵。
modelclass.cpp
#include "modelclass.h" modelclass::modelclass()
{
m_worldMatrix = XMMatrixIdentity();
} modelclass::~modelclass()
{
} bool modelclass::Initialize(ID3D11Device* device,LPCWSTR model,LPCWSTR texture)
{
HRESULT hr = S_OK;
bool m=Loadmodel(model);
bool t=Loadtexture(texture,device); D3D11_BUFFER_DESC bd;
ZeroMemory(&bd, sizeof(bd));
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof(vertex)* m_vertexCount;
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = ;
D3D11_SUBRESOURCE_DATA InitData;
InitData.pSysMem = m_vertexlist;
hr = device->CreateBuffer(&bd, &InitData, &m_vertexBuffer);
if (FAILED(hr))
{
return false;
} WORD *indices = new WORD[m_indexCount];
for (int i = ; i < m_indexCount; i++)
{
indices[i] = i;
}
D3D11_BUFFER_DESC bd1;
ZeroMemory(&bd1, sizeof(bd1));
bd1.Usage = D3D11_USAGE_DEFAULT;
bd1.ByteWidth = sizeof(WORD)* m_indexCount;
bd1.BindFlags = D3D11_BIND_INDEX_BUFFER;
bd1.CPUAccessFlags = ;
D3D11_SUBRESOURCE_DATA InitData1;
InitData1.pSysMem = indices;
hr = device->CreateBuffer(&bd1, &InitData1, &m_indexBuffer);
if (FAILED(hr))
{
return false;
} D3D11_BUFFER_DESC bd2;
ZeroMemory(&bd2, sizeof(bd2));
bd2.Usage = D3D11_USAGE_DEFAULT;
bd2.ByteWidth = sizeof(constantBuffer);
bd2.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
bd2.CPUAccessFlags = ;
hr = device->CreateBuffer(&bd2, NULL, &m_constantBuffer);
if (FAILED(hr))
{
return false;
} D3D11_SAMPLER_DESC sampDesc;
ZeroMemory(&sampDesc, sizeof(sampDesc));
sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
sampDesc.MinLOD = ;
sampDesc.MaxLOD = D3D11_FLOAT32_MAX;
device->CreateSamplerState(&sampDesc, &m_samplerstate); delete[] indices;
indices = ; return true;
} bool modelclass::Loadmodel(LPCWSTR file)
{
ifstream fin;
char input; fin.open(file);
if (fin.fail())
{
return false;
} fin.get(input);
while (input != ':')
{
fin.get(input);
} fin >> m_vertexCount; m_indexCount = m_vertexCount; m_vertexlist = new vertex[m_vertexCount];
if (!m_vertexlist)
{
return false;
} fin.get(input);
while (input != ':')
{
fin.get(input);
}
fin.get(input);
fin.get(input); for (int i = ; i<m_vertexCount; i++)
{
fin >> m_vertexlist[i].pos.x >> m_vertexlist[i].pos.y >> m_vertexlist[i].pos.z;
fin >> m_vertexlist[i].tex.x >> m_vertexlist[i].tex.y;
} fin.close();
return true;
} bool modelclass::Loadtexture(LPCWSTR file,ID3D11Device* device)
{
D3DX11CreateShaderResourceViewFromFile(device, file, NULL, NULL, &m_Texture, NULL);
return true;
} void modelclass::Render(ID3D11DeviceContext* context, XMMATRIX& viewmatrix, XMMATRIX& pro, D3D11_PRIMITIVE_TOPOLOGY geometry,
ID3D11VertexShader* vertexshader,ID3D11PixelShader* pixelshader)
{
UINT stride = sizeof(vertex);
UINT offset = ;
context->IASetVertexBuffers(,,&m_vertexBuffer,&stride,&offset);
context->IASetIndexBuffer(m_indexBuffer, DXGI_FORMAT_R16_UINT, );
context->IASetPrimitiveTopology(geometry); constantBuffer cb;
XMMATRIX worldmatrix = m_worldMatrix;
XMMATRIX promatrix = pro;
cb.world = XMMatrixTranspose(worldmatrix);
cb.view = XMMatrixTranspose(viewmatrix);
cb.pro = XMMatrixTranspose(promatrix); context->UpdateSubresource(m_constantBuffer, , NULL, &cb, , ); context->VSSetShader(vertexshader, NULL, );
context->VSSetConstantBuffers(, , &m_constantBuffer);
context->PSSetShader(pixelshader, NULL, ); context->PSSetShaderResources(, , &m_Texture);
context->PSSetSamplers(, , &m_samplerstate);
context->DrawIndexed(m_vertexCount, , );
} void modelclass::Setposition(float x, float y, float z)
{
m_worldMatrix = XMMatrixTranslation(x, y, z);
} void modelclass::RotationAxis(XMVECTOR axis, float angle)
{
m_worldMatrix *= XMMatrixRotationAxis(axis, angle);
} void modelclass::Shutdown()
{
if (m_samplerstate)
{
m_samplerstate->Release();
}
if (m_constantBuffer)
{
m_constantBuffer->Release();
}
if (m_indexBuffer)
{
m_indexBuffer->Release();
}
if (m_vertexBuffer)
{
m_vertexBuffer->Release();
}
if (m_Texture)
{
m_Texture->Release();
}
if (m_vertexlist)
{
delete[] m_vertexlist;
m_vertexlist = ;
}
}
initialize():
- 调用私有方法加载模型和纹理。加载完模型后,顶点列表,顶点个数已经有值了;加载完纹理后,纹理资源视图也有值了。
- 填充顶点缓存描述数据结构,将顶点列表填充到源数据数据结构的pSysmem字段,然后根据顶点描述数据结构和源数据数据结构创建顶点缓存
- for循环填充索引,填充索引缓存描述数据结构,填充源数据数据结构,创建索引缓存
- 填充常量缓存描述数据结构,并创建常量缓存
- 填充取样器描述数据结构,并创建取样器状态
私有方法Loadmodel():
从磁盘读取一个文件,该文件包含顶点信息,顶点个数该文件如下
Vertex Count: 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():
这两个方法只是作用于世界转换矩阵,没什么好说的,他们就是用来将模型翻转或平移的
C++小项目:directx11图形程序(七):modelclass的更多相关文章
- C++小项目:directx11图形程序(一):主框架
最近在学习DIRECTX11,在学习过程中编写了一个程序,到现在发现这个程序也有几行代码了,结构还算整齐,就想把这个程序分享出来,其中涉及到了C++程序的架构,windows窗口程序编写,和Direc ...
- C++小项目:directx11图形程序(四):d3dclass
主菜终于来了.这个d3dclass主要做的工作是dx11图形程序的初始化工作,它将创建显示表面交换链,d3d设备,d3d设备上下文,渲染目标表面,深度模板缓存:设置视口,生成投影矩阵. D3D设备:可 ...
- C++小项目:directx11图形程序(九):总结
整篇文章中对于directx11的知识的介绍并不多,我也不知道怎么介绍,也应该说对于directx,它有它自己的部分,比如设备(device),设备上下文(devicecontext),顶点缓存,索引 ...
- C++小项目:directx11图形程序(三):graphicsclass
这是框架的第三层graphicsclass,这个类才真正可以说是整个程序的框架,因为它组织了后面所有的成员. 代码: graphicsclass.h #pragma once #include< ...
- C++小项目:directx11图形程序(八):particleSysclass
粒子系统类,粒子系统是游戏里细小元素的控制系统,虽然感觉上它对游戏的影响不大,但是其实有了它能给游戏增色不少.粒子系统控制着细小元素的生死,运动,纹理.对它的编写让我知道,游戏里的这一片从天空飘落的雪 ...
- C++小项目:directx11图形程序(二):systemclass
先上代码: systemclass.h #pragma once #include"graphicsclass.h" const bool FULLSCREEN = true; c ...
- C++小项目:directx11图形程序(六):cameraclass
cameraclass是一个相机类,它的作用是生成非常重要的观察矩阵.本小节涉及到一点数学知识,相对前面需要只是填充,调用,算是比较有趣的吧. cameraclass.h #pragma once # ...
- C++小项目:directx11图形程序(五):shadersclass
这个类是用来创建着色器并设置输入布局的. 这个类比较特殊,它创建的着色器与Effect文件有关,effect文件是用高级着色语言(hlsl)编写的. shadersclass.h #pragma on ...
- Android小项目之七 应用程序的更新安装
------- 源自梦想.永远是你IT事业的好友.只是勇敢地说出我学到! ---------- 按惯例,写在前面的:可能在学习Android的过程中,大家会和我一样,学习过大量的基础知识,很多的知识点 ...
随机推荐
- quantile normalization原理
对于芯片或者其它表达数据来说,最常见的莫过于quantile normalization啦. 那么它到底对我们的表达数据做了什么呢?首先要么要清楚一个概念,表达矩阵的每一列都是一个样本,每一行都是一个 ...
- bean找不到异常
和这种的 原因: 这些都是因为bean注入的时候没有找个要注入的bean 解决办法: 1.查看dubbo文件中,暴露接口是否引入bean 2.如果有引入,查看引入路径和类是否存在.
- WinForm开发框架【细化权限至操作按钮】
有不少园友经常问我程序有没有更新,真的很抱歉,最近因为工作原因一直很忙,导致程序有很长时间都没有更新了,首先在这里感谢关心俺的朋友们. 这几天好好看了一下原来的程序,还有很多地方需要改进,比如操作数据 ...
- Sprint(第九天11.22)
- Latex引用插图格式制定问题(1)
自定义新命令\reffig如下:\newcommand{\reffig}[1]{Figure \ref{#1}}在需要引用图片的时候,用\reffig代替\ref,就可以自动在图号前面输出" ...
- 《BI那点儿事—数据的艺术》目录索引
原创·<BI那点儿事—数据的艺术>教程免费发布 各位园友,大家好,我是Bobby,在学习BI和开发的项目的过程中有一些感悟和想法,整理和编写了一些学习资料,本来只是内部学习使用,但为了方便 ...
- RealSense开发-搭建C#开发环境
一.前言 RealSense的开发环境主要包括如下几部分: 硬件:RealSense摄像头(此处以SR300为例)+搭载Intel酷睿6代处理器的PC机(其实4代处理器也能跑起来): 软件:Windo ...
- ajax请求总是进入Error里
ajax请求时找到了正确的地址,执行完返回总是进入error里,并且浏览器错误显示是找不到请求的地址. 解决办法: 查看配置文件的,把maxJsonLength值改大. <system.web. ...
- 浏览器Range,Selection等选中文本对象
Range对象 Range 对象表示文档的连续范围区域,如用户在浏览器窗口中用鼠标拖动选中的区域. 最常见的Range是用户文本选择范围(user text selection).当用户选择了页面上的 ...
- Spring集成Hibernate映射文件的4种方式
概要: 在Spring的applicationContext.xml中集成Hibernate映射文件,通常是在<sessionFactory>这个Bean实例中进行的,若配置的映射文件较少 ...