⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 d3dfont.cpp

📁 java实现的简单的分形树。简单易学!是学习分形知识的很好的例子。其java语法简单
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// --------------------------------------------------------------------------
// Dingus project - a collection of subsystems for game/graphics applications
// --------------------------------------------------------------------------
#include "stdafx.h"

#include "D3DFont.h"
#include "DXUtil.h"
#include "../kernel/D3DDevice.h"

using namespace dingus;


//---------------------------------------------------------------------------
// Custom vertex types for rendering text

#define MAX_NUM_VERTICES 50*6

struct SFont2DVertex { D3DXVECTOR4 p; D3DCOLOR color; 	float tu, tv; };
struct SFont3DVertex { D3DXVECTOR3 p; D3DXVECTOR3 n;	float tu, tv; };

#define D3DFVF_FONT2DVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_TEX1)
#define D3DFVF_FONT3DVERTEX (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1)

inline SFont2DVertex gInitFont2DVertex( const D3DXVECTOR4& p, D3DCOLOR color, float tu, float tv )
{
	SFont2DVertex v;
	v.p = p;	 v.color = color;	v.tu = tu;	 v.tv = tv;
	return v;
}

inline SFont3DVertex gInitFont3DVertex( const D3DXVECTOR3& p, const D3DXVECTOR3& n, float tu, float tv )
{
	SFont3DVertex v;
	v.p = p;	 v.n = n;	v.tu = tu;	 v.tv = tv;
	return v;
}



//---------------------------------------------------------------------------
// CD3DFont()
//---------------------------------------------------------------------------


CD3DFont::CD3DFont( const TCHAR* fontName, int height, int flags )
:	mFontHeight(height), mFontFlags(flags),
	mSpacing(0),
	/*mDevice(NULL), */mTexture(NULL), mVB(NULL),
	mBlockSaved(NULL), mBlockDrawText(NULL)
{
	_tcsncpy( mFontName, fontName, sizeof(mFontName) / sizeof(TCHAR) );
	mFontName[sizeof(mFontName) / sizeof(TCHAR) - 1] = _T('\0');
}


CD3DFont::~CD3DFont()
{
	passivateDeviceObjects();
	deleteDeviceObjects();
}


HRESULT CD3DFont::createDeviceObjects(/* IDirect3DDevice9& device */)
{
	HRESULT hr;
	
	CD3DDevice& device = CD3DDevice::getInstance();
	// Keep a local copy of the device
	//mDevice = &device;
	
	// Establish the font and texture size
	mTextScale	= 1.0f; // Draw fonts into texture without scaling
	
	// Large fonts need larger textures
	if( mFontHeight > 60 )
		mTexWidth = mTexHeight = 2048;
	else if( mFontHeight > 30 )
		mTexWidth = mTexHeight = 1024;
	else if( mFontHeight > 15 )
		mTexWidth = mTexHeight = 512;
	else
		mTexWidth  = mTexHeight = 256;
	
	// If requested texture is too big, use a smaller texture and smaller font,
	// and scale up when rendering.
	//D3DCAPS9 caps;
	//mDevice->GetDeviceCaps( &caps );
	
	if( mTexWidth > device.getCaps().MaxTextureWidth ) {
		mTextScale = (float)device.getCaps().MaxTextureWidth / (float)mTexWidth;
		mTexWidth = mTexHeight = device.getCaps().MaxTextureWidth;
	}
	
	// Create a new texture for the font
	hr = device.getDevice().CreateTexture(
		mTexWidth, mTexHeight, 1, 0, D3DFMT_A4R4G4B4,
		D3DPOOL_MANAGED, &mTexture, NULL );
	if( FAILED(hr) )
		return hr;
	
	// Prepare to create a bitmap
	DWORD*		pBitmapBits;
	BITMAPINFO	bmi;
	ZeroMemory( &bmi.bmiHeader,  sizeof(BITMAPINFOHEADER) );
	bmi.bmiHeader.biSize		= sizeof(BITMAPINFOHEADER);
	bmi.bmiHeader.biWidth		=  (int)mTexWidth;
	bmi.bmiHeader.biHeight		= -(int)mTexHeight;
	bmi.bmiHeader.biPlanes		= 1;
	bmi.bmiHeader.biCompression = BI_RGB;
	bmi.bmiHeader.biBitCount	= 32;
	
	// Create a DC and a bitmap for the font
	HDC 	hDC 	  = CreateCompatibleDC( NULL );
	HBITMAP hbmBitmap = CreateDIBSection( hDC, &bmi, DIB_RGB_COLORS, (void**)&pBitmapBits, NULL, 0 );
	SetMapMode( hDC, MM_TEXT );
	
	// Create a font.  By specifying ANTIALIASED_QUALITY, we might get an
	// antialiased font, but this is not guaranteed.
	INT nHeight    = -MulDiv( mFontHeight, (INT)(GetDeviceCaps(hDC, LOGPIXELSY) * mTextScale), 72 );
	DWORD dwBold   = (mFontFlags&BOLD)	 ? FW_BOLD : FW_NORMAL;
	DWORD dwItalic = (mFontFlags&ITALIC) ? TRUE    : FALSE;
	HFONT hFont    = CreateFont(
		nHeight, 0, 0, 0, dwBold, dwItalic,
		FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
		CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY,
		VARIABLE_PITCH, mFontName );
	if( NULL==hFont )
		return E_FAIL;
	
	HGDIOBJ hbmOld = SelectObject( hDC, hbmBitmap );
	HGDIOBJ hFontOld = SelectObject( hDC, hFont );
	
	// Set text properties
	SetTextColor( hDC, RGB(255,255,255) );
	SetBkColor(   hDC, 0x00000000 );
	SetTextAlign( hDC, TA_TOP );
	
	// Loop through all printable character and output them to the bitmap..
	// Meanwhile, keep track of the corresponding tex coords for each character.
	DWORD x = 0;
	DWORD y = 0;
	TCHAR str[2] = _T("x");
	SIZE size;
	
	// Calculate the spacing between characters based on line height
	GetTextExtentPoint32( hDC, TEXT(" "), 1, &size );
	x = mSpacing = (DWORD) ceil(size.cy * 0.3f);
	
	for( TCHAR c=32; c<127; c++ ) {
		str[0] = c;
		GetTextExtentPoint32( hDC, str, 1, &size );
		
		if( (DWORD)(x + size.cx + mSpacing) > mTexWidth ) {
			x  = mSpacing;
			y += size.cy+1;
		}
		
		ExtTextOut( hDC, x+0, y+0, ETO_OPAQUE, NULL, str, 1, NULL );
		
		mTexCoords[c-32][0] = ((float)(x + 0       - mSpacing))/mTexWidth;
		mTexCoords[c-32][1] = ((float)(y + 0       + 0       ))/mTexHeight;
		mTexCoords[c-32][2] = ((float)(x + size.cx + mSpacing))/mTexWidth;
		mTexCoords[c-32][3] = ((float)(y + size.cy + 0       ))/mTexHeight;
		
		x += size.cx + (2 * mSpacing);
	}
	
	// Lock the surface and write the alpha values for the set pixels
	D3DLOCKED_RECT d3dlr;
	mTexture->LockRect( 0, &d3dlr, 0, 0 );
	BYTE* pDstRow = (BYTE*)d3dlr.pBits;
	WORD* pDst16;
	BYTE bAlpha; // 4-bit measure of pixel intensity
	
	for( y=0; y < mTexHeight; y++ ) {
		pDst16 = (WORD*)pDstRow;
		for( x=0; x < mTexWidth; x++ ) {
			bAlpha = (BYTE)((pBitmapBits[mTexWidth*y + x] & 0xff) >> 4);
			if (bAlpha > 0) {
				*pDst16++ = (WORD) ((bAlpha << 12) | 0x0fff);
			} else {
				*pDst16++ = 0x0000;
			}
		}
		pDstRow += d3dlr.Pitch;
	}
	
	// Done updating texture, so clean up used objects
	mTexture->UnlockRect(0);
	SelectObject( hDC, hbmOld );
	SelectObject( hDC, hFontOld );
	DeleteObject( hbmBitmap );
	DeleteObject( hFont );
	DeleteDC( hDC );
	
	return S_OK;
}



HRESULT CD3DFont::activateDeviceObjects()
{
	HRESULT hr;
	
	CD3DDevice& device = CD3DDevice::getInstance();
	IDirect3DDevice9& dx = device.getDevice();

	// Create vertex buffer for the letters
	int vertexSize = sizeof(SFont2DVertex) > sizeof(SFont3DVertex ) ? sizeof(SFont2DVertex) : sizeof(SFont3DVertex);
	if( FAILED( hr = dx.CreateVertexBuffer(
		MAX_NUM_VERTICES * vertexSize,
		D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, 0,
		D3DPOOL_DEFAULT, &mVB, NULL ) ) )
	{
		return hr;
	}
	
	// Create the state blocks for rendering text
	for( UINT which=0; which<2; which++ ) {
		dx.BeginStateBlock();
		dx.SetTexture( 0, mTexture );
		
		if( ZENABLE & mFontFlags )
			dx.SetRenderState( D3DRS_ZENABLE, TRUE );
		else
			dx.SetRenderState( D3DRS_ZENABLE, FALSE );
		
		dx.SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
		dx.SetRenderState( D3DRS_SRCBLEND,   D3DBLEND_SRCALPHA );
		dx.SetRenderState( D3DRS_DESTBLEND,  D3DBLEND_INVSRCALPHA );
		dx.SetRenderState( D3DRS_ALPHATESTENABLE,  TRUE );
		dx.SetRenderState( D3DRS_ALPHAREF,		 0x08 );
		dx.SetRenderState( D3DRS_ALPHAFUNC,  D3DCMP_GREATEREQUAL );
		dx.SetRenderState( D3DRS_FILLMODE,   D3DFILL_SOLID );
		dx.SetRenderState( D3DRS_CULLMODE,   D3DCULL_CCW );
		dx.SetRenderState( D3DRS_STENCILENABLE,	 FALSE );
		dx.SetRenderState( D3DRS_CLIPPING,		 TRUE );
		dx.SetRenderState( D3DRS_CLIPPLANEENABLE,  FALSE );
		dx.SetRenderState( D3DRS_VERTEXBLEND, 	 D3DVBF_DISABLE );
		dx.SetRenderState( D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE );
		dx.SetRenderState( D3DRS_FOGENABLE,		 FALSE );
		dx.SetRenderState( D3DRS_COLORWRITEENABLE,
			D3DCOLORWRITEENABLE_RED  | D3DCOLORWRITEENABLE_GREEN |
			D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA );
		dx.SetTextureStageState( 0, D3DTSS_COLOROP,	D3DTOP_MODULATE );
		dx.SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
		dx.SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
		dx.SetTextureStageState( 0, D3DTSS_ALPHAOP,	D3DTOP_MODULATE );
		dx.SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
		dx.SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
		dx.SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 );
		dx.SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE );
		dx.SetTextureStageState( 1, D3DTSS_COLOROP,	D3DTOP_DISABLE );
		dx.SetTextureStageState( 1, D3DTSS_ALPHAOP,	D3DTOP_DISABLE );
		dx.SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_POINT );
		dx.SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT );
		dx.SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE );
		
		if( which==0 )
			dx.EndStateBlock( &mBlockSaved );
		else
			dx.EndStateBlock( &mBlockDrawText );
	}
	
	return S_OK;
}


HRESULT CD3DFont::passivateDeviceObjects()
{
	safeRelease( mVB );
	safeRelease( mBlockSaved );
	safeRelease( mBlockDrawText );
	
	return S_OK;
}


HRESULT CD3DFont::deleteDeviceObjects()
{
	safeRelease( mTexture );
	//mDevice = NULL;
	
	return S_OK;
}



/*
HRESULT CD3DFont::getTextExtent( const TCHAR* str, SIZE& resSize ) const
{
	if( !str )
		return E_FAIL;
	
	float fRowWidth  = 0.0f;
	float fRowHeight = (mTexCoords[0][3]-mTexCoords[0][1])*mTexHeight;
	float fWidth	 = 0.0f;
	float fHeight	 = fRowHeight;
	
	while( *str ) {
		TCHAR c = *str++;
		
		if( c == _T('\n') ) {
			fRowWidth = 0.0f;
			fHeight  += fRowHeight;
		}
		
		if( (c-32) < 0 || (c-32) >= 128-32 )
			continue;
		
		float tx1 = mTexCoords[c-32][0];
		float tx2 = mTexCoords[c-32][2];
		
		fRowWidth += (tx2-tx1)*mTexWidth - 2*mSpacing;
		
		if( fRowWidth > fWidth )
			fWidth = fRowWidth;
	}
	
	resSize.cx = (int)fWidth;
	resSize.cy = (int)fHeight;
	
	return S_OK;
}
*/


/**
 *  Draws scaled 2D text. Note that x and y are in viewport coordinates
 *  (ranging from -1 to +1). xScale and yScale are the size fraction 
 *  relative to the entire viewport. For example, a xScale of 0.25 is
 *  1/8th of the screen width. This allows you to output text at a fixed
 *  fraction of the viewport, even if the screen or window size changes.
 */
/*
HRESULT CD3DFont::drawTextScaled(

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -