Jump to content
  • Advertisement
Sign in to follow this  
sc_wolf

how draw text with D3DX11

This topic is 1192 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Dear all,
 
I’ve got an issue while trying to draw text with D3DX11, the flow is as following:
Setup a HOOK of abstract function IDXGISwapChain->Present(UINT SyncInterval,  UINT Flags)?
After successfully setup the HOOK, invoke my custom defined function DX11MyDXGISwapChainPresent to record the running frames of the DX11 game;
Draw the counted frames # to let the player know the game real time status(the frame #);
 
The first 2 steps passed but we can not draw the FPS data on screen, the issue is I can not get the DC since an error returned while invoking the GetDC. 
 
Will you please help me to find a solution of drawing the text with D3DX11 on screen?
 
 
Source code as below:
HRESULT __stdcall DX11MyDXGISwapChainPresent(IDXGISwapChain* pSwapChain,
 UINT SyncInterval,
 UINT Flags)
IDXGISurface1 *g_pSurface1 = NULL;
HDC g_hDC;
 
pSwapChain->GetBuffer(0, __uuidof(IDXGISurface1), (void**) &g_pSurface1); //Can get the value of IDXGISurface1 here
 
    g_pSurface1->GetDC(TRUE, &g_hDC );  //Can not get the hdc
 
 
TextOutA(g_hDC,50,50,"hello",5);
 
g_pSurface1->ReleaseDC( NULL );;
 
g_pSurface1->Release();
 
OutputDebugString(_T("SwapChainPresentHook MyDXGISwapChainPresent"));
 
RecodeFrpsProcess(); //Record the FPS data
 
return DX11TrueDXGISwapChainPresent(pSwapChain, SyncInterval, Flags);
}

Share this post


Link to post
Share on other sites
Advertisement

If you have code for drawing 2D quads with textures then you can make good looking bitmap fonts by mapping UV coordinates of each quad to a character in a texture altas. When you have large amounts of text, you can store the UV offsets in a dynamic texture and render the text using a pixel shader in a single quad. The problem is that you won't get unicode at resonable memory costs.

Share this post


Link to post
Share on other sites

The problem is you're mixing GDI and DirectX, and the surface may not be GDI compatible. Games normally use the method Dawoodz mentioned above for rendering text, have a look at the Intel sample code for how they render UI components if you'd like to try that out: http://software.intel.com/en-us/blogs/2013/03/22/software-occlusion-culling-update

 

If you can change the surface to a GDI comapitible one, you can use the GDI functions, see http://stackoverflow.com/questions/5979632/d3d11-how-to-draw-gdi-text-to-a-gxdi-surface-without-d2d

Share this post


Link to post
Share on other sites

Hi there,

 

I am trying to do something similar to this.  But I want to draw text on a texture.

 

I am creating a font "system". I have a base font class and two classes the inherit from it (GraphicFont and TrueTypeFont).

 

GraphicFont loads a png file and a data file.

 

What I want TrueTypeFont to do is create a texture from a width/Height. Draw the letters on it as it calculates the tu/tv.

 

My texture is empty.

 

Here is how I am creating the texture (it gets called from CGraphic::Create(aTexWidth, aTexWidth):

D3D11_TEXTURE2D_DESC textureDesc;
ZeroMemory(&textureDesc, sizeof(textureDesc));
textureDesc.Width = mWidth;
textureDesc.Height = mHeight;
textureDesc.MipLevels = 1;
textureDesc.ArraySize = 1;
textureDesc.Format = /*DXGI_FORMAT_R8G8B8A8_UNORM*/DXGI_FORMAT_B8G8R8A8_UNORM;
textureDesc.SampleDesc.Count = 1;
textureDesc.Usage = D3D11_USAGE_DEFAULT;
textureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
textureDesc.CPUAccessFlags = 0;
textureDesc.MiscFlags = /*0*/D3D11_RESOURCE_MISC_GDI_COMPATIBLE;

Here is how I am trying to draw to it:

CGraphic* apGraphic = CGraphic::Create(aTexWidth, aTexWidth);
if (apGraphic)
{
	apGraphic->SetRenderTarget();

	IDXGISurface1* apSurface = apGraphic->GetSurface();
	HDC hDC;
	apSurface->GetDC(0, &hDC);

	int x = 0, y = 0;
	char str[2] = "\0";
	for (char c = 32; c < 127; c++)
	{
		str[0] = c;
		SIZE Size;
		GetTextExtentPoint32A(hDC, str, 1, &Size);

		int Left = 0;
		int Right = Left + Size.cy;

		if (x + Right > aTexWidth)
		{
			x = 0;
			y += Size.cy;
		}

		Rectangle(hDC, x, y, x + Right, y + Size.cy);
		ExtTextOutA(hDC, x + Left, y, ETO_CLIPPED | ETO_OPAQUE, NULL, str, 1, NULL);

		SFontType aRect;
		aRect.Left = x / ((float)aTexWidth);
		aRect.Top = y / ((float)aTexHeight);
		aRect.Right = (x + Right) / ((float)aTexWidth);
		aRect.Bottom = (y + Size.cy) / ((float)aTexHeight);
		aRect.Height = Size.cy;
		aRect.Width = Size.cx;

		anLetters[c] = aRect;

		x += Right;
	}

	apSurface->ReleaseDC(NULL);
	apGraphic->SaveToPng();
}

Can anyone help me? It is a bit messy from trying this and that.

 

Thanks

Michael

 

 

Share this post


Link to post
Share on other sites

You could try using Map on the surface to map a rect on it and write pixels to it, and if it's not mappable use something like CopySubresourceRegion or UpdateSubresource to copy your text data in.

Share this post


Link to post
Share on other sites
Use dirextxtk's spritefont class or one like my own to do this simply and easily.

If you're stuck let me know and I can advise, it's certainly easier than d3d10 and directwrite...

Share this post


Link to post
Share on other sites

Thank you for your replies.

 

The project I am working on is converting an already existing Dx9 framework to Dx11. The application runs on a Win7 embedded OS. I am trying to keep the design of the framework intact and only change the VideoKit part. 

 

The font system in place currently supports font sprites (GraphicFont class) and truetype fonts (TrueTypeFont class). They inherit from a base class (Font class) that actually does the rendering.  The graphic font class just loads the png file into a texture and the data file that contains the rectangles for each letter.  The truetype font class is suppose to create the texture by rendering the letters on it and calculating the rectangles.

 

The true type font class needs to create fonts on the fly; they can't load the data like the graphic font.

 

The base font class contains a texture (texture class) and a list of the rectangles for each letter.

 

The texture class contains a ID3D11ShaderResourceView and a ID3D11RenderTargetView.

 

In this system, everything that gets drawn on the screen is a texture.

 

 

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!