DirectX11SDK文档三 directx sdk

总结

在前面的教程中,我们创建了一个小型的,能够显示单颜色的窗口的Direct3D11应用程序。在这个教程中,我们将扩展这个应用程序将一个三角形显示在屏幕上,我们将贯穿这个过程来创建关于三角形的数据结构。效果如上图。

三角形的元素

一个三角形由三个点组成,也可以叫做顶点。用一个顶点数组来定义一个三角形,为了GPU能够渲染这个三角形,我们必须告诉GPU三角形的三个顶点的坐标。以2D为例,对我们来讲很容易就可以渲染一个像图1那样的三角形。我们要向GPU传送三个顶点(0,0),(0,1),(1,0),这样GPU有足够的信息来渲染我们想要的三角形。

所以,我们现在知道我们必须传三个顶点坐标给GUP来渲染一个三角形。那我们要如何传这些信息给GPU呢?在Direct3D11中,向顶点信息(如坐标)叫保存在一个缓冲区资源内。如果一个缓冲区用来存放顶点信息,那么它就叫做顶点缓冲区。我们必须创建一个足够大的顶点缓冲区来保存者三个顶点坐标。在Direct3D11中,创建一个顶点缓冲区必须指定大小(以byte为单位)。我们知道这个缓冲区有足够的空间来存放这个顶点,但是每个顶点有多少byte呢?回答好这个问题之前,我们需要知道顶点格式。

Input Layout

一个顶点有一个坐标信息。但通常不仅仅只有顶点信息,它也可能有其他的属性。比如:向量,多个的颜色,纹理坐标等等。顶点格式将定义这些属性在内存中如何存放:每个数据属性的用法,每个数据属性的大小,还有属性之间的排列。由于属性通常有不同的类型,类似于C中的结构体,一个顶点通常用一个结构体表示。可以方便地根据一个结构体的大小来获取顶点的大小。

在这个教程中,我们只使用到坐标信息,所以我们的顶点结构体只声明一个XMFLOAT3,XMFLOAT3由三个浮点数组成,它的典型应用就是3D内表示坐标。

structSimpleVertex{
XMFLOAT3 Pos; // Position
};

现在我们有一个结构体来表示我们的顶点。在应用程序中要保存好这些顶点信息。然而,当我们需要GPU渲染包含这些顶点的顶点缓冲区的时候,我们要将它填入一个内存块中。GPU也必须知道顶点格式,以便于从缓冲区中提取顶点信息。完成这个需要了解inputlayout。

在Direct3D 11中,inputlayout是Direct3D对象,它能以一种GPU能够理解的方式来描述顶点结构体。每个顶点属性能够用D3D11_INPUT_ELEMENT_DESC结构体来描述。一个应用程序定义一个或多个的D3D11_INPUT_ELEMENT_DESC结构体数组。使用这些数组来创建inputlayout对象来描述顶点。D3D11_INPUT_ELEMENT_DESC结构体细节如下:

SemanticName

SemanticName是一个用来描述属性的字符串。这个字符串表示一个单词,这个单词可以使用C能够定义的任何格式。目前对于描述position属性的一个好的SemanticName是POSITION。SemanticName不区分大小写。

SemanticIndex

SemanticIndex补充SemanticName。一个顶点可能有多个属性是一样的。比如:有两组纹理坐标或者有两组颜色,用数字来代替SemanticName的使用,比如:”COLOR0”和”COLOR1”。这两个元素可以共享一个SemanticName—“COLOR”,使用0和1这两个不同的索引。

Format

元素使用Format定义了数据类型。目前,DXGI_FORMAT_R32G32B32_FLOAT数据格式有3个32位的浮点数,使这个元素有12字节大小。DXGI_FORMAT_R16G16B16A16_UINT有4个16字节无符号整型数,使这个元素8字节大小。

InputSlot

根据以前的方法,一个Direct3D11应用程序通过使用顶点缓冲区的方式把顶点数据传给GPU,Direct3D11在中,多种顶点缓冲区能够同时被传入GPU,确切的说是16种。每种顶点缓冲区将有一个数值在[0,15]绑定到Inputslot。这个InputSlot告诉GPU可以从哪个顶点缓冲区获取这个元素。

AlignedByteOffset

一个顶点保存在一个顶点缓冲区中,这个顶点缓冲区是一块连续的内存。AlignedByteOffset告诉GPU偏移量来获取这个元素。

InputSlotClass

这个通常保存有D3D11_INPUT_PER_VERTEX_DATA。当一个应用程序使用Instancing时,它能够设置一个inputlayout的InputSlotClass到D3D11_INPUT_PER_INSTANCE_DATA与包含实例数据的顶点缓冲区一起工作,Instancing是一个超前的Direct3D话题,并且不会这里做深入讨论。对于我们的教程,我们将专门使用D3D11_INPUT_PER_VERTEX_DATA。

InstanceDataStepRate

这个用于Instancing,既然我们没有使用Instancing,InstanceDataStepRate没有被用到,所以必须设置为0

现在我们能够定义我们的D3D11_INPUT_ELEMENT_DESC数组并且创建input layout:

// Define the input layout
D3D11_INPUT_ELEMENT_DESC layout[] ={
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0,D3D11_INPUT_PER_VERTEX_DATA, 0},
};
UINT numElements = ARRAYSIZE(layout);

顶点格式

在下一个教程,我们将解释这个技术对象和渲染器。现在,我们把注意力集中在创建Direct3D11顶点格式对象。然而,我们将了解到顶点渲染器将紧密地跟顶点格式联系在一起。原因在于创建一个顶点格式对象需要顶点渲染器的输入签名,我们将使用D3DX11CompileFromFile函数所返回的ID3DBlob对象来检索二进制数据,该二进制数据代表顶点渲染器的输入签名。一旦我们获得这个数据,我们就能够调用ID3D11Device::CreateInputLayout()函数来创建顶点格式对象,和调用ID3D11DeviceContext::IASetInputLayout()来激活这个顶点格式。代码如下:

// Create the input layout
if( FAILED( g_pd3dDevice->CreateInputLayout( layout,numElements,pVSBlob->GetBufferPointer(),
pVSBlob->GetBufferSize(),&g_pVertexLayout ) ) )
return FALSE;
// Set the input layout
g_pImmediateContext->IASetInputLayout(g_pVertexLayout );

创建顶点缓冲区

还有一件事在初始化时候要做的是创建顶点缓冲区保存顶点数据。在Direct3D11中,为了创建一个顶点缓冲区,我们要填充两个结构体D3D11_BUFFER_DESC和D3D11_SUBRESOURCE_DATA,然后调用ID3D11Device::CreateBuffer()函数。D3D11_BUFFER_DESC描述要创建的顶点缓冲区对象。在顶点缓冲区创建的时候,D3D11_SUBRESOURCE_DATA描述在将要复制到顶点缓冲区的实际数据。顶点缓冲区在创建的时候初始化,所以之后我们就不要再初始化。将要复制到顶点缓冲区的数据是顶点数组,是3个SimpleVertex结构体的数组,顶点数组中坐标的选择是为了让三角形能显示在窗口的中央。顶点缓冲区创建之后,我们可以调用ID3D11DeviceContext::IASetVertexBuffers()将它绑定到device上。代码如下:

// Create vertex buffer
SimpleVertex vertices[] ={
XMFLOAT3( 0.0f, 0.5f, 0.5f ),
XMFLOAT3( 0.5f, -0.5f, 0.5f),
XMFLOAT3( -0.5f, -0.5f, 0.5f ),
};
D3D11_BUFFER_DESC bd;
ZeroMemory( &bd, sizeof(bd) );
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof( SimpleVertex ) * 3;
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = 0;
bd.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA InitData;
ZeroMemory( &InitData, sizeof(InitData) );
InitData.pSysMem = vertices;
if( FAILED( g_pd3dDevice->CreateBuffer(&bd, &InitData,&g_pVertexBuffer ) ) )
return FALSE;
// Set vertex buffer
UINT stride = sizeof( SimpleVertex );
UINT offset = 0;
g_pImmediateContext->IASetVertexBuffers( 0, 1,&g_pVertexBuffer, &stride,&offset );

Primitive Topology

PrimitiveTopology是关于GPU如何获得要渲染三角形的3个顶点。我们上面讨论的都是如何让渲染一个简单三角形,应用程序需要传送这个3个顶点给GPU。所以,顶点缓冲区保存有3个顶点信息。那如果我们想要渲染两个三角形,该如何做呢?一种办法就是向GPU发送6个顶点。前3个顶点定义第一个三角形,后三个顶点定义第二个三角形,这个Topology叫做三角形列。三角形列是比较好理解的,当然它并不高效。这些例子能够成功地渲染三角形。目前为止图3a显示了一个矩形由两个三角形组成:ABC和CBD(按照惯例,以顺时针的顺序依次组成三角形列)。如果我们以三角形列的方式发送这两个三角形给GPU。我们的顶点应该这样定义:

A B C C B D

注意:B和C在顶点缓冲区中出现了两次,因为他们分别被两个三角形使用。

我们能够使顶点缓冲区更小,如果告诉GPU在渲染第二个三角形的时候,重复使用第一个三角形的最后两个顶点,然后再加上接下来的一个顶点组成第二个三角形。Direct3D支持这种格式,它叫做三角形带。当渲染一个三角形带时,第一个三角形由顶点数组的前三个顶点定义,那个接下来的三角形由前一个三角形的最后两个顶点和接下来的一个顶点定义。那么顶点应该这样定义:

A B C D

前三个顶点,即A B C定义第一个三角形。第二个三角形由BC(第一个三角形的最后两个顶点)加上D来定义。那个通过使用三角带,我们的顶点缓冲区从之前的6个顶点缩小为现在的4个顶点。

同理如图3b,使用三角列的话,顶点定义如下:ABC CBD CDE

如果使用三角带的话,顶点定义如下:A B C D E

你可能会注意到三角带的例子中,第二个三角形是由B CD来定义,这三个顶点的排列不是顺时针方向。使用三角形带时这是很正常的现象。这种现象只出现在第二个三角形,第四个三角形,第六个三角形,第八个三角形等等。这就确保了每个三角形的顶点都能够绕顺时针方向(顺时针,在这个例子中)。除了三角形列和三角形带,还有其他一些Direct3D支持的PrimitiveTopology,在这个教程上不做讨论。

在我们的代码里,我们只需要一个三角形,所以我们用三角形列还是三角形带都可以。但是它必须定义,所以我们使用三角形列。

// Set primitive topology
g_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );

渲染三角形

最后的代码就是如何渲染这个三角形。我们已经创建了两个渲染器用于渲染,顶点渲染器和像素渲染器。顶点渲染器负责将三角形的各个顶点变换到正确的位置。像素渲染器负责三角形内部的最后输出颜色的计算。这个将在下一个教程详细讲解。为了使用这两个渲染器,我们必须分别调用ID3D11DeviceContext::VSSetShader()函数和ID3D11DeviceContext::PSSetShader()函数。最后我们要做的就是调用ID3D11DeviceContext::Draw()函数,该函数命令GPU使用当前的顶点缓冲区,当前的顶点格式,当前的primitivetopology进行渲染。Draw()的第一个参数要传给GPU的顶点个数。第二个参数表示顶点缓冲区的起始索引。因为我们要渲染一个三角形,并且我们从顶点缓冲区的0位置开始。我们分别用3和0来填充这两个参数。代码如下:

//Render a triangle
DirectX11SDK文档(三) directx sdk
g_pImmediateContext->VSSetShader( g_pVertexShader,NULL, 0 );
g_pImmediateContext->PSSetShader( g_pPixelShader,NULL, 0 );
g_pImmediateContext->Draw( 3, 0 );

  

爱华网本文地址 » http://www.aihuau.com/a/25101013/156077.html

更多阅读

用Word2003也能给文档加上稿纸 word2003稿纸模板

在Office XP中,可以使用“稿纸向导”将文档以稿纸方式打印出来,但在Word 2003中,却没有提供这一功能。不过,微软提供了另外一种方法来实现稿纸打印,通过下载并安装一个“Microsoft Office Word 2003 稿纸加载项”,即可使用稿纸功能。使用

Word文档中如何设置页码 word2007怎么设置页码

Word文档中如何设置页码——简介Word文档中插入页码是办公的基本操作,利用微软Office所提供的强大页码功能,我们可以实现丰富多样的页码格式。以下小编将为大家讲解一下在Word中插入页码的方法。Word文档中如何设置页码——工具/原料

Word文档如何添加删除线 word 结束线

Word文档如何添加删除线——简介怎样给Word文档添加删除线,添加单条删除线,添加两条删除线本经验说明:小编使用的是2013版本的office 的word,其它版本的word可能有些差异,请根据实际版本来进行操作。Word文档如何添加删除线——工具/

怎么复制百度文库的文档 自动取款机打印凭条

怎么复制百度文库的文档——简介百度文库是无法复制的,如果我们想复制该怎么办呢?其实很简单,我们无须下载任何东西!就这个问题今天我写了篇经验,希望这篇经验能帮到大家!!!谢谢!!!!!怎么复制百度文库的文档——方法/步骤

Word 2003文件损坏而无法打开的修复方法 修复损坏的word文档

相信经常用word的朋友都遇到过这种情况:打开之前辛辛苦苦制作的word文档的时候,提示文件损坏无法打开。郁闷的要跳楼。今天就介绍一个方法来修复损坏的word文档,下面是具体的步骤。Word 2003文件损坏而无法打开的修复方法——步骤/方法

声明:《DirectX11SDK文档三 directx sdk》为网友瀟灑不迴头分享!如侵犯到您的合法权益请联系我们删除