背面消隐
每个多边形都有两个侧面(sides),我们将其中一个侧面标记为正面,另一个侧面标记为背面。通常,多边形的背面是不可见的。这是由于场景中的多数物体都是封闭体(enclosed volume),例如盒子、圆柱体、桶、字符等,而且摄像机总是禁止进入物体内部的实体空间的。所以,摄像机是不可能观察不到多边形的背面的。这-点很重要,因为如果某-多边形的背面可见,背面消隐(backface culling就失去了意义。
默认状态下,Direct3D认为顶点排列顺序为顺时针
(观察坐标系中)的三角形单元是正面朝向的,顶点排列顺序为逆时针
(观察坐标系中)的三角形单元是背面朝向的。
顶点缓存和索引缓存
顶点缓存与索引缓存(vertex/index buffer)是两类相似的接口,二者所具有的方法也十分相像。一个顶点缓存是-个包含顶点数据的连续内存空间。类似的,一个索引缓存是一个包含索引数据的连续内存空间。我们之所以用顶点缓存和索引缓存而非数组来存储数据,是因为顶点缓存和索引缓存可以被放置在显存(video memory中。进行绘制时,使用显存中的数据将获得比使用系统内存中的数据快得多的绘制速度。
在代码中,顶点缓存用接口IDirect3DVertexufer9 表示,索引缓存用接口IDirect3DIndexBuffer9表示。
Device->CreateVertexBuffer(
3 * sizeof(Vertex), // size in bytes
D3DUSAGE_WRITEONLY, // flags
Vertex::FVF, // vertex format
D3DPOOL_MANAGED, // managed memory pool
&Triangle, // return create vertex buffer
0); // not used - set to 0
Device->CreateIndexBuffer(
36 * sizeof(WORD),
D3DUSAGE_WRITEONLY,
D3DFMT_INDEX16,
D3DPOOL_MANAGED,
&IB,
0);
创建缓存时,如果未使用标记D3DUSAGE_ DYNAMIC,则称所创建的缓存为静态缓存(static buffer)。静态缓存一般被放置在显存中,以保证存储于其中的数据得到最高效的处理。然而,静态缓存是以牺牲对静态缓存读写操作的速度为代价的,这是因为访问显存的速度本身就很慢。基于上述原因,我们用静态缓存来存储静态数据(那些不需要经常修改或访问的数据)。例如,地形和城市建筑的数据就很适合存储在静态缓存中,因为这类数据在程序运行过程中通常不需进行修改。静态缓存必须在应用程序初始化时用几何体的数据进行填充。
创建缓存时,如果使用了标记D3DUSAGE_ DYNAMIC,则称所创建的缓存为动态缓存(dynamic buffer). 动态缓存一般放置在AGP存储区中,其内容可被迅速更新。动态缓存中数据的处理速度不像静态缓存那样快,这是因为在绘制前数据必须传输到显存中。但动态缓存的突出优点是其更新速度相当快(快速的CPU写操作)。所以,如果您需要频繁更新缓存中的内容,该缓存应设置为动态的。粒子系统就是使用动态缓存的一个很好的例子,因为粒子都是活动的,所以需要对每帧图像中粒子的几何布局进行更新。
访问缓存内容
HRESULT IDirect3DVertexBuffer9::Lock (
UINT OffsetToLock,
UINT SizeToLock,
BYTE** ppbData,
DWORD Flags
);
HRESULT IDirect3DIndexBuffer9::Lock (
UINT OffsetToLock,
UINT SizeToLock,
BYTE** ppbData,
DWORD Flags
);
访问三角形缓冲区
Vertex* vertices;
Triangle->Lock(0, 0, (void**)&vertices, 0);
vertices[0] = Vertex(-1.0f, 0.0f, 2.0f);
vertices[1] = Vertex( 0.0f, 1.0f, 2.0f);
vertices[2] = Vertex( 1.0f, 0.0f, 2.0f);
Triangle->Unlock();