Directx 9 Create Font Issue

Started by
4 comments, last by kamal7 12 years, 9 months ago
I am having trouble creating font from an external class command outside my WinMain.cpp file. However it works if i send the external command in my "main" .cpp file. I was just wondering why it won't work in my Game.cpp file. Here are my codes:

WinMain.cpp: removed some irrelevant code.
m_pGame->MainDisplay(); initiates the external class there the external font commands are sent.
#include <windows.h>
#include <d3dx9.h>
#include "Game.h"

HWND g_hWnd;

LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

class CGame * m_pGame;
class CDxDraw DxDraw;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow)
{ char szAppClass[32];
MSG uMsg;
RECT rScreen;

sprintf(szAppClass, "Client-%d", hInstance);

WNDCLASSEX wc;

wc.cbSize = sizeof(WNDCLASSEX);
wc.style = (CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS);
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = szAppClass;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

RegisterClassEx(&wc);

DWORD dwStyle;

g_hWnd = CreateWindow(szAppClass, "Helbreath 2 - A New Era", dwStyle, 0, 0, wx, wy, NULL, NULL, hInstance, NULL);

if (!g_hWnd) {
MessageBox(g_hWnd, "Create window pointer is corrupt.", "ERROR!", MB_OK);
return 0;
}

if (DxDraw.DX3DInit(wx, wy) != S_OK)
{
MessageBox(g_hWnd, "Initialization error.", "ERROR!", MB_OK);
return 0;
}

m_pGame = new class CGame;

ShowWindow(g_hWnd, nCmdShow);
UpdateWindow(g_hWnd);

char cTxt[32];
short msX, msY, msZ;
char cLB, cRB;
HRESULT hr;

while(GetMessage(&uMsg, NULL, 0, 0))
{
DxDraw.BeginRender();
m_pGame->MainDisplay();
//DxDraw.DisplayText(cTxt, 0, wy-20, wx, -1, 255, 255, 255, 255); // THIS COMMAND WORKS HERE!!! BUT NOT IN m_pGame->MainDisplay(); FOR SOME ODD REASON.....
DxDraw.DisplayText("Beta Client", 10, wy-20, -1, -1, 255, 0, 200, 0);
DxDraw.EndRender();

TranslateMessage(&uMsg);
DispatchMessage(&uMsg);
}

return 0;
}


Game.cpp: class which contains the MainDisplay(); function and create font commands.
#include "Game.h"

extern int m_iMaxRes_X, m_iMaxRes_Y, wx, wy;
extern HWND g_hWnd;

CGame::CGame()
{
}

CGame::~CGame()
{
}

void CGame::MainDisplay()
{
DrawGame.DisplayText("Beta Client", 10, 20, -1, -1, 255, 0, 200, 0); // DOESN'T SEEM TO WORK FOR SOME REASON....
}


Game.h: For definitions.

#include <windows.h>
#include <stdio.h>
#include "DxDraw.h"

class CGame
{
public:
CGame();
virtual ~CGame();

void MainDisplay();
void DebugLog(char *cStr);

class CDxDraw DrawGame;
class CDxInput InputGame;
};


DxDraw.cpp: This calls all the d3d graphics functions (i.e. DisplayText(....) )
#include "DxDraw.h"

extern bool bFullScreen;
extern int m_iMaxRes_X, m_iMaxRes_Y, wx, wy;
extern HWND g_hWnd;

CDxDraw::CDxDraw()
{
g_pDirect3D = NULL;
g_pD3DDevice = NULL;
m_pFont = NULL;
}

CDxDraw::~CDxDraw()
{ int i;

for (i = 0; i < DEF_MAXSPRITES; i++) m_pSprite = NULL;
m_pFont->Release();
g_pD3DDevice->Release();
g_pDirect3D->Release();
}

HRESULT CDxDraw::DX3DInit(DWORD iWidth, DWORD iHeight)
{
if ((g_pDirect3D = Direct3DCreate9(D3D_SDK_VERSION)) == NULL){
MessageBox(g_hWnd, "Direct3D create interface pointer is undefined.", "ERROR!", MB_OK);
return 0;
}

ZeroMemory(&d3dpp, sizeof(d3dpp));

d3dpp.BackBufferWidth = iWidth;
d3dpp.BackBufferHeight = iHeight;
d3dpp.hDeviceWindow = g_hWnd; // set the window to be used by Direct3D
d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8; // set the back buffer format: D3DFMT_A16B16G16R16 = 64-bit (unavailable), D3DFMT_A8R8G8B8 = 32-bit with alpha channel

if (bFullScreen) { // Fullscreen Mode
d3dpp.SwapEffect = D3DSWAPEFFECT_FLIP; // discard old frames
d3dpp.BackBufferCount = 1;
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
d3dpp.Windowed = FALSE; // program fullscreen
}else { // Window Mode
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; // discard old frames
d3dpp.Windowed = TRUE; // program windowed
}

HRESULT hRes;
if(FAILED(hRes = g_pDirect3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd, D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp, &g_pD3DDevice))) return hRes;

float Aspect = (float)d3dpp.BackBufferWidth / (float)d3dpp.BackBufferHeight;
D3DXMATRIX matProjection;
D3DXMatrixPerspectiveFovLH(&matProjection, D3DX_PI/4.0f, Aspect, 0.001f, 1000.0f);
g_pD3DDevice->SetTransform(D3DTS_PROJECTION, &matProjection);
g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);

D3DXCreateFont(g_pD3DDevice, 13, 0, FW_BOLD, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, TEXT("Tahoma"), &m_pFont);

return S_OK;
}

void CDxDraw::BeginRender()
{ int i;
if (g_pD3DDevice == NULL) return;

// Clear the backbuffer to a black color
g_pD3DDevice->Clear( 0, //number of rectangles to clear, 0 for all
NULL, //rects to be cleared, NULL for entire buffer
D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, //the buffers to clear
D3DCOLOR_XRGB(255,255,255), //the Color to fill the buffer with
1.0f, //depth for the z-buffer to clear
0 //stencil buffer clear
);

g_pD3DDevice->BeginScene();

for (i = 0; i < DEF_MAXSPRITES; i++)
if (m_pSprite != NULL) m_pSprite->render(100);
}

void CDxDraw::EndRender()
{
//Notify the device that we're finished rendering for this frame
g_pD3DDevice->EndScene();

//Show the results
g_pD3DDevice->Present(NULL, //Source rectangle to display, NULL for all of it
NULL, //Destination rectangle, NULL to fill whole display
NULL, //Target window, if NULL uses device window set in CreateDevice
NULL //Unused parameter, set it to NULL
);
}

void CDxDraw::DisplayText(char *pString, short sX, short sY, short sMaxW_X, short sMaxL_Y, short sA, short sR, short sG, short sB)
{
// Create a rectangle to indicate where on the screen it should be drawn
RECT rct;
rct.left = sX;
rct.top = sY;

//Set default rectangle coordinates (hidden)
m_pFont->DrawText(NULL, pString, -1, &rct, DT_CALCRECT | DT_WORDBREAK | DT_SINGLELINE, NULL);

//Determine if align is required and set max rectangle rct.right(x)/rct.bottom(y) coordinates.
if (sMaxW_X != -1) rct.right = rct.left+sMaxW_X;
if (sMaxL_Y != -1) rct.bottom = rct.top+sMaxL_Y;

//Draw text in set rectangle coordinates
m_pFont->DrawText(NULL, pString, -1, &rct, DT_WORDBREAK | DT_SINGLELINE | DT_CENTER | DT_VCENTER, D3DCOLOR_ARGB(sA,sR,sG,sB)); //D3DCOLOR_ARGB(alpha,red,green,blue)
}
}


DxDraw.h: Incase the problem is here...

#include <windows.h>
#include <d3dx9.h>

class CDxDraw
{
public:
CDxDraw();
virtual ~CDxDraw();

LPDIRECT3D9 g_pDirect3D;
LPDIRECT3DDEVICE9 g_pD3DDevice;
D3DPRESENT_PARAMETERS d3dpp;
LPD3DXFONT m_pFont;

HRESULT DX3DInit(DWORD iWidth, DWORD iHeight);
void BeginRender();
void EndRender();
void DisplayText(char *pString, short sX, short sY, short sMaxW_X, short sMaxL_Y, short sA, short sR, short sG, short sB);
void bInit();
void ResetDevice();
};


Thanks for your patience and help.

Sincerely, Kamal.
Advertisement
What error are you getting?
The problem is

[color="#1C2837"][color="#000088"]class [color="#660066"]CDxDraw [color="#660066"]DxDraw[color="#1C2837"][color="#666600"];
[color="#666600"]
in WinMain.cpp and

[color="#1C2837"][color="#000088"]class [color="#660066"]CDxDraw [color="#660066"]DrawGame[color="#1C2837"][color="#666600"];
[color="#666600"]
in Game.h are two different objects. You initialize the first one but you don't initialize the second one. That's why it can't draw anything (it crashes, doesn't it?). Quick solution: Remove the first one in WinMain.cpp and move initialization

[color="#1C2837"][color="#000088"]if [color="#666600"]([color="#660066"]DxDraw[color="#666600"].[color="#000000"]DX3DInit[color="#666600"]([color="#000000"]wx[color="#666600"],[color="#000000"] wy[color="#666600"]) [color="#666600"]!=[color="#000000"] S_OK[color="#666600"]) [color="#666600"]{ [color="#660066"]MessageBox[color="#666600"]([color="#000000"]g_hWnd[color="#666600"], [color="#008800"]"Initialization error."[color="#666600"], [color="#008800"]"ERROR!"[color="#666600"],[color="#000000"] MB_OK[color="#666600"]); [color="#000088"]return [color="#006666"]0[color="#666600"]; [color="#1C2837"][color="#666600"]}
[color="#666600"]
to the CGame class. You are creating Direct3D device in CDxDraw class, so don't initialize both at the same time.

Also, debugger.

// I hate formatting on those forums. : P

The problem is

[color="#1C2837"][color="#000088"]class [color="#660066"]CDxDraw [color="#660066"]DxDraw[color="#1C2837"][color="#666600"];
in WinMain.cpp and

[color="#1C2837"][color="#000088"]class [color="#660066"]CDxDraw [color="#660066"]DrawGame[color="#1C2837"][color="#666600"];
in Game.h are two different objects. You initialize the first one but you don't initialize the second one. That's why it can't draw anything (it crashes, doesn't it?). Quick solution: Remove the first one in WinMain.cpp and move initialization

[color="#1C2837"][color="#000088"]if [color="#666600"]([color="#660066"]DxDraw[color="#666600"].[color="#000000"]DX3DInit[color="#666600"]([color="#000000"]wx[color="#666600"],[color="#000000"] wy[color="#666600"]) [color="#666600"]!=[color="#000000"] S_OK[color="#666600"]) [color="#666600"]{ [color="#660066"]MessageBox[color="#666600"]([color="#000000"]g_hWnd[color="#666600"], [color="#008800"]"Initialization error."[color="#666600"], [color="#008800"]"ERROR!"[color="#666600"],[color="#000000"] MB_OK[color="#666600"]); [color="#000088"]return [color="#006666"]0[color="#666600"]; [color="#1C2837"][color="#666600"]}
to the CGame class. You are creating Direct3D device in CDxDraw class, so don't initialize both at the same time.

Also, debugger.

// I hate formatting on those forums. : P


I have done as you told, Game.cpp now looks like this...

#include "Game.h"

extern int m_iMaxRes_X, m_iMaxRes_Y, wx, wy;
extern HWND g_hWnd;

CGame::CGame()
{
if (DxDraw.DX3DInit(wx, wy) != S_OK)
{
MessageBox(g_hWnd, "Initialization error.", "ERROR!", MB_OK);
}
}

CGame::~CGame()
{
}

void CGame::MainDisplay()
{
DxDraw.BeginRender();
DxDraw.DisplayText("Beta Client", 10, wy-20, -1, -1, 255, 0, 200, 0);
DxDraw.EndRender();
}


I know the issue is the command DxDraw.BeginRender(); in Game.cpp because when I remove it... the .exe doesn't crash. But I need this command in order to display the font/rendering.

I have run the Debugger and this is what it outputs:

First-chance exception at 0x011b4b1b in Helbreath 2 Client.exe: 0xC0000005: Access violation reading location 0xcdcdcded.
Unhandled exception at 0x011b4b1b in Helbreath 2 Client.exe: 0xC0000005: Access violation reading location 0xcdcdcded.
bump
Problem solved. Thanks for all your help guys! Apparently I had more than one problem with my code, my sprite classes weren't defined as NULL prior to initiating them which would affect my code.

This topic is closed to new replies.

Advertisement