注:下面涉及的代码都基于这篇文章的内容
https://blog.csdn.net/Kurozaki_Kun/article/details/86709050
绘制过程
要在DX上绘制一个基本图形,大体流程有以下几步
- 给出输入布局(主要是描述顶点的格式)
- 给出描述几何体的顶点,索引,拓扑图元
- 加载并创建各种着色器
- 创建索引缓冲,顶点缓冲,以及必要的常量缓冲
- 将以上内容绑定到渲染管线,然后绘制
简单封装
主要针对于步骤2,绘制什么样的几何体应该需要做一下封装,我希望能够用一个结构体描述顶点,通过不同的函数为结构体填充顶点信息,然后根据结构体创建顶点缓冲,索引缓冲。
如下,定义一个结构体Shape3D
struct Shape3DVertex;
struct Shape3D;
#include "AppPublic.h"
struct Shape3DVertex // 顶点的结构
{
DirectX::XMFLOAT3 Pos; // 仅描述顶点的坐标
};
struct Shape3D // 图形的结构体
{
Shape3DVertex* VertexArrPtr;
UINT VertexNum;
WORD* IndexArrPtr;
UINT IndexNum;
~Shape3D()
{
delete[] VertexArrPtr;
delete[] IndexArrPtr;
}
};
填充几何体的顶点以及索引
这里分别演示如何创建长方体,圆柱,球体和正棱锥四种图形。声明下面函数
// 创建长方体
bool Shape3DCreateCuboid(float length, float width, float height, Shape3D* pShape);
//
// 创建圆柱
//
// diff 用于描述用正 n 边形拟合圆柱,其中 n = diff
//
bool Shape3DCreateCylinder(float radius, float height, UINT diff, Shape3D* pShape);
//
// 创建一个球
//
// radius: 半径
// longitude: 经线的数量
// latitude: 纬线的数量(不包含两极)
//
// 本算法可优化,做出 1/8 球面的顶点,然后利用对称性
//
bool Shape3DCreateBall(float radius, UINT longitude, UINT latitude, Shape3D* pShape);
//
// 创建一个正棱锥图形
//
bool Shape3DCreateRegularPyramid(float radius, float height, UINT sideNum, Shape3D* pShape);
接着是函数实现
bool Shape3DCreateCuboid(float length, float width, float height, Shape3D * pShape)
{
if (nullptr == pShape)
return false;
float x = length / 2;
float y = width / 2;
float z = height / 2;
DirectX::XMFLOAT3 poses[] =
{
DirectX::XMFLOAT3(-x, +y, +z),
DirectX::XMFLOAT3(+x, +y, +z),
DirectX::XMFLOAT3(+x, -y, +z),
DirectX::XMFLOAT3(-x, -y, +z),
DirectX::XMFLOAT3(-x, +y, -z),
DirectX::XMFLOAT3(+x, +y, -z),
DirectX::XMFLOAT3(+x, -y, -z),
DirectX::XMFLOAT3(-x, -y, -z),
};
WORD indexes[] =
{
3, 1, 0,
2, 1, 3,
0, 5, 4,
1, 5, 0,
3, 4, 7,
0, 4, 3,
1, 6, 5,
2, 6, 1,
2, 7, 6,
3, 7, 2,
6, 4, 5,
7, 4, 6,
};
pShape->IndexNum = ARRAYSIZE(indexes);
pShape->VertexNum = ARRAYSIZE(poses);
pShape->IndexArrPtr = new WORD[pShape->IndexNum];
pShape->VertexArrPtr = new Shape3DVertex[pShape->VertexNum];
// fill index array
memcpy(pShape->IndexArrPtr, indexes, sizeof(WORD)*pShape->IndexNum);
// fill vertex array
for (UINT i = 0; i < pShape->VertexNum; i++)
pShape->VertexArrPtr[i] = { poses[i] };
return true;
}
bool Shape3DCreateCylinder(float r, float h, UINT n, Shape3D * pShape)
{
if (nullptr == pShape)
return false;
if (n < 6) n = 6;
if (n > 64) n = 64;