ID3DX10Font slow

Started by
4 comments, last by MJP 15 years, 11 months ago
im trying to render some text... and its very slow! goes from 0.008s frametime to 0.016s... and thats when go from around 30 chars to 300 chars... what am i doin wrong here?

#include "D3D10Font.hpp"
#include "D3D10Exception.hpp"

#include <iostream>

namespace drone{
    namespace d3d10{

struct Font::Implementation
{
	Implementation(	 RenderDevicePtr pRenderDevice, 
					 INT Height, 
					 UINT Width, 
					 UINT Weight, 
					 UINT MipLevels, 
					 BOOL Italic, 
					 UINT CharSet, 
					 UINT OutputPrecision,
					 UINT Quality,
					 UINT PitchAndFamily,
					 LPCWSTR pFaceName)
	{
		pRenderDevice_ = pRenderDevice;

		HRESULT hr = D3DX10CreateFont(pRenderDevice_->Device(),
									  Height,
									  Width,
									  Weight,
									  MipLevels,
									  Italic,
									  CharSet,
									  OutputPrecision,
									  Quality,
									  PitchAndFamily,
									  pFaceName,
									  &pFont_);

		if (FAILED(hr))
			throw Exception(L"Failed to Create font", hr);

		hr = pFont_->PreloadCharacters(32, 127);

		if(FAILED(hr))
			throw Exception(L"Faled to preload characters", hr);
				
		hr = D3DX10CreateSprite(pRenderDevice_->Device(),512,&pSprite_);

		if (FAILED(hr))
			throw Exception(L"Failed to Create Sprite", hr);


		D3D10_BLEND_DESC StateDesc;
		ZeroMemory(&StateDesc, sizeof(D3D10_BLEND_DESC));
		StateDesc.AlphaToCoverageEnable = FALSE;
		StateDesc.BlendEnable[0] = TRUE;
		StateDesc.SrcBlend = D3D10_BLEND_SRC_ALPHA;
		StateDesc.DestBlend = D3D10_BLEND_INV_SRC_ALPHA;
		StateDesc.BlendOp = D3D10_BLEND_OP_ADD;
		StateDesc.SrcBlendAlpha = D3D10_BLEND_ZERO;
		StateDesc.DestBlendAlpha = D3D10_BLEND_ZERO;
		StateDesc.BlendOpAlpha = D3D10_BLEND_OP_ADD;
		StateDesc.RenderTargetWriteMask[0] = D3D10_COLOR_WRITE_ENABLE_ALL;
		pRenderDevice_->Device()->CreateBlendState(&StateDesc, &pFontBlendState10);
	}	

	void GetFontRectangle(LPCWSTR text, RECT* rect)
	{
		pFont_->DrawText(NULL,
						text,
						-1,
						rect,
						DT_CALCRECT | DT_LEFT,
						D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f));
	}

	void Print(LPCWSTR text, vec4f color, vec2f pos = vec2f(0.0f, 0.0f))
	{
		FLOAT OriginalBlendFactor[4];
		UINT  OriginalSampleMask = 0;

		RECT rc;
		SetRectEmpty(&rc);

		GetFontRectangle(text, &rc);

		rc.bottom += (LONG)pos[1];
		rc.top += (LONG)pos[1];
		rc.left += (LONG)pos[0];
		rc.right += (LONG)pos[0];

		pSprite_->Begin(D3DX10_SPRITE_SORT_TEXTURE);

		pFont_->DrawText( pSprite_, text, -1, &rc, DT_LEFT | DT_EXPANDTABS, D3DXCOLOR( color[0], color[1], color[2], color[3] ) );
		
			pRenderDevice_->Device()->OMGetBlendState(&pOriginalBlendState10, OriginalBlendFactor, &OriginalSampleMask);

			if(pFontBlendState10)
			{
				FLOAT NewBlendFactor[4] = {0,0,0,0};
				pRenderDevice_->Device()->OMSetBlendState(pFontBlendState10, NewBlendFactor, 0xffffffff);
			}

		pSprite_->End();

		pRenderDevice_->Device()->OMSetBlendState(pOriginalBlendState10, OriginalBlendFactor, OriginalSampleMask);
	}

	RenderDevicePtr pRenderDevice_;
	
	ID3DX10FontPtr pFont_;
	ID3DX10SpritePtr pSprite_;

	ID3D10BlendStatePtr		  pOriginalBlendState10;
	ID3D10BlendStatePtr       pFontBlendState10;
};

Font::Font(	 const std::string& id, 
			 RenderDevicePtr pRenderDevice,
			 INT Height, 
			 UINT Width, 
			 UINT Weight, 
			 UINT MipLevels, 
			 BOOL Italic,
			 LPCWSTR pFaceName,
			 UINT CharSet, 
			 UINT OutputPrecision,
			 UINT Quality,
			 UINT PitchAndFamily)  : IFont(id), pImpl_(new Implementation(	pRenderDevice, 
																			 Height, 
																			 Width, 
																			 Weight, 
																			 MipLevels, 
																			 Italic, 
																			 CharSet, 
																			 OutputPrecision,
																			 Quality,
																			 PitchAndFamily,
																			 pFaceName))
{
	std::wcout << L">> Created Font: \"" << id.c_str() << L"\". (D3D10)\n";

}



void Font::Print(const std::wstring& text, vec4f color, vec2f pos)
{
	pImpl_->Print(text.c_str(), color, pos);
}






		
	} // d3d10
} // drone



EDIT:: ive profiled it and [d3dx10d_36.dll] drone::d3d10::Font::Implementation::GetFontRectangle(wchar_t const *,struct is whats takin all the cpu time..
Advertisement
ID3DX10Font is meant to be convenient, not fast. You shouldn't be using it in any performance-critical areas. It works by having GDI write out text to a DIB, and then copies that to a texture. As you can imagine, getting GDI and D3D to work together in this way isn't quick.
what alternatives are there?
Quote:Original post by Dragon_Strike
what alternatives are there?
Implementing your own version is one. I doubt there's many font engines for DX10 yet. Alternatively, using a bitmap font would be fairly straightforward.

As MJP said, if you need performance, don't use ID3DX10Font font (And similarly for DX9's ID3DXFont), it's not up to it.
wrong forum... please move this topic
You could roll a sprite-based system if you wanted. Write out a bunch of letters in a particular font to a texture, then change the texture coordinates based on which letter is selected.

This topic is closed to new replies.

Advertisement