[D3D] - DirectX SDK 2006学习笔记3——索引缓冲

来源:http://www.cnblogs.com/fence/archive/2010/03/12/1683918.html

 

  索引缓冲Index Buffer是由用户定义的,用来告诉D3D渲染顶点顺序的WORD或者DWORD数组。
索引缓冲离不开顶点缓冲,但是顶点缓冲却不一定需要索引缓冲。创建索引缓冲的过程和创建顶点缓冲类似,首先是声明,然后在OnCreateDevice中初始化和创建,在OnFrameRender中渲染,在OnDestroyDevice中销毁。相关代码如下:
声明:
    
      
LPDIRECT3DINDEXBUFFER9 g_pIB = NULL; // Buffer to hold indeces

 


OnCreateDevice():
   
     
   HRESULT hr;
V_RETURN( g_DialogResourceManager.OnCreateDevice( pd3dDevice ) );
V_RETURN( g_SettingsDlg.OnCreateDevice( pd3dDevice ) );
// Initialize the font
V_RETURN( D3DXCreateFont( pd3dDevice, 15 , 0 , FW_BOLD, 1 , FALSE, DEFAULT_CHARSET,
OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH
| FF_DONTCARE,
L
" Arial " , & g_pFont ) );
// Initialize vertices for rendering a triangle
CUSTOMVERTEX vertices[] =
{
{
0.0f , 0.0f , 0.5f , 1.0f , 0xffff0000 , }, // x, y, z, rhw, color
{ ( float )pBackBufferSurfaceDesc -> Width, 0.0f , 0.5f , 1.0f , 0xff00ff00 , },
{ (
float )pBackBufferSurfaceDesc -> Width, ( float )pBackBufferSurfaceDesc -> Height, 0.5f , 1.0f , 0xffff00ff , },
{
0.0f , ( float )pBackBufferSurfaceDesc -> Height, 0.5f , 1.0f , 0xff0000ff , },
};
// Create the vertex buffer
V_RETURN( pd3dDevice -> CreateVertexBuffer( sizeof (vertices),
0 , D3DFVF_CUSTOMVERTEX,
D3DPOOL_MANAGED,
& g_pVB, NULL ) );
VOID
* pVertices;
V_RETURN( g_pVB
-> Lock( 0 , sizeof (vertices), ( void ** ) & pVertices, 0 ) );
memcpy( pVertices, vertices,
sizeof (vertices) );
g_pVB
-> Unlock();
// Initialize index buffer for rendering
WORDwIndeces[] = { 0 , 1 , 2 , 0 , 2 , 3 };
// Create the index buffer
V_RETURN( pd3dDevice -> CreateIndexBuffer( sizeof (wIndeces),
0 , D3DFMT_INDEX16,
D3DPOOL_MANAGED,
& g_pIB, NULL) );
VOID
* pIndeces;
V_RETURN( g_pIB
-> Lock( 0 , sizeof (wIndeces), & pIndeces, 0 ) );
memcpy( pIndeces, wIndeces,
sizeof (wIndeces) );
g_pIB
-> Unlock();
returnS_OK;
OnRender中BeginScene和EndScene之间
pd3dDevice
-> SetStreamSource( 0 , g_pVB, 0 , sizeof (CUSTOMVERTEX) );
pd3dDevice
-> SetFVF( D3DFVF_CUSTOMVERTEX );
pd3dDevice
-> SetIndices( g_pIB );
// pd3dDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, 2 );
pd3dDevice -> DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0 , 0 , 4 , 0 , 2 );
OnDestroyDevice
SAFE_RELEASE( g_pVB );
SAFE_RELEASE( g_pIB );

下面是这段代码的效果图:
[D3D] - DirectX SDK 2006学习笔记3——索引缓冲
挺PP的吧?
这段代码和顶点缓冲最重要的不同在于DrawIndexedPrimitive函数。这个函数的使用方法请看下面的例子(整理自SDK文档Rendering from Vertex and Index Buffers):
Scenario 1:画两个没有索引缓冲的三角形(为了方便现在仅列出三维坐标的x,y值,下同)
[D3D] - DirectX SDK 2006学习笔记3——索引缓冲
  左图上的正方形由两个三角形组成,从右图可以看出顶点缓冲程序采用了TRIANGLELIST的图元方式分别画出了两个三角形,代码如下:
   
     
DrawPrimitive( D3DPT_TRIANGLELIST, // PrimitiveType
0 , // StartVertex
2 ); // PrimitiveCount


Scenario 2:用索引缓冲画两个三角形
[D3D] - DirectX SDK 2006学习笔记3——索引缓冲
  右边图的是顶点缓冲,和场景1相比少了两个重复定义的顶点,左边的数组就是索引缓冲,方框中的数字就是右边顶点缓冲的编号,其中顶点0, 1, 2构成一个独立的三角形,顶点3, 0, 2独立构成另一个独立的三角形,代码如下:
   
     
DrawIndexPrimitive( D3DPT_TRIANGLELIST, // PrimitiveType
0 , // BaseVertexIndex
0 , // MinIndex
4 , // NumVertices
0 , // StartIndex
2 ); // PrimitiveCount

 


  函数由DrawPrimitive换成了DrawIndexPrimitive,图元类型仍然为TRIANGLELIST。图元数仍然为2。
Scenario 3:使用索引渲染一个三角形
[D3D] - DirectX SDK 2006学习笔记3——索引缓冲
  这次需求变更,但是仍然想用上面的索引缓冲和顶点缓冲怎么办呢?具体来说,我们只想要画由顶点0, 2, 3构成的三角形。研究DrawIndexPrimitive之后发现只要这样调用就可以了:
   
     
DrawIndexPrimitive( D3DPT_TRIANGLELIST, // PrimitiveType
0 , // BaseVertexIndex
0 , // MinIndex
4 , // NumVertices
3 , // StartIndex
1 ); // PrimitiveCount

 


  StartIndex为3,就是说从第三个元素开始使用索引缓冲,上图中第三个元素对应的正好是顶点3。图元数为1,因为我们只需要画一个三角形。顶点个数仍然为4。
Scenario 4:使用索引缓冲的Offset渲染一个三角形
   [D3D] - DirectX SDK 2006学习笔记3——索引缓冲
   假如一个顶点缓冲特别大,顶点的标号已经达到50, 51, 52, 53这样的数字,我们可以通过填写Offset的方法来调用DrawIndexPrimitive。上图的情况只要将Offset这个参数设为50,就可 以达到不变更上几例中的索引缓冲内容的目的。这种情况下,中间一幅图描述的索引信息就等同于左边的索引信息,而下面函数渲染出的图形就是由顶点53, 50, 52构成的三角形。
   
     
DrawIndexPrimitive( D3DPT_TRIANGLELIST, // PrimitiveType
50 , // BaseVertexIndex
0 , // MinIndex
4 , // NumVertices
3 , // StartIndex
1 ); // PrimitiveCount

 

你可能感兴趣的:(学习笔记)