您的位置:首页 > 其它

D3D 文字 Text2D

2014-08-22 14:53 239 查看

D3D文字是什么

由于文字在程序里面出现的次数太多,所以d3d就将他独立出来,成为单独的一个部分。游戏中使用的太多了,也就有了研究的必要。我在学习的时候问题的确很多,现在照样一知半解,不过知识总是慢点梳理的,有所得记录下来还是很不错的。

D3D文字原理

我觉得D3D文字分为两类三种,第一类就是2D空间里面的文字,由于2D空间没有Z轴,所以文字的大小是很平均的,不会随着位置的改变大小发生变化。第二类就是3D空间里面的文字的,可以分为两种。第一种就是3D空间中的2D文字,比如说纹理图片里面的文字,显示的时候就会随着纹理的变化而变化。第二种就是3D文字模型,或者叫网格,我喜欢把Mesh翻译成模型,这样理解着好理解而已。例子就是类似高楼大厦顶上的文字图标,例如中国人民银行等等。这篇文章主要的实验对象是2D文字,属于哪一种我也说不是很清楚,因为看了半天,找了变天没有相应方面的知识,暂时先认为是2D空间中的文字吧。

D3D文字程序实现

说明

程序中需要注意的地方我都用中文标了注释。需要研究程序框架的话参考DXUT框架就可以了。

程序源码

#pragma once

//win32
#pragma comment(lib,"comctl32.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.
//1.字体和字体精灵
ID3DXFont* pFont=NULL;
ID3DXSprite* pSprite=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.
//创建字体和字体精灵
D3DXCreateSprite(pd3dDevice,&pSprite);

if(FAILED(D3DXCreateFont(
pd3dDevice,
24,
0,
FW_BOLD,
0,
FALSE,
DEFAULT_CHARSET,
OUT_DEFAULT_PRECIS,
DEFAULT_QUALITY,
DEFAULT_PITCH|FF_DONTCARE,
L"Arial",
&pFont)))
{
return E_FAIL;
}

return S_OK;
}

void    CALLBACK OnDeviceDestroyed(
void* pUserContext )
{
//TODO:destroy d3d device.
if(pSprite != NULL)
{
pSprite->Release();
pSprite=NULL;
}

if(pFont != NULL)
{
pFont->Release();
pFont=NULL;
}
}

void    CALLBACK OnFrameRender(
IDirect3DDevice9* pd3dDevice,
double fTime,
float fElapsedTime,
void* pUserContext )
{
RECT rc;

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.
//绘制字体
pSprite->Begin(D3DXSPRITE_ALPHABLEND | D3DXSPRITE_SORT_TEXTURE);
SetRect( &rc, 150, 200, 0, 0 );
pFont->DrawText(
pSprite,
L"你好,世界!",
-1,
&rc,
DT_NOCLIP,
D3DXCOLOR( 1.0f, 0.0f, 0.0f, 1.0f ) );
pSprite->End();
pd3dDevice->EndScene();
}

pd3dDevice->Present(NULL,NULL,NULL,NULL);
}

void SetUpMatrix(IDirect3DDevice9* pd3dDevice)
{
D3DXMATRIXA16 viewMatrix;
D3DXVECTOR3 vEye(0.0f,5.0f,-3.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);
}

D3D文字程序运行结果



D3D文字总结

这个知识点觉得总结的地方挺少的。

1. 需要了解ID3DXFont 接口的作用,主要就是绘制文字。字符串-->字体设置-->文字显示。

2.需要了解ID3DXSprite接口的作用,这个有一些文章说直接指定NULL,我查阅MSDN上说最好指定,如果文字很多就会有优化,当然,只有一行文字指定NULL和指定其他的性能是一样的 。

3.ID3DXSprite 接口提升性能是牺牲空间为代价的,当绘制一次文字的时候,会将文字存放到空间中的纹理里面,以后如果再用就会直接从纹理取出,空间在内存还是显存现在还没有研究清楚。这样文字多的时候就会提高效率。DXUTTextHelper将ID3DXFont进行了封装到时候可以研究一下。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  D3D 文字 Text3D