Skip to main content
gamedev.net
🔒 Locked

Font problem...

Started by D_lichu Aug 28, 2008 at 12:32 PM 11 replies 2.4k views
Original Post
D_lichu
D_lichu
Hi all, I got a font problem... I try to use code like this: (from other post, author errand ) LPD3DXFONT g_pD3DXFont; HFONT hFont = CreateFont(28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, PROOF_QUALITY, 0, "Arial"); D3DXCreateFont(d3dDevice, hFont, &g_pD3DXFont); and I only get message "D3DXCreateFontA: function does not take 3 arguments" :/ I also try to use code like this (CD3DFont) Font = new CD3DFont("Times New Roman", 16, 0); // instantiate Font->InitDeviceObjects( Device ); Font->RestoreDeviceObjects(); and it says that it doesn't know any CD3DFont... I use Visual Studio .NET 2003 and got Microsoft DirectX SDK (August 2007). F1? Thanx.
D_lichu
D_lichu
Funny thing - I thought that, when I use hFont (or even &hFont) it should transfer all elements of the structure...

And now

LPD3DXFONT* Font = 0;
D3DXCreateFont(d3ddev,10,10,2,2,0,SYSTEM_FONT,2,2,0,0,Font);

is this correct?
and if it is (NOOB QUESTION), how to draw text?

Tried Font-> but nothing happens...
Evil Steve
Evil Steve
Quote:
Original post by D_lichu
Funny thing - I thought that, when I use hFont (or even &hFont) it should transfer all elements of the structure...

And now

LPD3DXFONT* Font = 0;
D3DXCreateFont(d3ddev,10,10,2,2,0,SYSTEM_FONT,2,2,0,0,Font);

is this correct?
and if it is (NOOB QUESTION), how to draw text?

Tried Font-> but nothing happens...


Firstly, D3DXCreateFont expects you to pass it a pointer to a pointer, not null. You should do something like:
LPD3DXFONT* Font;
D3DXCreateFont(d3ddev,10,10,2,2,0,SYSTEM_FONT,2,2,0,0,&Font);


Secondly, if you use the font in the code you pasted, not "nothing" will happen, your code will crash.

Thirdly, you need to check the return value of D3DXCreateFont to see if it succeeded. The Debug Runtimes will tell you when something goes wrong like this too, but you still need the check.

Fourthly, if you want to create an ID3DXFont from a HFONT, you can use GetObject to get a LOGFONT from the HFONT, which you can pass to D3DXCreateFontIndirect.

Fifthly, I gather that you're a relative beginner at C++. I'd very strongly recommend not going any further with DirectX until you've got a good, solid understanding of C++, and you know how Win32 works well enough to create a window and handle it properly.
D_lichu
D_lichu
"D3DXCreateFont(d3ddev,10,10,2,2,0,SYSTEM_FONT,2,2,0,0,&Font);"

Visual response: "D3DXCreateFontA': cannot convert parameter 12 from LPD3DXFONT**__w64 to LPD3DXFONT*"

"Tried Font-> but nothing happens..."
"Secondly, if you use the font in the code you pasted, not "nothing" will happen, your code will crash."
i mean that i got no options in Font->... (like DrawText or something like that)
Evil Steve
Evil Steve
Quote:
Original post by D_lichu
"D3DXCreateFont(d3ddev,10,10,2,2,0,SYSTEM_FONT,2,2,0,0,&Font);"

Visual response: "D3DXCreateFontA': cannot convert parameter 12 from LPD3DXFONT**__w64 to LPD3DXFONT*"
Argh, sorry that was a typo (late night [smile]). it should be:
LPD3DXFONT Font = 0;
not
LPD3DXFONT* Font = 0;

Quote:
Original post by D_lichu
"Tried Font-> but nothing happens..."
"Secondly, if you use the font in the code you pasted, not "nothing" will happen, your code will crash."
i mean that i got no options in Font->... (like DrawText or something like that)
If you mean it doesn't show the intelisense, that's because you have a pointer to a pointer. You really shouldn't be using intellisense for that anyway, you should be consulting the Documentation and looking at the list of member functions.
D_lichu
D_lichu
From my past - if everything is good then intelisense works.
Now, when I did as you suggested - it works.

But I have one more question (mayby the last one)...

INT ID3DXFont::DrawText(
LPCSTR pString,
INT Count,
LPRECT pRect,
DWORD Format,
D3DCOLOR Color
);


yes?
In one book I found something like this:


Font->DrawText(
"Hello World", // String to draw.
-1, // Null terminating string.
▭, // Rectangle to draw the string in.
DT_TOP | DT_LEFT, // Draw in top-left corner of rect.
0xff000000); // Black.


And the problem is that... I don't know how to create rect structure :/
When I try using something like RECT rect; and then want to fill it (probably that's why my function still isn't working) I cannot... never used rect anyway.

And MSDN didn't help me (or I didn't understand it content and someone must point me a word so I understand :P).
Evil Steve
Evil Steve
Quote:
Original post by D_lichu
From my past - if everything is good then intelisense works.
Yes, but it doesn't always. My point is that you shouldn't rely on it to find out what functions are available. If you know one exists, by all means use it - but use the documentation to check for functions.

Quote:
Original post by D_lichu
And the problem is that... I don't know how to create rect structure :/
When I try using something like RECT rect; and then want to fill it (probably that's why my function still isn't working) I cannot... never used rect anyway.

And MSDN didn't help me (or I didn't understand it content and someone must point me a word so I understand :P).
I'd really recommend stepping back from DirectX and getting to grips with C++ first. A RECT is just a struct, and you set it's members like any other struct:
RECT rc;rc.top = 0;rc.left = 0;rc.right = 100;rc.bottom = 200;
That'd create a rectangle describing the region (0, 0) to (100, 200).
D_lichu
D_lichu
Man, are you reading what I am saying?

"When I try using something like RECT rect; and then want to fill it (probably that's why my function still isn't working) I cannot..."

and if I do:

rect.left=5;

it shows me an error.
"missing ; before ."

And it's not all about that I don't know how to use structures!
Evil Steve
Evil Steve
Quote:
Original post by D_lichu
Man, are you reading what I am saying?

"When I try using something like RECT rect; and then want to fill it (probably that's why my function still isn't working) I cannot..."

and if I do:

rect.left=5;

it shows me an error.
"missing ; before ."

And it's not all about that I don't know how to use structures!
Can we see your exact code? The error means the compiler doesn't know what rect is.
stupid_programmer
stupid_programmer
Quote:
Original post by D_lichu
Man, are you reading what I am saying?

"When I try using something like RECT rect; and then want to fill it (probably that's why my function still isn't working) I cannot..."

and if I do:

rect.left=5;

it shows me an error.
"missing ; before ."

And it's not all about that I don't know how to use structures!


RECT isn't a built in data type like int and float. You are including windows.h right?

D_lichu
D_lichu
Hmmm... I don't know why, but now, after a few days when I do the same things - it works... application is executing, but it come with "Unhandled exeption"...

My source code looks like this:

---MAIN---
// include the basic windows header files and the Direct3D header file
#include
#include
#include
#include
#include
#include
#include "01stala.h"
#include "02funkcje.h"
#include "03przyciski.h"
#include "03ZMyszka.h"
#include "04render.h"
#include "05figury.h"
#include "06Swiatlo.h"
#include "07czcionka.h"




// the entry point for any Windows program
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{


rc.top = 0;
rc.left = 0;
rc.right = 100;
rc.bottom = 200;


ZeroMemory(&wc, sizeof(WNDCLASSEX));

wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WindowProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpszClassName = "WindowClass";

RegisterClassEx(&wc);

hWnd = CreateWindowEx(NULL, "WindowClass", "Our Direct3D Program",
WS_EX_TOPMOST | WS_POPUP, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT,
NULL, NULL, hInstance, NULL);

ShowWindow(hWnd, nCmdShow);

// set up and initialize Direct3D & DInput
initD3D(hWnd);
initDInput(hInstance, hWnd);

// enter the main loop:

while(TRUE)
{
DWORD starting_point = GetTickCount();

if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
break;

TranslateMessage(&msg);
DispatchMessage(&msg);
}

render_frame();

detect_mousepos();
detect_keys();



while ((GetTickCount() - starting_point) < 25);
}

// clean up DirectX and COM
cleanD3D();

return msg.wParam;
}




---"01stala.h"---
// define the screen resolution and keyboard macros

#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600
#define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEY_UP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)

static float kamerad = -10.0f;
static float kameraw = 0.0f;
static float kameraa = 0.0f;
static float kameras = 0.0f;

static float skalal = 1.0f;
static float zoom = 0.0f;
static float indexY = 0.0f;
static float indexX = 0.0f;
int b=1,c=1;

D3DXMATRIX matRotateXc, matRotateX, matRotateY, translate;

// include the Direct3D Library files
#pragma comment (lib, "d3d9.lib")
#pragma comment (lib, "d3dx9.lib")
#pragma comment (lib, "dinput.lib")
#pragma comment (lib, "dinput8.lib")
#pragma comment (lib, "dxguid.lib")

// global declarations
LPDIRECT3D9 d3d; // the pointer to our Direct3D interface
LPDIRECT3DDEVICE9 d3ddev; // the pointer to the device class
LPDIRECT3DVERTEXBUFFER9 t_buffer = NULL; // the pointer to the vertex buffer
LPDIRECTINPUT8 din; // the pointer to our DirectInput interface
LPDIRECTINPUTDEVICE8 dinkeyboard; // the pointer to the keyboard device
LPDIRECTINPUTDEVICE8 dinmouse; // the pointer to the mouse device

struct CUSTOMVERTEX {FLOAT X, Y, Z;D3DVECTOR NORMAL; FLOAT U, V;};
#define CUSTOMFVF (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1)

HWND hWnd;
WNDCLASSEX wc;
MSG msg;

LPDIRECT3DTEXTURE9 texture_1;
LPD3DXFONT Font;

RECT rc;

----02funkcje.h"---
// function prototypes
void initD3D(HWND hWnd); // sets up and initializes Direct3D
void render_frame(void); // renders a single frame
void cleanD3D(void); // closes Direct3D and releases memory
void init_graphics(void); // 3D declarations
void initDInput(HINSTANCE hInstance, HWND hWnd); // sets up and initializes DirectInput
void detect_keys(void); // gets the current keys being pressed
void cleanDInput(void); // closes DirectInput and releases memory
void detect_mousepos(void); // gets the mouse movement and updates the static variables
void przyciski(void);
void render(void);
void rysuj(void);
void init_light(void);
// the WindowProc function prototype
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

// this is the main message handler for the program
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
} break;
}

return DefWindowProc (hWnd, message, wParam, lParam);
}


// this function initializes and prepares Direct3D for use
void initD3D(HWND hWnd)
{
d3d = Direct3DCreate9(D3D_SDK_VERSION);

D3DPRESENT_PARAMETERS d3dpp;

ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = FALSE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = hWnd;
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
d3dpp.BackBufferWidth = SCREEN_WIDTH;
d3dpp.BackBufferHeight = SCREEN_HEIGHT;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;

/*
HFONT hFont = (HFONT)GetStockObject( SYSTEM_FONT );

r = D3DXCreateFont( d3ddev, hFont, &pFont );
*/

D3DXCreateFont(d3ddev,10,10,2,2,0,SYSTEM_FONT,2,2,0,0,&Font); // d3dDevice is a valif D3D Device


// create a device class using this information and the info from the d3dpp stuct
d3d->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp,
&d3ddev);

init_graphics(); // call the function to initialize the triangle
init_light(); // call the function to initialize the light and material

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

return;
}

void initDInput(HINSTANCE hInstance, HWND hWnd)
{
// create the DirectInput interface
DirectInput8Create(hInstance, // the handle to the application
DIRECTINPUT_VERSION, // the compatible version
IID_IDirectInput8, // the DirectInput interface version
(void**)&din, // the pointer to the interface
NULL); // COM stuff, so we'll set it to NULL

// create the keyboard device
din->CreateDevice(GUID_SysKeyboard, // the default keyboard ID being used
&dinkeyboard, // the pointer to the device interface
NULL); // COM stuff, so we'll set it to NULL

// create the mouse device
din->CreateDevice(GUID_SysMouse, // the default mouse ID being used
&dinmouse, // the pointer to the device interface
NULL); // COM stuff, so we'll set it to NULL

dinkeyboard->SetDataFormat(&c_dfDIKeyboard); // set the data format to keyboard format
dinmouse->SetDataFormat(&c_dfDIMouse); // set the data format to mouse format

// set the control you will have over the keyboard
dinkeyboard->SetCooperativeLevel(hWnd,
DISCL_NONEXCLUSIVE | DISCL_BACKGROUND);
// set the control you will have over the mouse
dinmouse->SetCooperativeLevel(hWnd,
DISCL_NONEXCLUSIVE | DISCL_BACKGROUND);

dinmouse->Acquire(); // Acquire the mouse only once
return; // return to WinMain()
}

// this is the function that cleans up Direct3D and COM
void cleanD3D(void)
{
t_buffer->Release(); // close and release the vertex buffer
texture_1->Release(); // close and release the texture
dinkeyboard->Unacquire(); // make sure the keyboard is unacquired
dinmouse->Unacquire(); // make sure the mouse is unacquired
din->Release(); // close DirectInput before exiting
d3ddev->Release(); // close and release the 3D device
d3d->Release(); // close and release Direct3D

return;
}


// this is the function that puts the 3D models into video RAM
void init_graphics(void)
{
D3DXCreateTextureFromFile(d3ddev,
"Wood.png",
&texture_1);

// create the vertices using the CUSTOMVERTEX struct
CUSTOMVERTEX t_vert[] =
{

{ 0.0f, 3.0f, 0.0f, 0,0,-1,0,0, },
{ 3.0f, 3.0f, 0.0f, 0,0,-1,1,0, },
{ 0.0f, 0.0f, 0.0f, 0,0,-1,0,1, },
{ 3.0f, 0.0f, 0.0f, 0,0,-1,1,1, },
};

// create a vertex buffer interface called t_buffer
d3ddev->CreateVertexBuffer(4*sizeof(CUSTOMVERTEX),
0,
CUSTOMFVF,
D3DPOOL_MANAGED,
&t_buffer,
NULL);

VOID* pVoid; // a void pointer

// lock t_buffer and load the vertices into it
t_buffer->Lock(0, 0, (void**)&pVoid, 0);
memcpy(pVoid, t_vert, sizeof(t_vert));
t_buffer->Unlock();

return;
}

---"04render.h"---
void render_frame(void)
{
d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
d3ddev->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);

d3ddev->BeginScene();

// select which vertex format we are using
d3ddev->SetFVF(CUSTOMFVF);




rysuj();

///////////////////////
//KAMERA//
///////////////////////
D3DXMATRIX matView; // the view transform matrix

D3DXMatrixLookAtLH(&matView,
&D3DXVECTOR3 (0, 0.0f, -10.0f ), // the camera position
&D3DXVECTOR3 (0.0, 0.0f, 0.0), // the look-at position
&D3DXVECTOR3 (0.0f, 1.0f, 0.0f)); // the up direction

d3ddev->SetTransform(D3DTS_VIEW, &matView); // set the view transform to matView

D3DXMATRIX matProjection; // the projection transform matrix

D3DXMatrixPerspectiveFovLH(&matProjection,
D3DXToRadian(45-zoom), // the horizontal field of view
(FLOAT)SCREEN_WIDTH / (FLOAT)SCREEN_HEIGHT, // aspect ratio
1.0f, // the near view-plane
100.0f); // the far view-plane

d3ddev->SetTransform(D3DTS_PROJECTION, &matProjection); // set the projection

// select the vertex buffer to display
d3ddev->SetStreamSource(0, t_buffer, 0, sizeof(CUSTOMVERTEX));

d3ddev->EndScene();

d3ddev->Present(NULL, NULL, NULL, NULL);

return;
}

---"05figury.h"---
void rysuj(void)
{

Font->DrawText(NULL, "Hello World", -1, &rc, DT_LEFT, 0xff000000);


D3DXMatrixRotationX(&matRotateX, indexX);
//przod
D3DXMatrixRotationY(&matRotateY, indexY);
D3DXMatrixTranslation(&translate, -1.5f,-1.5,-1.5);
d3ddev->SetTransform(D3DTS_WORLD, &(translate*matRotateY*matRotateX));
d3ddev->SetTexture(0, texture_1);
d3ddev->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
//tyl
D3DXMatrixRotationY(&matRotateY, D3DXToRadian(180.0f)+indexY);
d3ddev->SetTransform(D3DTS_WORLD, &(translate*matRotateY*matRotateX));
d3ddev->SetTexture(0, texture_1);
d3ddev->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
//bok prawy
D3DXMatrixRotationY(&matRotateY, D3DXToRadian(90.0f)+indexY);
d3ddev->SetTransform(D3DTS_WORLD, &(translate*matRotateY*matRotateX));
d3ddev->SetTexture(0, texture_1);
d3ddev->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
//bok lewy
D3DXMatrixRotationY(&matRotateY, D3DXToRadian(-90.0f)+indexY);
d3ddev->SetTransform(D3DTS_WORLD, &(translate*matRotateY*matRotateX));
d3ddev->SetTexture(0, texture_1);
d3ddev->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
//gora
D3DXMatrixRotationX(&matRotateXc, D3DXToRadian(-90.0f));
d3ddev->SetTransform(D3DTS_WORLD, &(translate*matRotateXc*matRotateY*matRotateX));
d3ddev->SetTexture(0, texture_1);
d3ddev->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
//dol
D3DXMatrixRotationX(&matRotateXc, D3DXToRadian(90.0f));
d3ddev->SetTransform(D3DTS_WORLD, &(translate*matRotateXc*matRotateY*matRotateX));
d3ddev->SetTexture(0, texture_1);
d3ddev->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
}



Sorry for this long time form my replay - Internet crash...
Evil Steve
Evil Steve
Quote:
Original post by D_lichu
Hmmm... I don't know why, but now, after a few days when I do the same things - it works... application is executing, but it come with "Unhandled exeption"...
Ok, some points:

  1. What line is the exception on, and what is the exact error message you get?

  2. Why are you not checking any return values? That's almost certainly the cause of the crash. D3D uses return values to tell you if a function succeeded, or if it failed. And if it failed, then any interface pointers will be null (Or possibly invalid, I don't know if D3D / COM guarantees they'll be null).

  3. Your cleanD3D function assumes all the interfaces are valid, doesn't check they're null and doesn't set them to null after. That's extremely bad form, and is likely going to cause crashes at some point.

  4. What do the Debug Runtimes say about it?

  5. I really wouldn't use DirectInput for keyboard or mouse input.

  6. You're not checking if the device you're trying to create is even supported. There's a few functions you need to call to check that a particular device setup is usable. Relevant link

  7. You shouldn't clear the backbuffer and Z-buffer in two passes, that just makes it twice as slow (And on some drivers, more than twice as slow). Do it in one by bitwise OR-ing the flags together

  8. You're doing rendering before you've set up your device to render. The only reason it'll work is because the state from the last frame is still sticking around.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.