`
yuanjinxiu
  • 浏览: 660541 次
文章分类
社区版块
存档分类
最新评论

3D游戏从入门到精通-12

 
阅读更多
1、 使用索引缓冲区
什么是索引缓冲区呢?其实索引缓冲区,就像指针一样的工具。顶点缓冲区里保存的是真实的顶点,而索引缓冲区只记录顶点缓冲区的顶点编号。比如顶点缓冲区里有4个顶点,而这4个顶点就可以构成两个三角形来显示。如果直接使用顶点缓冲区的话,就需要写6个顶点。这样就可以使用索引缓冲区,指明第一个三角形是由顶点编号1、2、3构成一个三角形,而第二个三角形就是1、3、4组成。
现在把上面的立方体改为使用索引缓冲区,先创建8个顶点,如下:
pVertices[0].vPosition = D3DXVECTOR3( -1.0f,-1.0f,-1.0f );
pVertices[1].vPosition = D3DXVECTOR3( -1.0f,1.0f,-1.0f );
pVertices[2].vPosition = D3DXVECTOR3( 1.0f,1.0f,-1.0f );
pVertices[3].vPosition = D3DXVECTOR3( 1.0f,-1.0f,-1.0f );
pVertices[4].vPosition = D3DXVECTOR3( -1.0f,1.0f,1.0f );
pVertices[5].vPosition = D3DXVECTOR3( 1.0f,1.0f,1.0f );
pVertices[6].vPosition = D3DXVECTOR3( 1.0f,-1.0f,1.0f );
pVertices[7].vPosition = D3DXVECTOR3( -1.0f,-1.0f,1.0f );
这样,就可省下许多顶点占用的内存了,然后创建36个索引点的缓冲区,如下:
//创建索引缓冲区。
hr = m_pd3dDevice->CreateIndexBuffer( 12*3 *sizeof(WORD),
0, D3DFMT_INDEX16, D3DPOOL_DEFAULT,
&m_pIB, NULL );
if( FAILED( hr ) )
{
return E_FAIL;
}
上面创建了36个WORD大小的索引点,这样省了很多内存空间。由于顶点是由3个浮点数和其它值组成,肯定比两个字节索引值占用空间大。接着下来就是设置索引缓冲区,如下:
void* pIndices;
if( FAILED( m_pIB->Lock( 0,sizeof(WORD)*12*3, &pIndices,0 ) ) )
{
m_pIB->Release();
m_pIB = NULL;
return E_FAIL;
}
//
WORD* pIndex = reinterpret_cast<WORD*>(pIndices);
int nPos = 0;
//1
pIndex[nPos++] = 0;
pIndex[nPos++] = 1;
pIndex[nPos++] = 2;
pIndex[nPos++] = 0;
pIndex[nPos++] = 2;
pIndex[nPos++] = 3;
//2
pIndex[nPos++] = 1;
pIndex[nPos++] = 4;
pIndex[nPos++] = 2;
pIndex[nPos++] = 2;
pIndex[nPos++] = 4;
pIndex[nPos++] = 5;
//3
pIndex[nPos++] = 2;
pIndex[nPos++] = 5;
pIndex[nPos++] = 3;
pIndex[nPos++] = 3;
pIndex[nPos++] = 5;
pIndex[nPos++] = 6;
//4
pIndex[nPos++] = 0;
pIndex[nPos++] = 7;
pIndex[nPos++] = 1;
pIndex[nPos++] = 1;
pIndex[nPos++] = 7;
pIndex[nPos++] = 4;
//5
pIndex[nPos++] = 0;
pIndex[nPos++] = 3;
pIndex[nPos++] = 7;
pIndex[nPos++] = 3;
pIndex[nPos++] = 6;
pIndex[nPos++] = 7;
//6
pIndex[nPos++] = 4;
pIndex[nPos++] = 7;
pIndex[nPos++] = 5;
pIndex[nPos++] = 5;
pIndex[nPos++] = 7;
pIndex[nPos++] = 6;
//
m_pIB->Unlock();
上面这段代码,先Lock函数取得索引缓冲区地址,然后依次设置索引值,这里使用三角形列表,所以顶点顺序一样是按顺时针方向来设置的,也就是按左手坐标系来设置的。
接着下来,就需要渲染这个立方体了,如下:
m_pd3dDevice->SetStreamSource( 0, m_pVB, 0, sizeof(VT_CAICUBE) );
m_pd3dDevice->SetFVF( VT_CAICUBE::dwFVF );
m_pd3dDevice->SetIndices(m_pIB);
m_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,8,0,12);
上面代码先设置了8个顶点缓冲区到管道里,然后再调用SetIndices设置索引缓冲区,最后调用DrawIndexedPrimitive函数来显示所有三角形列表。DrawIndexedPrimitive函数的第一个参数是索引列表里的类型,第二个参数是索引缓冲区在顶点缓冲区里的起始位置,比如顶点缓区是0,1,3的,当设置这个值为50时,那么相当于访问了50,51,53的顶点值。第三个参数是最小索引值。第四个参数是有多少个顶点会使用。第五个参数是从那个索引值开始。第六个参数是基本图形个数。
通过这样学习,就学会使用了索引缓冲区,如果有很多顶点,有很多三角形,就需要使用优化的算法,以便有最少的顶点,使用最多的索引,这样有利于减少内存占用,提高带宽利用,提高显示卡显示更多图形,提高游戏的性能。
电子书MM3D引擎源程序例子源程序49元一套
联系人:蔡军生
联系方式:
QQ: 9073204
EMAIL: caimouse1976 at sina.com
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics