今天北京下了一天的雨,而且是暴雨,不知道又有多少地方可以划船了,这么大的雨也打乱了我的搬家计划,不能搬家,那就写一篇小文吧,也是刚才没事浏览DX SDK文档时偶有所悟,非常简单,博大家一笑而。
Triangle Strips是D3D用来绘制三角形的一种方式,这种方式比Triangle list更加高效,因为不用重复存储三角形顶点。下面看一个例子,分析一下这两种方式的不同。
现在我们要绘制一个矩形,在D3D中,最基本的几何图元是三角形,所以可用两个三角形拼接成一个矩形,如下图。
使用Triangle list绘制
triangle list的工作方式是每次取三个顶点作为一组,绘制一个三角形。如果有n个三角形,那么依次取1,2,3为一组,4,5,6为一组, i, i + 1, i + 2为一组,如下图,如果一共有n个顶点,那么可以绘制n / 3个三角形。
所以为了绘制上面的矩形,我们一共需要六个顶点,见下图。V1,V2,V3绘制左上角的三角形,V2,V4,V3绘制右下角的三角形。这里,V2和V3被重复定义了(或者说重复存储了)。
定义顶点及绘制的核心代码如下
// 定义顶点 D3DXVECTOR3 vertex[] = { D3DXVECTOR3(-1.0f, 1.0f, 0), // 1 D3DXVECTOR3( 1.0f, 1.0f, 0), // 2 D3DXVECTOR3(-1.0f, -1.0f, 0), // 3 D3DXVECTOR3( 1.0f, 1.0f, 0), // 2 D3DXVECTOR3( 1.0f, -1.0f, 0), // 4 D3DXVECTOR3(-1.0f, -1.0f, 0), // 3 }; // 绘制矩形 g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
使用Triangle strip绘制
使用triangle strip则完全不必重复定义顶点,先来看看什么是triangle strip,图如下,实际上是一系列连着的三角形,即相邻的两个三角形有一条公用边。这意味着有些顶点时可以重复利用的,我们不必为每个三角形都指定独立的三个顶点,如下图,可以用七个顶点表示五个三角形。如果是triangle list方式,表示五个三角形则需要15个顶点。
triangle strip取三角形的方式略有不同,每次从编号为i的位置开始依次取三个,i=1,2,3,4。。。也就是1,2,3为一组,2,3,4为一组。i, i + 1, i + 2为一组,见下图。如果有n个顶点,那么可以绘制n - 2个三角形。
这种方式使得除了第一个和最后一个顶点外,所有的顶点都可以被重复利用,比如顶点V2,它既属于第一个三角形V1V2V3,又属于第二个三角形V2V3V4。所以为了绘制上面的矩形,我们只需要四个顶点。V1, V2, V3绘制左上角的三角形,V2, V4, V3绘制右下角的三角形。这里V2和V3是无需重复定义(或重复存储)的。
定义顶点和绘制的代码如下。
// 定义顶点 D3DXVECTOR3 vertex[] = { D3DXVECTOR3(-1.0f, 1.0f, 0), // 1 D3DXVECTOR3( 1.0f, 1.0f, 0), // 2 D3DXVECTOR3(-1.0f, -1.0f, 0), // 3 D3DXVECTOR3( 1.0f, -1.0f, 0), // 4 }; // 使用triangle strip方式绘制矩形 g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
除了顶点可以重复利用外,还有一个重要的区别就是绘制时的back face culling选项,如果使用triangle strip绘制,那么这个选项每绘制一个三角形就flip一次,什么意思呢?也就是说如果第一个三角形以CCW方式剔除,那么第二个三角形就以CW方式剔除,第三个三角形又以CCW方式剔除,第四个三角形以CW方式剔除,如此这般。。。这个特征需要我们在定义顶点的时候小心,必须以“锯齿”方式定义顶点才可以。如下。这样第一个三角形V1V2V3是顺时针方向,可以绘制,第二个三角形V2V3V4是逆时针方向,也可以正确绘制。余下类同。
Happy Coding!!!