Jump to content
  • Advertisement
Sign in to follow this  
kiwicoder

LPD3DXFONT-DrawText Positioning

This topic is 3883 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

Having a bit of trouble trying to position 2D text on the screen. When I position it at 0,0 it renders in the correct position, but as it gets lower on screen it seems to "slip out" of the rect as illustrated in this image: Free Image Hosting at allyoucanupload.com Important bits of code:

RECT fontRect;
	
LPD3DXFONT font;
D3DXCreateFont( directXDevice, 30, 0, FW_NORMAL, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH | FF_DONTCARE, TEXT("Arial"), &font );

//...

for(int x = 0; x <= 1000; x = x + 50)
{
  SetRect(&fontRect, 0, x, 500, 500);
  font->DrawText(NULL, "TEST", -1, &fontRect, DT_SINGLELINE | DT_TOP, D3DCOLOR_XRGB(160, 160, 160) );
}

Complete code
#include <windows.h>
#include <d3d9.h> 
#include <d3dx9.h>
#include <dinput.h> 

#define SAFE_DELETE(p)  { if(p) { delete (p);     (p)=NULL; } }
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }

const char	MAIN_WINDOW_TITLE[] = "Window",
			MAIN_WINDOW_CLASS_NAME[] = "WindowClass";

const int	MAIN_WINDOW_WIDTH  = 750,
			MAIN_WINDOW_HEIGHT = 750;

int int_AppRunning = true;

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch(msg)
	{
		case WM_CLOSE:
			DestroyWindow(hwnd);
			int_AppRunning = false;
			break;
		case WM_DESTROY:
			PostQuitMessage(0);
			int_AppRunning = false;
			break;
		default:
			return DefWindowProc(hwnd, msg, wParam, lParam);
	}
	return 0;
}


WNDCLASSEX initWindow(HINSTANCE hInstance)
{
	WNDCLASSEX w;
	//Register window class
	w.cbSize = sizeof(WNDCLASSEX);
	w.style = 0;
	w.lpfnWndProc = WndProc;
	w.cbClsExtra = 0;
	w.cbWndExtra = 0;
	w.hInstance = hInstance;
	w.hIcon = LoadIcon(NULL, IDI_APPLICATION); // large icon (Alt+Tab)
	w.hCursor = LoadCursor(NULL, IDC_ARROW);
	w.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	w.lpszMenuName = NULL;
	w.lpszClassName = MAIN_WINDOW_CLASS_NAME;
	w.hIconSm = LoadIcon(NULL, IDI_APPLICATION); // small icon (title bar)


	if(!RegisterClassEx(&w)){
		MessageBox(NULL, "RegisterClassEx() failed", "System error",
			MB_ICONEXCLAMATION | MB_OK);
	}

	return w;
}



int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	
	WNDCLASSEX w = initWindow(hInstance);
	DWORD windowStyle = WS_OVERLAPPEDWINDOW;

	// Create window
	HWND hwnd = CreateWindowEx(NULL, MAIN_WINDOW_CLASS_NAME, MAIN_WINDOW_TITLE,windowStyle, CW_USEDEFAULT, CW_USEDEFAULT, MAIN_WINDOW_WIDTH, MAIN_WINDOW_HEIGHT, NULL, NULL, hInstance, NULL);

	if(hwnd == NULL){
		MessageBox(NULL, "CreateWindowEx() failed", "System error", MB_ICONEXCLAMATION | MB_OK);
		return 0;
	}

	// Show window
	ShowWindow(hwnd, nCmdShow);
	UpdateWindow(hwnd);

	// Init DirectX objects
	LPDIRECT3D9 directX;
	LPDIRECT3DDEVICE9 directXDevice;

	D3DPRESENT_PARAMETERS dxPresentParams;

	directX = Direct3DCreate9(D3D_SDK_VERSION);
	if (directX == NULL){
		::MessageBox(hwnd, "DirectX runtime library is not installed.", "System error", MB_ICONEXCLAMATION | MB_OK);
	}

	ZeroMemory( &dxPresentParams, sizeof(dxPresentParams) );
	dxPresentParams.Windowed = true;
	dxPresentParams.SwapEffect = D3DSWAPEFFECT_DISCARD;
	dxPresentParams.BackBufferFormat = D3DFMT_UNKNOWN;		
    dxPresentParams.SwapEffect = D3DSWAPEFFECT_DISCARD;
    dxPresentParams.hDeviceWindow = hwnd;
    dxPresentParams.BackBufferFormat = D3DFMT_X8R8G8B8;
    dxPresentParams.BackBufferWidth = MAIN_WINDOW_WIDTH;
    dxPresentParams.BackBufferHeight = MAIN_WINDOW_HEIGHT;
    dxPresentParams.EnableAutoDepthStencil = TRUE;  
    dxPresentParams.AutoDepthStencilFormat = D3DFMT_D16;
	D3DDISPLAYMODE d3ddm;

	directX->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm);

	if (FAILED(directX->CreateDevice(
		D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, 
		hwnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, 
		&dxPresentParams, &directXDevice))){
		if (FAILED(directX->CreateDevice(
			D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, 
			hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, 
			&dxPresentParams, &directXDevice))){
			::MessageBox(hwnd, 
			"CreateDevice() failed", "System error", 
			MB_ICONEXCLAMATION | MB_OK);
		}
	}

	directXDevice->SetRenderState(D3DRS_LIGHTING, TRUE);    // turn on the 3D lighting
    directXDevice->SetRenderState(D3DRS_ZENABLE, TRUE);    // turn on the z-buffer
    directXDevice->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(50, 50, 50));    // ambient light

	// Init Font	
	RECT fontRect;
	
	LPD3DXFONT font;
	D3DXCreateFont( directXDevice, 30, 0, FW_NORMAL, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH | FF_DONTCARE, TEXT("Arial"), &font );

	MSG msg;
	while(int_AppRunning)
	{
		if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE)){
			::TranslateMessage(&msg);
			::DispatchMessage(&msg);
		}	

		directXDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(255, 255, 255), 1.0f, 0);
		directXDevice->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
		directXDevice->BeginScene();



		for(int x = 0; x <= 1000; x = x + 50)
		{
			SetRect(&fontRect, 0, x, 500, 500);
			font->DrawText(NULL, "TEST", -1, &fontRect, DT_SINGLELINE | DT_TOP, D3DCOLOR_XRGB(160, 160, 160) );
		}		
		directXDevice->EndScene();
		directXDevice->Present(NULL, NULL, NULL, NULL);

		Sleep(100);
		
	}

	SAFE_RELEASE(directXDevice);
	SAFE_RELEASE(directX)
	SAFE_RELEASE(font);

	DestroyWindow(hwnd);
	return 0;
}



Any help as to what im doing wrong here would be much appreciated. Thanks.

Share this post


Link to post
Share on other sites
Advertisement
I would say it's the background texture that is wrong, check it :)

secondly...

// to clear both screen and zbuffer
directXDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(255, 255, 255), 1.0f, 0);

// c++ supports += operator
for(int x = 0; x <= 1000; x += 50)

Share this post


Link to post
Share on other sites
Thanks for the clearing tip.

I'm not quite sure what you mean by 'background texture' the red boxes were added to the output via photoshop, to show where the rects are.

Share this post


Link to post
Share on other sites
ok, well you must have drawn those line wrong then :)

and it should be:
SetRect(&fontRect, 0, x, 500, x + 500);

Share this post


Link to post
Share on other sites
I've double checked and the red boxes are 50px in height (including the 1px red lines).

The reason why I'm trying to solve this problem is that I change the color of the text when the mouse is within the rect. So I'm pretty sure about the position of the rects.

I've changed my code to:

SetRect(&fontRect, 0, x, 500, x + 500); (as it is in my actual game)

but the only difference it makes is that the text now shows below y = 500px

Any other ideas?

Share this post


Link to post
Share on other sites
The problem is most likely your window creation code. When you call CreateWindow() you pass it MAIN_WINDOW_WIDTH and MAIN_WINDOW_HEIGHT and when you set your present parameters you use the same sizes. Unfortunately, the client area of your window is going to be smaller than MAIN_WINDOW_WIDTH and MAIN_WINDOW_HEIGHT since the values you pass to CreateWindow() include things like the window caption and borders. Try using AdjustWindowRect() to account for the difference.

Share this post


Link to post
Share on other sites
Thanks SiCrane that seems to have fixed it (it still slips a little but not as much).

The msdn docs say that WS_OVERLAPPED can't be used with AdjustWindowRect:
http://msdn2.microsoft.com/en-us/library/ms632665(VS.85).aspx

but they don't specify why? Is it simply because WS_OVERLAPPED is an aggregate of other window styles?

Share this post


Link to post
Share on other sites
I don't know the official reason, but I've been told it's because WS_OVERLAPPED has a numeric value of 0 and the code that adjusts the rectangle works off of the bit flags so the 0 value isn't processed correctly. This is hearsay so take it with a grain of salt.

Here is a thread that describes other posters' workarounds for this.

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!