www.pudn.com > zfxcengine-0.1.0.zip > ceFont.cpp


// $Id: ceFont.cpp,v 1.4 2005/08/27 11:44:43 kimmi Exp $  
//////////////////////////////////////////////////////////////////////////////// 
// 
//	Module:		GUI 
//	File:		ceFont.cpp 
//	Created:	14.08.2005 
//	Author:		Kim Kulling aka kimmi 
//	Licence:    See licence file in root 
//	Last Mod:   $Id: ceFont.cpp,v 1.4 2005/08/27 11:44:43 kimmi Exp $ 
// 
//////////////////////////////////////////////////////////////////////////////// 
#include  
#include  
#include "Core/ceDebug.h" 
#include "Render/ceRenderTypes.h" 
#include "Render/ceRenderDevice.h" 
#include "Render/ceViewport.h" 
#include "GUI/ceFont.h" 
#include "GUI/ceDefaultFontDef.h" 
#include "GUI/ceGUITypes.h" 
 
namespace ZFXCE { 
namespace GUI { 
	//------------------------------------------------------------------------------ 
	using namespace std; 
	using namespace Render; 
	 
	//------------------------------------------------------------------------------ 
	ceFont::ceFont() 
	{ 
		PUSH_FUNCTION; 
		Init(); 
	} 
	//------------------------------------------------------------------------------ 
	ceFont::ceFont(ceRenderDevice *pDevice, ceWindow *pWindow,  
		ceViewport *pViewport) 
	{ 
		PUSH_FUNCTION; 
		Init(); 
		m_pDevice = pDevice; 
		m_pRenderObjectFactory = pDevice->GetRenderObjectFactory(); 
	} 
	//------------------------------------------------------------------------------ 
	ceFont::~ceFont() 
	{ 
		PUSH_FUNCTION; 
		Release(); 
	} 
	//------------------------------------------------------------------------------ 
	void ceFont::Load(const char *pTexture) 
	{ 
		PUSH_FUNCTION; 
		 
		if (NULL == pTexture) { 
			m_iFontTex = m_pTextureManager->LoadTexture((void*)ceDefaultFont, 16, 2, false,  
				false, CE_RS_TEXFILTER_LINEAR, CE_RS_TEX_2D); 
			return; 
		} 
		m_iFontTex = m_pTextureManager->LoadTexture(pTexture); 
		ce_check (-1 != m_iFontTex, "Cannot load font texture"); 
	} 
	//------------------------------------------------------------------------------ 
	void ceFont::SetText(const char *pText, const int iSizeX, const int iSizeY) 
	{ 
		PUSH_FUNCTION; 
		ce_assert (NULL != pText); 
		m_strText = pText; 
		m_iX = iSizeX; 
		m_iY = iSizeY; 
		m_bUpdate = true; 
	} 
	//------------------------------------------------------------------------------ 
	void ceFont::Render() 
	{ 
		PUSH_FUNCTION; 
 
	} 
	//------------------------------------------------------------------------------ 
	void ceFont::Update(const DOUBLE Tick) 
	{ 
		if (m_bUpdate)  
			CreateRenderJob(m_strText.c_str(), m_iX, m_iY); 
	} 
	//------------------------------------------------------------------------------ 
	void ceFont::Init() 
	{ 
		PUSH_FUNCTION; 
		m_pRenderJob = NULL; 
		m_pRenderJob = NULL; 
		m_pRenderObjectFactory = NULL; 
		m_pWindow = NULL; 
		m_pTextureManager = NULL; 
		m_iFontTex = -1; 
		m_bUpdate = true; 
	} 
	//------------------------------------------------------------------------------ 
	void ceFont::Release() 
	{ 
		PUSH_FUNCTION; 
		m_pDevice = NULL; 
	} 
	//------------------------------------------------------------------------------ 
	void ceFont::CreateRenderJob(const char *pText, const int iSizeX, const int iSizeY)	 
	{ 
		PUSH_FUNCTION; 
		ceVertexDescription VertexDesc; 
		VertexDesc.add(0, CE_RS_VT_FLOAT3, CE_RS_VU_POSITION); 
		VertexDesc.add(sizeof(FLOAT)*3, CE_RS_VT_FLOAT2, CE_RS_VU_TEXCOORD0); 
		vector Vertices; 
 
		// Size is 256, 16 chars per line, so each char is 16 high 
		const FLOAT CharSize = 16.0f; 
		const FLOAT TCOffset = 16.0f/256.0f; 
		 
		// center string 
		const size_t outlength = strlen(pText); 
		INT x = outlength * -8; 
		INT x1=x, y1=0; 
		 
		//cout << "String: " << pText << endl; 
		for(size_t i=0; i < outlength; i++) { 
			FLOAT cx=(float)fmod(pText[i]/16.0f, 1); 
			FLOAT cy=((pText[i]/16)+1)/16.0f;	// 16 chars per line in texture 
			//cout << "cy: " << (out[i]/16) << endl; 
			//cout << "TC: " << cx << " " << cy << endl; 
			cy = 1-cy; 
			FontVertex v1, v2, v3, v4; 
			// bottom left 
			v1.tc[0] = cx; v1.tc[1] = 1 - cy; 
			v1.Pos.x = x1; v1.Pos.y = CharSize+y1; 
		 
			// top left 
			v2.tc[0] = cx; v2.tc[1] = 1 - cy - TCOffset; 
			v2.Pos.x = x1; v2.Pos.y = y1; 
		 
			// bottom right 
			v3.tc[0] = cx+TCOffset; v3.tc[1] = 1 - cy; 
			v3.Pos.x = CharSize + x1; v3.Pos.y = CharSize + y1; 
				 
			// top right 
			v4.tc[0] = cx+TCOffset; v4.tc[1] = 1 - cy - TCOffset; 
			v4.Pos.x = CharSize + x1; v4.Pos.y = y1; 
		 
			Vertices.push_back(v1); 
			Vertices.push_back(v2); 
			Vertices.push_back(v3); 
			Vertices.push_back(v4); 
			x1+=16; 
 
			if (pText[i] == '\n' || pText[i] == '\r') { 
				x1 = x; 
				y1 -= 16; 
			} 
		} 
	 
		// Fill with default data 
		INT iVertexBuffer = m_pRenderObjectFactory->CreateStaticVertexBuffer(CE_RS_PRIM_TRISTRIP,  
			VertexDesc, (const FLOAT*) &Vertices[0], Vertices.size()); 
		m_pRenderJob = m_pDevice->CreateRenderJob(m_pWindow, m_Viewport, iVertexBuffer); 
		ce_check(NULL != m_pRenderJob, "Cannot create renderjob"); 
 
		ceVertexPipeState VPState; 
		ceFragmentPipeState FPState; 
		FPState.AlphaBlending = true; 
		FPState.BlendingSrc = CE_RS_BLENDOPT_SRC_COLOR; 
		FPState.BlendingDst = CE_RS_BLENDOPT_ONE_MINUS_SRC_COLOR; 
		m_pRenderJob->SetPass(0, VPState, FPState); 
		if (-1 == m_iFontTex)  
			Load(this->m_FontName.c_str()); 
		 
		m_bUpdate = false; 
	} 
	//------------------------------------------------------------------------------ 
	void ceFont::SetParentGUIElement(ceIGUIElement *pParent) 
	{ 
		PUSH_FUNCTION; 
	} 
	//------------------------------------------------------------------------------ 
 
} // Namespace GUI 
} // namespace ZFXCE