这次教程涉及到材质和光照。
Step 1 - Initializing Scene Geometry
struct CUSTOMVERTEX
{
D3DXVECTOR3 position; // The 3D position for the vertex.
D3DXVECTOR3 normal; // The surface normal for the vertex.
};
// Custom flexible vertex format (FVF).
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_NORMAL)
计算顶点的光照需要法线向量,因此顶点格式中包含顶点位置和法线向量。
这一次教程使用的几何体是圆柱,因此使用下面的代码创建一个圆柱。
// Create the vertex buffer.
if( FAILED( g_pd3dDevice->CreateVertexBuffer( 50*2*sizeof(CUSTOMVERTEX),
0 /*Usage*/, D3DFVF_CUSTOMVERTEX,
D3DPOOL_DEFAULT, &g_pVB, NULL ) ) )
return E_FAIL;
CUSTOMVERTEX* pVertices;
if( FAILED( g_pVB->Lock( 0, 0, (void**)&pVertices, 0 ) ) ) 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) );
}
创建出的圆柱分别以(0.0f, -1.0f, 0.0f)和(0.0f, 1.0f, 0.0f)作为下上底面。
Step 2 - Setting Up Material and Light
首先创建材料。
D3DMATERIAL9 mtrl;
ZeroMemory( &mtrl, sizeof(mtrl) );
mtrl.Diffuse.r = mtrl.Ambient.r = 1.0f;
mtrl.Diffuse.g = mtrl.Ambient.g = 1.0f;
mtrl.Diffuse.b = mtrl.Ambient.b = 0.0f;
mtrl.Diffuse.a = mtrl.Ambient.a = 1.0f;
g_pd3dDevice->SetMaterial( &mtrl );
上面的代码创建了一个黄色的材质,漫射光和环境光都是黄色。接下来是设置光照。DX9中有三种光照:点光(类似白炽灯),方向光(类似阳光),射灯光(聚光灯)
D3DXVECTOR3 vecDir;
D3DLight9 light;
ZeroMemory( &light, sizeof(light) );
light.Type = D3DLIGHT_DIRECTIONAL;
接下来设置灯光为白色。light.Diffuse.r = 1.0f;
light.Diffuse.g = 1.0f;
light.Diffuse.b = 1.0f;
这个教程还将光不停旋转。
vecDir = D3DXVECTOR3(cosf(timeGetTime()/360.0f),
0.0f,
sinf(timeGetTime()/360.0f) );
D3DXVec3Normalize( (D3DXVECTOR3*)&light.Direction, &vecDir );
还可以给灯光设置范围。light.Range = 1000.0f;
设置灯光。g_pd3dDevice->SetLight( 0, &light );
注意第一个参数是灯光的索引值,一个索引值仅对应一个灯光实体。g_pd3dDevice->LightEnable( 0, TRUE);
还需要把灯光打开。g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
渲染状态中也要设置灯光打开。
这一步可选,设置环境光。
g_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0x00202020 );