Text3D就是一个网格模型,在3D空间中,文字对象对待方式就是一个模型,只不过代表的信息很不一般罢了。Text3D看起来有一定的立体感觉,因为有Z轴控制。这篇文章主要研究Text3D如何显示到3D场景中的。
Text3D将文字看成一般的网格模型,设置属性的时候按照字体来设置,最后显示的时候按照3D空间中的网格模型来显示。
程序中有关Text3D的重要部分,我用中文注释了,如果想研究程序的框架,请参考DXUT。
#pragma once //win32 #pragma comment(lib,"comctl32.lib") #pragma comment(lib,"winmm.lib") //d3d #pragma comment(lib,"dxerr.lib") #pragma comment(lib,"d3dx9.lib") //dxut #pragma comment(lib,"dxut.lib") //dxut #include"DXUT.h" HRESULT CALLBACK OnDeviceCreate( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext ); void CALLBACK OnDeviceDestroyed(void* pUserContext ); void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext ); void SetUpMatrix(IDirect3DDevice9* pd3dDevice); void SetupLight(IDirect3DDevice9* pd3dDevice); //TODO: global variables. //声明文字模型 ID3DXMesh* g_pd3dxTextMesh=NULL; INT WINAPI wWinMain( HINSTANCE, HINSTANCE, LPWSTR, INT) { DXUTSetCallbackD3D9DeviceCreated( OnDeviceCreate, NULL); DXUTSetCallbackD3D9DeviceDestroyed( OnDeviceDestroyed, NULL); DXUTSetCallbackD3D9FrameRender( OnFrameRender, NULL); //0.dxut init. DXUTInit(true,true,NULL,true); //1.create window DXUTCreateWindow( L"dxut window", GetModuleHandle(NULL), NULL, NULL, CW_USEDEFAULT, CW_USEDEFAULT); //2.create device. DXUTCreateDevice(true,640,480); //3.main loop DXUTMainLoop(); //exit. return DXUTGetExitCode(); } HRESULT CALLBACK OnDeviceCreate( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext ) { //TODO: create d3d device. //创建文字模型。 HDC hdc=CreateCompatibleDC(NULL); HFONT hNewFont=NULL; HFONT hOldFont=NULL; hNewFont=CreateFont( 24, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH|FF_DONTCARE, L"Arial"); hOldFont=(HFONT)SelectObject(hdc,hNewFont); if(FAILED(D3DXCreateText( pd3dDevice, hdc, L"你好,世界!", 0.001f, 0.4f, &g_pd3dxTextMesh, NULL, NULL))) { return E_FAIL; } SelectObject(hdc,hOldFont); DeleteObject(hNewFont); DeleteDC(hdc); return S_OK; } void CALLBACK OnDeviceDestroyed( void* pUserContext ) { //TODO:destroy d3d device. //释放文字模型 if(g_pd3dxTextMesh != NULL) { g_pd3dxTextMesh->Release(); g_pd3dxTextMesh=NULL; } } void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext ) { pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,255), 1.0f, 0); //设置矩阵变换 SetUpMatrix(pd3dDevice); SetupLight(pd3dDevice); if(SUCCEEDED(pd3dDevice->BeginScene())) { //TODO:render d3d scene. //绘制文字模型 g_pd3dxTextMesh->DrawSubset(0); pd3dDevice->EndScene(); } pd3dDevice->Present(NULL,NULL,NULL,NULL); } void SetUpMatrix(IDirect3DDevice9* pd3dDevice) { D3DXMATRIXA16 worldMatrix; D3DXMatrixIdentity(&worldMatrix); D3DXMatrixTranslation(&worldMatrix,-2.0f,0.0f,0.0f); pd3dDevice->SetTransform(D3DTS_WORLD,&worldMatrix); D3DXMATRIXA16 viewMatrix; D3DXVECTOR3 vEye(0.0f,0.0f,-10.0f); D3DXVECTOR3 vLookAt(0.0f,0.0f,0.0f); D3DXVECTOR3 vUp(0.0f,1.0f,0.0f); D3DXMatrixLookAtLH(&viewMatrix,&vEye,&vLookAt,&vUp); pd3dDevice->SetTransform(D3DTS_VIEW,&viewMatrix); D3DXMATRIXA16 projectionMatrix; D3DXMatrixPerspectiveFovLH(&projectionMatrix,D3DX_PI/4,1.0f,1.0f,1000.0f); pd3dDevice->SetTransform(D3DTS_PROJECTION,&projectionMatrix); } void SetupLight(IDirect3DDevice9* pd3dDevice) { D3DMATERIAL9 mtrl; ZeroMemory(&mtrl,sizeof(mtrl)); mtrl.Ambient.r=mtrl.Diffuse.r=1.0f; mtrl.Ambient.g=mtrl.Diffuse.g=1.0f; mtrl.Ambient.b=mtrl.Diffuse.b=0.0f; mtrl.Ambient.a=mtrl.Diffuse.a=1.0f; pd3dDevice->SetMaterial(&mtrl); D3DLIGHT9 light; D3DXVECTOR3 dir(1.0f,0.0f,0.0f); D3DXCOLOR color(1.0f,1.0f,1.0f,0.0f); ZeroMemory(&light,sizeof(light)); light.Type=D3DLIGHT_DIRECTIONAL; light.Ambient=color*0.6f; light.Diffuse=color; light.Specular=color*0.6f; light.Direction=dir; pd3dDevice->SetLight(0,&light); pd3dDevice->LightEnable(0,TRUE); pd3dDevice->SetRenderState(D3DRS_LIGHTING,TRUE); pd3dDevice->SetRenderState(D3DRS_NORMALIZENORMALS,TRUE); }
1.程序的逻辑不是很难,声明3D文字模型,创建文字模型,渲染显示文字模型,释放文字模型。
2.需要注意的地方是 创建文字模型 需要有字体属性,这里的字体是windowsGUI里面的字体。创建字体需要获得设备句柄。在渲染的时候需要设置坐标转换,字体的位置按照第一个字的左下角定位。
3.需要注意的函数
创建字体:CreateFont()
创建文字模型:D3DXCreateText()
平移矩阵函数:D3DXMatrixTranslation()
4.呵呵,我终于把文字研究了一下 ,刚开始的时候连程序都看不懂,就是抄程序抄出来的,慢慢的也就理解了,可是距离研究游戏引擎还远呢。
原文地址:http://blog.csdn.net/yonshi/article/details/38759193