使用灯光的一个必要条件是:每个表面都必须有一个法线。为了达到这个目标,Lights示例工程使用一个不同于前面示例的自定义顶点类型。新的顶点类型有一个3-D的位置向量和一个表面法向量。法线用来提供给Direct3D,使其在内部进行相关的灯光计算。
struct CUSTOMVERTEX
{
D3DXVECTOR3 position; // The 3-D position for the vertex.
D3DXVECTOR3 normal; // The surface normal for the vertex.
};
// Custom FVF.
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_NORMAL)
目前为止,已经定义好正确的向量格式,Lights示例工程调用自定义函数InitGeometry创建一个圆柱体。首先需要创建一个顶点缓冲,用来存储圆柱体的各个顶点,代码如下:
// Create the vertex buffer.
if( FAILED( g_pd3dDevice->CreateVertexBuffer( 50*2*sizeof(CUSTOMVERTEX),
0 /**//* Usage */, D3DFVF_CUSTOMVERTEX,
D3DPOOL_DEFAULT, &g_pVB ) ) )
return E_FAIL;
下一步则是要将圆柱体的各个顶点数据填充到顶点缓冲当中。注意下面的示例代码,每个顶点都被定义了一个位置和一个法向量。
for( DWORD i=0; i<50; i++ )
{
FLOAT theta = (2*D3DX_PI*i)/(50-1);
pVertices[2*i+0].position = D3DXVECTOR3( sinf(theta),-1.0f, cosf(theta) );
pVertices[2*i+0].normal = D3DXVECTOR3( sinf(theta), 0.0f, cosf(theta) );
pVertices[2*i+1].position = D3DXVECTOR3( sinf(theta), 1.0f, cosf(theta) );
pVertices[2*i+1].normal = D3DXVECTOR3( sinf(theta), 0.0f, cosf(theta) );
}
在填充完顶点缓冲之后,就可以渲染它了。但是首先,必须在渲染圆柱体之前设置这个场景的材质和灯光。