既然每个顶点已经被明确定义了,并且没有任何两个三角形没有共享边缘,这是考虑到使用三角形列。总之,包含12个三角形的三角列,我们需要36个顶点。
顶点索引缓冲区的创建跟顶点缓冲区的创建类似。我们提供指定的参数,比如一个结构体包含大小和类型,然后创建缓冲区。这个类型是D3D11_BIND_INDEX_BUFFER。既然我们使用DWORD来申请数组,那我们用sizeof(DWORD)。
D3D11_BUFFER_DESC bd; ZeroMemory( &bd, sizeof(bd) );
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof( WORD ) * 36; // 36 vertices needed for 12 triangles in a triangle list
bd.BindFlags = D3D11_BIND_INDEX_BUFFER; bd.CPUAccessFlags = 0; bd.MiscFlags = 0;
InitData.pSysMem = indices;
if( FAILED( g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pIndexBuffer ) ) ) return FALSE;
一旦我们创建好缓冲区,我们就要去设置它,以至于Direct3D能知道如何去使用索引缓冲区来获得三角形。我们指定顶点的缓冲区,格式,和偏移量。代码如下:
// Set index buffer
g_pImmediateContext->IASetIndexBuffer( g_pIndexBuffer, DXGI_FORMAT_R16_UINT, 0 );
改写顶点渲染器
在前面教程中的顶点渲染器,我们以顶点坐标为输入,以相同的顶点坐标为输出,没有进行任何的修改。我们能够完成这个是因为输入的顶点坐标已经被定义在投影空间内。现在,因为我们的顶点是被定义在对象空间。在顶点渲染器输出之前,必须对顶点进行变换。我们需要3个步骤:将对象空间转换到世界空间,然后转换到观察空间,最后转换到投影空间。我们第一件事要做的是申请静态的缓冲变量。静态缓冲区用来保存应用程序需要传入渲染器的数据。在渲染之前,应用程序通常将重要的数据写入静态缓冲区,并且在渲染数据期间西欧哪个渲染器中可以获取这些数据。在一个FX文件中,静态缓冲变量就像C++结构体中的全局变量。我们要用的者3个变量分别是世界矩阵,观察矩阵,投影矩阵,在HLSL中,他们的数据类型为matrix。
一旦我们清楚了我们所需要的矩阵,我们利用这些矩阵里运行顶点渲染器来处理输入的坐标数据。一个向量将被矩阵中多个向量变换。在HLSL,通过使用内置函数mul()。代码如下: cbuffer ConstantBuffer : register( b0 ){ matrix World; matrix View;
matrix Projection; } //
// Vertex Shader //
VS_OUTPUT VS( float4 Pos : POSITION, float4 Color : COLOR ){
VS_OUTPUT output = (VS_OUTPUT)0; output.Pos = mul( Pos, World );
output.Pos = mul( output.Pos, View );
output.Pos = mul( output.Pos, Projection ); output.Color = Color; return output; }
在这个顶点渲染器中,每个mul()函数应用一个变换作用于输入坐标。按顺序使用世界矩阵,观察矩阵,投影矩阵。这个顺序是固定的,不允许交换。 设置矩阵
通过使用这些矩阵,我们可以更新我们的顶点渲染器,但我们也需要在程序中定义这三个矩阵。在渲染的时候,这3个矩阵保存着我们需要使用的变换。在渲染之前,我们将这3个矩阵的值复制到渲染器的静态缓冲区。然后,通过调用Draw()来启动渲染,我们的顶点渲染器从静态缓冲区读出矩阵数据。除了这些矩阵,我们还需要一个ID3D11Buffer对象来表示静态缓冲区。代码如下:
ID3D11Buffer* g_pConstantBuffer = NULL; XMMATRIX g_World; XMMATRIX g_View;
XMMATRIX g_Projection;
为了创建ID3D11Buffer对象,我们使用ID3D11Device::CreateBuffer(),并指定 D3D11_BIND_CONSTANT_BUFFER。
D3D11_BUFFER_DESC bd; ZeroMemory( &bd, sizeof(bd) );
bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = sizeof(ConstantBuffer);
bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; bd.CPUAccessFlags = 0;
if( FAILED(g_pd3dDevice->CreateBuffer( &bd, NULL, &g_pConstantBuffer ) ) ) return hr;
接下来我们需要做的就是利用这3个矩阵进行变换。我们要让三角形设置在原点,并平行于XY平面。那么相对于对象空间,这些顶点要如何保存呢?所以世界变换不需要做任何事情,我们只需要把世界矩阵设置为单位矩阵即可。我们要设置摄像机的位置在(0,1,-5),看着(0,1,0)点,向上的向量为(0,1,0)。我们调用 XMMatrixLookAtLH()函数来方便地计算出观察矩阵。我们习惯Y轴的正方向为向上的方向。最后,计算投影矩阵,我们调用XMMatrixPerspectiveFovLH()函数,以90°的垂直视野(即pi/2),aspect宽高比为640/480,这个数据来自背景缓冲区的宽高。Zn=0.1,Zf=110,。这意味着任何事物力摄像机的距离小于0.1或者大于110将视为不可见。这三个矩阵分别保存在全局变量g_World, g_View, and g_Projection上。 更新静态缓冲区
相关推荐: