常量缓冲区和索引缓冲区
前言
在上篇文章中,我们成功在程序中心渲染了一个三角形。我们创建顶点缓冲区时,我们使用顶点位置直接在投影空间,这样我们就不必执行任何变化,就可以在屏幕上输出。但是我们如果想让物体在D3D中动起来,必须就在每一帧前把顶点缓冲中的数据变成物体动完后再投影空间。但是那样太麻烦了,我们应该输入的就是模型空间的位置,再在着色器中变换位置以造成动画效果。在本篇中,我们了解一些新知识用来实现我们的效果。
修改常量缓冲区
由于我们开始动起来,所以我们实际上就进入了3D空间。因此我们将之前的平面三角形更改为3维物体立方体。
// ******************
// 设置立方体顶点
// 5________ 6
// /| /|
// /_|_____/ |
// 1|4|_ _ 2|_|7
// | / | /
// |/______|/
// 0 3
VertexPosCol vertices[] =
{
{ XMFLOAT3(-1.0f, -1.0f, -1.0f), XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f) },
{ XMFLOAT3(-1.0f, 1.0f, -1.0f), XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f) },
{ XMFLOAT3(1.0f, 1.0f, -1.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
{ XMFLOAT3(1.0f, -1.0f, -1.0f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f) },
{ XMFLOAT3(-1.0f, -1.0f, 1.0f), XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f) },
{ XMFLOAT3(-1.0f, 1.0f, 1.0f), XMFLOAT4(1.0f, 0.0f, 1.0f, 1.0f) },
{ XMFLOAT3(1.0f, 1.0f, 1.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f) },
{ XMFLOAT3(1.0f, -1.0f, 1.0f), XMFLOAT4(0.0f, 1.0f, 1.0f, 1.0f) }
};如果你注意到,实际上我知识指定了立方体的8个顶点,我们并没有描述各个三角形。如果我们原样输入,我们是无法得到我们想要的结果的。
在立方体上,许多三角形共享相同的顶点,如果一遍又一遍的定义三角形的顶点将会浪费空间。因此,有一个方法只指定八个点,然后让D3D知道要为三角形选择哪些点。这就是索引缓冲区完成的。
索引缓冲区
使用索引缓冲区代替指定顺序绘制,可以有效减少顶点缓冲区占用的空间。避免提供大量重复的顶点数据。
索引数组初始化
// 索引数组
WORD indices[] = {
// 正面
0, 1, 2,
2, 3, 0,
// 左面
4, 5, 1,
1, 0, 4,
// 顶面
1, 5, 6,
6, 2, 1,
// 背面
7, 6, 5,
5, 4, 7,
// 右面
3, 2, 6,
6, 7, 3,
// 底面
4, 0, 3,
3, 7, 4
};然后填充缓冲区描述信息并创建索引缓冲区
D3D11_BUFFER_DESC ibd = {};
ibd.Usage = D3D11_USAGE_DEFAULT;
ibd.ByteWidth = sizeof(indices);
ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;
ibd.CPUAccessFlags = 0;
D3D11_SUBRESOURCE_DATA initData = {};
initData.pSysMem = indices;
g_pD3D11Device->CreateBuffer(&ibd, &initData, g_pIndiceBuffer.GetAddressOf()))就像顶点缓冲区一样,我们得到索引缓冲区后,还需要把它绑定到渲染管道上。
void ID3D11DeviceContext::IASetIndexBuffer(
ID3D11Buffer *pIndexBuffer, // [In]索引缓冲区
DXGI_FORMAT Format, // [In]数据格式
UINT Offset); // [In]字节偏移量其中Format
所以我们这里示例如下;
g_pImmediateContext->IASetIndexBuffer(g_pIndiceBuffer.Get(), DXGI_FORMAT_R16_UINT, 0);
修改顶点着色器
我们需要在顶点着色器内完成一个顶点从模型空间转换到

京公网安备 11010502036488号