LPDIRECT3DDEVICE9 g_lpd3ddevice;//全局的
HRESULT InitD3D(HWND hWnd)
{
D3DPRESENT_PARAMETERS m_d3dpp;
//我们要把当前适配器(显卡)的信息读到这个结构体里,它将被用于创建设备
D3DDISPLAYMODE m_d3ddm;
g_lpd3d9->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&m_d3ddm);
//D3DADAPTER_DEFAULT表示默认显卡
ZeroMemory(&m_d3dpp,sizeof(m_d3dpp));
m_d3dpp.Windowed=false;//要建立一个全屏程序,则置此项为FALSE
m_d3dpp.BackBufferWidth=m_d3ddm.Width;
m_d3dpp.BackBufferHeight=m_d3ddm.Height;
m_d3dpp.BackBufferFormat=m_d3ddm.Format;//此项记录色深信息
m_d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD;
m_d3dpp.EnableAutoDepthStencil = TRUE;//让D3D管理深度缓冲
m_d3dpp.AutoDepthStencilFormat=D3DFMT_D16;//设置深度缓冲为16位
m_d3dpp.hDeviceWindow=hWnd;
//create the device:
g_lpd3d9->CreateDevice(D3DADAPTER_DEFAULT,//适配器标识符,大多数情况使用默认的
D3DDEVTYPE_HAL,//硬件抽象层
hWnd,//这是一个当前窗口的句柄,使用刚才CreateWindowEx()的返回值就行了
D3DCREATE_HARDWARE_VERTEXPROCESSING,//顶点处理类型,这里使用硬件处理
&m_d3dpp,//描述设备的结构体
&g_lpd3ddevice);//最后给一个要被创建的设备的指针
//启用Z缓冲
g_lpd3ddevice->SetRenderState(D3DRS_ZENABLE,TRUE);
return S_OK;
}
Z缓冲是深度缓冲的一种。深度缓冲是一块与屏幕大小相同的区域,记录着屏幕上每个点的“最近像素”有多“近”。比如说程序要画一个三角形中的某个点,但它发现深度缓冲中记录的距离比这个点要近,也就是说其他物体的某点挡在它前面,自然也就不会去画它;否则就画它,然后把该点的深度信息写进缓冲。现在我们把Z-Buffer打开,就是把这些事交给系统处理。调节缓冲数据位数是在较精确的数据与较大的空间之间作个权衡。
该用到刚刚做完的那个东西了。在D3D中,可以说所有物体的外形位置由顶点构成;材质决定着物体如何反射光线;贴图的作用自不言而喻。任何3D程序首先要做的就是创建一套这些信息。刚才说道,现在这些信息都包含在现成的mesh物体中,我们要做的就是把它从文件中提取出来。D3D中的IDirect3DMesh界面提供了这些方法。 LPD3DXMESH g_lpmesh;//全局的
mesh物体的定点信息都存放在g_lpmesh里,而材质和贴图还要单独提取出。D3D里,材质和贴图分别用D3DMATERIAL9结构体和ID3DTexture9界面描述。一般来说,mesh中都含有多种贴图和材质,我们要将其声明为数组。 D3DMATERIAL9 *g_meshmtrl;
LPDIRECT3DTEXTURE9 *g_meshtex;
数组的大小事先并不知道,取决于mesh物体的SebSet的数量。在一个mesh物体中,拥有相同材质贴图属性的一组三角形叫它的一个SubSet。因为转换当前材质和贴图是十分耗时的,因此在D3D中是按照一个SubSet组接着另一个去渲染的,这样就避免了材质贴图的频繁转变。我们用一个DWOD型的全局变量g_meshmtrlnum记录这个mesh中的SubSet数量。
HRESULT InitGeometry()
{
LPD3DXBUFFER lpmeshmtrlbuffer;//材质贴图的临时缓冲
//从文件装载一个mesh物体:
D3DXLoadMeshFromX("c:\\", //文件路径
D3DXMESH_SYSTEMMEM,//g_lpmesh被创建的位置,这里它被创建在系统内存而非显示内存
g_lpd3ddevice,NULL,&lpmeshmtrlbuffer,NULL,
&g_meshmtrlnum,//一个用于存放SubSet数量的变量指针
&g_lpmesh);//最后是要被创建的mesh指针
//我们要一次性读取出全部材质和贴图信息,并都存放在这里:
D3DXMATERIAL *pd3dxmtrl=(D3DXMATERIAL*)lpmeshmtrlbuffer->GetBufferPointer();
//然后再细分:
g_meshmtrl=new D3DMATERIAL9[g_meshmtrlnum];
g_meshtex=new LPDIRECT3DTEXTURE9[g_meshmtrlnum];
//对每个SubSet,我们分别提取它的材质和贴图
for(DWORD i=0;i<g_meshmtrlnum;i++)
{
g_meshmtrl=pd3dxmtrl.MatD3D;
//实际上,pd3dxmtrl.pTextureFilename只是个文件名
TCHAR texname[512];//存放完整的贴图文件路径
strcpy(texname,"c:\\");
strcat(texname, pd3dxmtrl.pTextureFilename);
D3DXCreateTextureFromFile(g_lpd3ddevice,texname,&g_meshtex);
}
lpmeshmtrlbuffer->Release();
lpmeshmtrlbuffer = NULL;
return S_OK;
} |