在绘制前可能需要初始化的动作:
清除back buffer的当前缓冲器(也可以有深度缓冲器、模板缓冲),设置世界矩阵、投影矩阵和视点,再有就是视口。
清除三种缓冲区:
定义:
Clear(THIS_ DWORD Count,CONST D3DRECT* pRects,DWORD Flags,D3DCOLOR Color,float Z,DWORD Stencil);
Clear作用是用来设置当前的背景色(D3DCLEAR_TARGET)、深度缓冲区(D3DCLEAR_ZBUFFER)、stencil(D3DCLEAR_ZBUFFER)的值。
因为深度缓冲区1.0表示最远,所以一般设置为0.
m_pDevice->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER|D3DCLEAR_STENCIL,D3DCOLOR_XRGB(0,0,255),1.0,0);
注意1:color的值是从0到255,而不是偶倒256,设置成了256的话,会出现意外。
注意2: 如果没有深度缓存绘制stencil的话,那么clear将不会正确执行。
设置世界矩阵:
D3DXMATRIXA16 matWorld;
D3DXMatrixIdentity( &matWorld );
D3DXMatrixRotationX( &matWorld, timeGetTime()/1000.0f );
g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
设置视点(观察点)
D3DXVECTOR3 vEyePt( 0.0f, 3.0f,-5.0f );
D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
D3DXMATRIXA16 matView;
D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
设置投影矩阵:
D3DXMATRIXA16 matProj;
D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/2, 1.0f, 1.0f, 500.0f );
g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
得到和设置当前视口:
由于视口有默认的值,所以这一步不是必须的。
相关函数:
g_pDevice->SetViewport()
g_pDevice->GettViewport()
内容说明:
typedef struct _D3DVIEWPORT9 {
DWORD X; 屏幕左上角 x 坐标,默认为 0
DWORD Y; 屏幕左上角 y 坐标,默认为 0
DWORD Width; 屏幕显示区宽度,默认为创建 Direct3DDevice8 设备对象时的缓存宽度
DWORD Height; 屏幕显示区高度,默认为创建 Direct3DDevice8 设备对象时的缓存高度
float MinZ; Z 深度最小值,默认为 0
float MaxZ; Z 深度最大值,默认为 1
} D3DVIEWPORT9;
绘制一个三角形的基本步骤:
定义三角形的顶点类型:
在这里顶点的类型称为FVF(Flexible Vertex Format),这个FVF是一个结构体。结构体里面可以有x,y,z坐标信息,还可以有颜色、光照、纹理等数据。由于这个结构体里面的数据是根据需要来定义的,所以我们把这个结构体称为FVF。
分配三角形顶点的存储区域(Vertex Buffer):
得到VB的起始地址,把三角形的所有顶点写入到VB里面:
最后一步就是把图元绘制出来。
定义顶点类型由下面两部分组成:
//定义顶点信息的结构体
struct CUSTOMVERTEX
{
FLOAT x, y, z, rhw;
DWORD colour;
};
//定义自由顶点格式
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)
创建VB:
//通过设备创建顶点缓冲
if(FAILED(g_pD3DDevice->CreateVertexBuffer(3 * sizeof(CUSTOMVERTEX),
0, D3DFVF_CUSTOMVERTEX,
D3DPOOL_DEFAULT, &g_pVertexBuffer,NULL)))
{
return E_FAIL;
}
得到VB的起始地址,把数据写入:
//顶点信息数组
CUSTOMVERTEX cvVertices[] =
{
{250.0f, 100.0f, 0.5f, 1.0f, D3DCOLOR_XRGB(255, 0, 0),},
{400.0f, 350.0f, 0.5f, 1.0f, D3DCOLOR_XRGB(0, 255, 0),},
{100.0f, 350.0f, 0.5f, 1.0f, D3DCOLOR_XRGB(0, 0, 255),},
};
//锁定顶点缓冲,并得到一个存放顶点信息的缓冲区的指针
if(FAILED(g_pVertexBuffer->Lock(0, sizeof(cvVertices), (void**)&pVertices, 0)))
{
return E_FAIL;
}
//复制顶点信息
memcpy(pVertices, cvVertices, sizeof(cvVertices));
//解锁顶点缓冲区
g_pVertexBuffer->Unlock();
最后一步把图元绘制出来:
g_pD3DDevice->BeginScene();
//渲染三角形
g_pD3DDevice->SetStreamSource(0, g_pVertexBuffer, 0, sizeof(CUSTOMVERTEX));
g_pD3DDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
//结束绘制场景
g_pD3DDevice->EndScene();
【关于背面剔除:D3DCULL_MODE】
注意:
■ D3D默认是把顺时针看成正面,所以通常要把三角形顶点按顺时针顺序进行定义。
■ 确认使用的是 D3DFVF_XYZ 格式还是 D3DFVF_XYZRHW 格式。
SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE ) :不要剔除背面,即正反面都绘制。
SetRenderState( D3DRS_CULLMODE, D3DCULL_CW ) :把顺时针的方向看作背面剔除掉。
SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW ) :把逆时针的方向看作背面剔除掉(在消隐中为默认值)。
正确理解是:从视点看过去,如果这个面是顺时针绘制的,那么面对着眼睛的面就是正面,否则就是反面。