此文为 我在学习DirectX3D过程中,总结的一些基础函数 和 绘制过程。 方便以后使用查下。后续随学习过程不断添加吧。
目录
12、索引绘制图元 DrawIndexedPrimitive
1、Direct3D 初始化
LPDIRECT3D9 g_pD3D; // Used to create the D3DDevice
LPDIRECT3DDEVICE9 g_pd3dDevice; // Our rendering device
if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
return false;
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(d3dpp) );
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp, &g_pd3dDevice ) ) )
{
return false;
}
2、屏幕的清空
void UIMain::Render()
{
if( NULL == g_pd3dDevice )
return;
// Clear the backbuffer to a blue color //用0,0,255 颜色填充屏幕
g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,255), 1.0f, 0 );
// Begin the scene
if( SUCCEEDED( g_pd3dDevice->BeginScene() ) ) //在里面书写逻辑绘制过程
{
// Rendering of scene objects can happen here
// End the scene
g_pd3dDevice->EndScene();
}
// Present the backbuffer contents to the display
g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}
3、释放
void UIMain::Cleanup()
{
if( g_pd3dDevice != NULL)
g_pd3dDevice->Release();
if( g_pD3D != NULL)
g_pD3D->Release();
}
4、顶点形式
//灵活顶点格式 D3DFVF_XYZ 表示x,y,z值,D3DFVF_NORMAL 表示法线值, D3DFVF_TEX1表示文理坐标
//D3DFVF_DIFFUSE 表示rgb值 有文理坐标,就不需要rgb值了
//顶点形式(包含文理坐标和法线的顶点格式 )
#define FVF_VERTEX (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1)
struct Vertex
{
Vertex(){}
Vertex(
float x, float y, float z,
float nx, float ny, float nz,
float u, float v)
{
_x = x; _y = y; _z = z;
_nx = nx; _ny = ny; _nz = nz;//法线
_u = u; _v = v; //文理坐标
}
float _x, _y, _z;
float _nx, _ny, _nz;
float _u, _v; // texture coordinates
};
5、坐标转换SetTransform
HRESULT SetTransform( D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX * pMatrix);
//如:世界坐标系
g_pd3dDevice->SetTransform(D3DTS_WORLD, &p); //根据矩阵p 从局部坐标系(local space) 转换到 世界坐标系中(world space)
//转换到观察坐标系:
D3DXVECTOR3 vEyePt( 0.0f, 0.0f,-5.0f ); //观察点坐标(相机 在世界坐标系中的位置)
D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f ); //被观察物体的坐标(在世界坐标系中的位置)
D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f ); //世界坐标系中表示 向上 方向的向量
D3DXMATRIX matView;
D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec ); //此函数 进行计算 求得 观察坐标 视图转换矩阵
g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView ); //根据视图转换矩阵 matView 转换到 观察坐标系中
//投影变化
// D3DXMATRIX * D3DXMatrixPerspectiveFovLH( D3DXMATRIX *pOut, FLOAT fovy, FLOAT Aspect, FLOAT zn, FLOAT zf);
//fovy 在Y方向上的视野,以弧度表示。
// Aspect 宽高比,定义为视图空间宽度除以高度。
//zn 近裁面 的Z值。 zf 远裁面 的 z值
D3DXMATRIXA16 matProj;
D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/2, 1.0f, 1.0f, 1000.0f ); //D3DX_PI/2 表示90度的
g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
6、修改绘制状态SetRenderState
HRESULT SetRenderState( D3DRENDERSTATETYPE State, DWORD Value);
//如:
g_pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
7、视口变换SetViewport
将投影窗口 转换到 屏幕的一个矩形区域中
D3DVIEWPORT9 vp; //默认视口参数
vp.X = 0;
vp.Y = 0;
vp.Width = RenderTarget.Width;
vp.Height = RenderTarget.Height; //前4个参数,定义了视口矩形相对于其父窗口的位置及大小
vp.MinZ = 0.0f; //指定深度缓存中的最小深度值 (direct3D 深度缓存的范围为 0-1)
vp.MaxZ = 1.0f; //指定深度缓存中的最大深度值
HRESULT SetViewport( CONST D3DVIEWPORT9* pViewport); //设置函数
8、顶点的创建CreateVertexBuffer
HRESULT CreateVertexBuffer( UINT Length, DWORD Usage, DWORD FVF, D3DPOOL Pool,
IDirect3DVertexBuffer9** ppVertexBuffer, HANDLE* pSharedHandle);
//Usage 指定关于如何使用缓存的一些附加属性
//FVF 顶点数据格式
//Pool 容纳缓存的内存池
//ppVertexBuffer 接收所创建的顶点缓存的指针
// pSharedHandle 不使用,设置为0
//示范:
struct Vertex //顶点数据的定义
{
Vertex(){}
Vertex(float x, float y, float z, float nx, float ny, float nz, float u, float v)
{
_x = x; _y = y; _z = z;
_nx = nx; _ny = ny; _nz = nz;
_u = u; _v = v;
}
float _x, _y, _z;
float _nx, _ny, _nz;
float _u, _v; // 文理坐标
};
#define FVF_VERTEX (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1)
IDirect3DVertexBuffer9* _vb;
_device->CreateVertexBuffer(4 * sizeof(Vertex),
D3DUSAGE_WRITEONLY, //只写
FVF_VERTEX,
D3DPOOL_MANAGED,
&_vb,
0);
Vertex* v;
_vb->Lock(0, 0, (void**)&v, 0); //锁定赋值
v[0] = Vertex(-1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f);
v[1] = Vertex(-1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f);
v[2] = Vertex( 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f);
v[3] = Vertex( 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f);
_vb->Unlock(); //锁定赋值结束
if(_vb){_vb->Release(); _vb = 0;} //释放
9、索引的创建CreateIndexBuffer
HRESULT CreateIndexBuffer( UINT Length, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool,
IDirect3DIndexBuffer9** ppIndexBuffer, HANDLE* pSharedHandle);
//示范:
IDirect3DIndexBuffer9* _ib;
_device->CreateIndexBuffer(36 * sizeof(WORD),
D3DUSAGE_WRITEONLY,
D3DFMT_INDEX16,
D3DPOOL_MANAGED,
&_ib,
0);
WORD* i = 0;
_ib->Lock(0, 0, (void**)&i, 0);
i[0] = 0; i[1] = 1; i[2] = 2; i[3] = 0;
_ib->Unlock();
if(_ib){_ib->Release(); _ib = 0;} //释放
10、绘制的准备SetStreamSource
在绘制前,必须将相关数据 指定给 设备
device->SetStreamSource(0, _vb, 0, sizeof(Vertex)); //指定顶点数据流
device->SetIndices(_ib); //指定索引缓存, 在切换索引时,必须重新设置一下
device->SetFVF(FVF_VERTEX); //指定顶点格式
11、不使用索引绘制图元DrawPrimitive
HRESULT DrawPrimitive( D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount);
//绘制类型说明:
typedef enum D3DPRIMITIVETYPE
{
D3DPT_POINTLIST = 1, //将顶点作为孤立点的集合呈现, 绘制点, 不支持 索引绘制函数 6个点
D3DPT_LINELIST = 2, //将顶点作为孤立的直线段列表 绘制孤立直线 6个点3条线
D3DPT_LINESTRIP = 3, //将顶点作为单个折线呈现 将多个点连接成折线 6个点依次连接成5条线
D3DPT_TRIANGLELIST = 4, //将指定顶点作为孤立三角形序列 每组三个顶点定义了一个独立的三角形, 6个点2个三角形
D3DPT_TRIANGLESTRIP = 5, //将顶点作为三角形条带。背面剔除标志是在偶数三角形上自动翻转的
D3DPT_TRIANGLEFAN = 6, //渲染顶点为三角形扇形
D3DPT_FORCE_DWORD = 0x7fffffff, //不使用此值,是在为了编译
} D3DPRIMITIVETYPE, *LPD3DPRIMITIVETYPE;
// StartVertex 顶点数据流 绘制起点 索引
// PrimitiveCount 绘制图元数量
g_pd3dDevice->DrawPrimitive( D3DPT_LINESTRIP, 0, 5 );
12、索引绘制图元 DrawIndexedPrimitive
HRESULT DrawIndexedPrimitive( D3DPRIMITIVETYPE Type, INT BaseVertexIndex,
UINT MinIndex, UINT NumVertices, UINT StartIndex, UINT PrimitiveCount);
// BaseVertexIndex 索引的偏移量
// MinIndex 最小索引值
// NumVertices 顶点总数
// StartIndex 顶点缓存中标识索引的读取起始点的原始的索引
// PrimitiveCount 图元总数
Device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 8, 0, 12);
13、Begin/End Scene
if( SUCCEEDED( g_pd3dDevice->BeginScene() ) ) //在里面书写逻辑绘制过程
{
g_pd3dDevice->DrawPrimitive(.....);
g_pd3dDevice->EndScene();
}
14、四元数 旋转D3DXQUATERNION
D3DXQUATERNION angle;
//四元数Q = [cos(O/2) sin(O/2)N] = [ cos(O/2) ( sin(O/2)Nx sin(O/2)Ny sin(O/2)Nz ) ]
angle.x = 0;
angle.y = sin(fAngle/2.0);
angle.z = 0;
angle.w = cos(fAngle/2.0);
D3DXVECTOR3 pinyi(-5.0f, 0.0f, 0.0f); //平移向量
//获取平移+旋转矩阵
D3DXMatrixTransformation(&m_worldMatrix, NULL, NULL, NULL, NULL, &angle, &pinyi);
//将物品坐标系映射到世界坐标系(-5.0,0,0)点上,并绕y=-5.0 旋转fAngle度
g_pd3dDevice->SetTransform(D3DTS_WORLD, &m_worldMatrix);
15、旋转矩阵D3DXMatrixRotationAxis
D3DXMATRIX * D3DXMatrixRotationAxis( D3DXMATRIX *pOut, CONST D3DXVECTOR3 *pV, FLOAT Angle); //绕任意轴旋转
D3DXMATRIX * D3DXMatrixRotationX( D3DXMATRIX *pOut, FLOAT Angle); //绕X轴旋转
D3DXMATRIX * D3DXMatrixRotationY( D3DXMATRIX *pOut, FLOAT Angle); //绕Y轴旋转
D3DXMATRIX * D3DXMatrixRotationZ( D3DXMATRIX *pOut, FLOAT Angle); //绕Z轴旋转
//例:
FLOAT fAngle = iTime * (2.0f * D3DX_PI) / 1000.0f;
D3DXMATRIXA16 m_worldMatrix;
D3DXMatrixRotationY( &m_worldMatrix, fAngle );
D3DXVECTOR3 pinyi(-5.0f, 0.0f, 0.0f);
D3DXMatrixRotationAxis( &m_worldMatrix, pinyi, fAngle);
g_pd3dDevice->SetTransform(D3DTS_WORLD, &m_worldMatrix);
16、材质结构体D3DMATERIAL9
typedef struct _D3DMATERIAL9 {
D3DCOLORVALUE Diffuse; /* Diffuse color RGBA 对漫射光的反射率*/
D3DCOLORVALUE Ambient; /* Ambient color RGB 对环境光的反射率*/
D3DCOLORVALUE Specular; /* Specular 'shininess' 对镜面光的反射率*/
D3DCOLORVALUE Emissive; /* Emissive color RGB 增强物体亮度,看起来好像自己可以发光*/
float Power; /* Sharpness if specular highlight 镜面高光点的锐度,越大,锐度越大*/
} D3DMATERIAL9;
//示范,只反射红色光
D3DMATERIAL9 red;
ZeroMemory(&red, sizeof(red));
red.Diffuse = D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f);
red.Ambient = D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f);
red.Specular = D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f);
red.Emissive = D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f);
red.Power = 5.0f
Device->SetMaterial(&red);