码迷,mamicode.com
首页 > 其他好文 > 详细

D3D 文字 Text2D

时间:2014-08-22 16:28:49      阅读:244      评论:0      收藏:0      [点我收藏+]

标签:d3d   文字   text3d   

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文字程序运行结果

bubuko.com,布布扣

D3D文字总结

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

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

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

3.ID3DXSprite 接口提升性能是牺牲空间为代价的,当绘制一次文字的时候,会将文字存放到空间中的纹理里面,以后如果再用就会直接从纹理取出,空间在内存还是显存现在还没有研究清楚。这样文字多的时候就会提高效率。DXUTTextHelper将ID3DXFont进行了封装到时候可以研究一下。

D3D 文字 Text2D

标签:d3d   文字   text3d   

原文地址:http://blog.csdn.net/yonshi/article/details/38756567

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!