Thread: DirectX9 Font Problem

  1. #1
    Yah. Morgul's Avatar
    Join Date
    Feb 2005
    Posts
    109

    Question DirectX9 Font Problem

    It is the *start* of my game and of my first real program with DirectX. I'm still working off tutorials and trying to learn it as fast as possible so that I can make a game immediately. I have come upon one issue when it came to writing text to the screen.

    All the tutorials I have read have told me to load/write fonts in a certain way. However, when I tried it in my compiler, it came up with an error, saying there were too many arguments and stuff. I am now doing it the way the compiler told me to.

    The prototype:
    Code:
    HRESULT WINAPI
        D3DXCreateFont(
            LPDIRECT3DDEVICE9   pDevice,
            HFONT               hFont,
            LPD3DXFONT*         ppFont);
    The original prototype:
    Code:
    HRESULT WINAPI D3DXCreateFont(LPDIRECT3DDEVICE9 pDevice,
        INT Height,
        UINT Width,
        UINT Weight,
        UINT MipLevels,
        BOOL Italic,
        DWORD CharSet,
        DWORD OutputPrecision,
        DWORD Quality,
        DWORD PitchAndFamily,
        LPCTSTR pFacename,
        LPD3DXFONT *ppFont);
    Even the MSDN tutorial said to use the second way, but it doesn't work. Also, the way of writing text in the scene didn't work.

    Old way:
    Code:
    Font->DrawText(NULL, "Text Here", -1, &FontPosition, DT_CENTER, 0xffffffff);
    The way the compiler said (cant find the prototype, so this is how I did it):
    Code:
    Font->DrawText("Demo", 0, &FontPosition, DT_CENTER, 0xffffffff);
    Anyway, I fixed both those things in my code and so I got no more errors. However, the program quits immediately after starting, and I want to know why.

    The code for my program (I am just starting out and have a random triangle in there for no reason):
    Code:
    #define WIN32_LEAN_AND_MEAN
    
    #include<d3dx9.h>
    
    #define D3DFVF_D3DVertex (D3DFVF_XYZ | D3DFVF_DIFFUSE)
    
    bool InitializeDirect3D(HWND hwnd, bool fullscreen);
    bool InitializeObject();
    void RenderScence();
    void ShutdownDirect3D();
    LPDIRECT3D9 Direct3D_Object = NULL;
    LPDIRECT3DDEVICE9 D3D_Device = NULL;
    LPD3DXFONT Font = NULL;
    LPDIRECT3DVERTEXBUFFER9 Vertex_Buffer = NULL;
    RECT FontPosition = {0, 0, 0, 0};
    HFONT hfont = CreateFont(0, 1, 0, 0, FW_DONTCARE, false, false, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_MODERN, "Courier New");
    struct Vertex
    {
        FLOAT x, y, z;
        DWORD color;
    };
    
    
    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch(message) {
    		   case WM_KEYUP:
    		       switch(wParam) {
    		           case VK_ESCAPE:
    		               PostQuitMessage(0);
    		               break;
                   }        
                break;
             case WM_DESTROY:
             case WM_CLOSE:
                PostQuitMessage(0);
                break;
             default:
                   break;
         }
         return DefWindowProc( hwnd, message, wParam, lParam );
    }
    
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
    {
       MSG msg;
       HWND hwnd;
       WNDCLASSEX windowClass;
       bool done = false;
       windowClass.cbSize = sizeof(WNDCLASSEX);
       windowClass.style = CS_HREDRAW | CS_VREDRAW;
       windowClass.lpfnWndProc = WndProc;
       windowClass.cbClsExtra = 0;
       windowClass.cbWndExtra = 0;
       windowClass.hInstance = hInstance;
       windowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
       windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
       windowClass.hbrBackground = NULL;
       windowClass.lpszMenuName = NULL;
       windowClass.lpszClassName = "XClass";
       windowClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
       if(!RegisterClassEx(&windowClass)) return 0;
       hwnd = CreateWindow("XClass", "Empty DirectX", WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_SYSMENU |WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 100, 100, 640, 480, NULL, NULL, hInstance, NULL);
       if(!hwnd) return 0;
    
       ShowWindow(hwnd, SW_SHOW);
       UpdateWindow(hwnd);
       done = false;
       if(!InitializeDirect3D(hwnd, true)) done = true;
       while(!done)
          {
             if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
                {
                   if(msg.message == WM_QUIT)
                      {
                         done = true;
                      }
                   TranslateMessage(&msg);
                   DispatchMessage(&msg);
                }
             else
                {
                   RenderScence();
                }
          }
    	ShutdownDirect3D();
       UnregisterClass("XClass", windowClass.hInstance);
    
       return (int)msg.wParam;
    }
    
    
    bool InitializeDirect3D(HWND hwnd, bool fullscreen) {
       D3DDISPLAYMODE DisplayMode;
       D3DPRESENT_PARAMETERS Present_Parameters;
       D3DCAPS9 D3DCaps;
       ZeroMemory(&Present_Parameters, sizeof(Present_Parameters));
       Direct3D_Object = Direct3DCreate9(D3D_SDK_VERSION);
       if(Direct3D_Object == NULL)
          {
             MessageBox(NULL, "Error, couldn't initialize DirectX", "Error!", MB_ICONSTOP | MB_OK);
             return false;
          }
       if(FAILED(Direct3D_Object->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &DisplayMode))) {
           MessageBox(NULL, "Error setting the display mode.", "Error!", MB_ICONSTOP | MB_OK);
           return false;
       }
       if(FAILED(Direct3D_Object->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &D3DCaps))) {
           return false;
       }
       DWORD VertexProcessing = 0;
       if(D3DCaps.VertexProcessingCaps != 0) {
           VertexProcessing |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
       }
       else {
           VertexProcessing |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
       }
       if(fullscreen) {
           Present_Parameters.Windowed = FALSE;
           Present_Parameters.BackBufferWidth = 800;
           Present_Parameters.BackBufferHeight = 600;
       }
       else {
           Present_Parameters.Windowed = TRUE;
       }
       Present_Parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
       Present_Parameters.BackBufferFormat = DisplayMode.Format;
       Present_Parameters.BackBufferCount = 1;
       Present_Parameters.EnableAutoDepthStencil = TRUE;
       Present_Parameters.AutoDepthStencilFormat = D3DFMT_D16;
       if(FAILED(Direct3D_Object->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, VertexProcessing, &Present_Parameters, &D3D_Device))) {
           MessageBox(NULL, "CreateDevice() failed!  Make sure you have DirectX 9.", "Error!", MB_ICONSTOP | MB_OK);
           return false;
       }
       D3D_Device->SetRenderState(D3DRS_LIGHTING, false);
       D3D_Device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
       if(D3D_Device == NULL) {
           MessageBox(NULL, "D3D_Device setup error", "Error!", MB_ICONSTOP | MB_OK);
           return false;
       }
       if(!InitializeObject()) {
           return false;
       }
       if(FAILED(D3DXCreateFont(D3D_Device, hfont, &Font))) {
           return false;
       }
       FontPosition.top = 8;
       FontPosition.left = 8;
       FontPosition.right = 48;
       FontPosition.bottom = 16;
       return true;
    }
    
    
    bool InitializeObject()
    {
        Vertex Triangle_Data[6] =
       {
    	   {-0.5f, -0.5f, 0.0f, D3DCOLOR_XRGB(255,255,0)},
           {0.5f, -0.5f, 0.0f, D3DCOLOR_XRGB(255,255,0)},
    	   {0.0f, 0.3f, 0.0f, D3DCOLOR_XRGB(0,0,255)},
           {-2.5f, -2.5f, 0.0f, D3DCOLOR_XRGB(255,255,0)},
           {3.0f, 3.0f, 2.23f, D3DCOLOR_XRGB(100,100,100)},
    	   {2.5f, -2.5f, 0.0f, D3DCOLOR_XRGB(0,0,255)}
       };
       if(FAILED(D3D_Device->CreateVertexBuffer(3 * sizeof(Vertex), 0, D3DFVF_D3DVertex, D3DPOOL_DEFAULT, &Vertex_Buffer, NULL))) {
           return false;
       }
       Vertex* Vertices;
       if(FAILED(Vertex_Buffer->Lock(0, sizeof(Triangle_Data), (void**)&Vertices, 0))) {
           return false;
       }    
       memcpy(Vertices, Triangle_Data, sizeof(Triangle_Data));
       Vertex_Buffer->Unlock();
       return true;
    }
    
    
    void RenderScence() {
       D3D_Device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0);
       D3D_Device->BeginScene();
          Font->DrawText("Demo", 0, &FontPosition, DT_CENTER, 0xffffffff);
          D3D_Device->SetStreamSource(0, Vertex_Buffer, 0, sizeof(Vertex));
          D3D_Device->SetFVF(D3DFVF_D3DVertex);
          D3D_Device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
       D3D_Device->EndScene();
       D3D_Device->Present(NULL, NULL, NULL, NULL);
    }
    
    
    void ShutdownDirect3D() {
       if(D3D_Device != NULL) {
           D3D_Device->Release();
           D3D_Device = NULL;
       }    
       if(Direct3D_Object != NULL) {
           Direct3D_Object->Release();
           Direct3D_Object = NULL;
       }
       if(Vertex_Buffer != NULL) {
           Vertex_Buffer->Release();
           Vertex_Buffer = NULL;
       }
       if(Font) {
           Font->Release();
           Font = NULL;
       }
    }
    I am using Dev-C++ 4.9.9.2.

    If anyone can help me, it would be much appreciated.
    Last edited by Morgul; 04-15-2005 at 04:34 PM.
    Sic vis pacum para bellum. If you want peace, prepare for war.

  2. #2
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    Okay, I've fixed your code to have the correct parameters for the latest DirectX 9. It goes a little something like this:

    Here is the creation of the Font interface:
    Code:
       // old call
       //if(FAILED(D3DXCreateFont(D3D_Device, hfont, &Font))) {
       //	return false;
       //}
       
       // New call
       if(FAILED(D3DXCreateFont(D3D_Device,			 // Device
    						 -MulDiv(16, 96, 72),	// Height
    						 0,					 // Width
    						 0,					 // Weight
    						 0,					 // Miplevels
    						 FALSE,				 // Italic
    						 ANSI_CHARSET,		 // CharSet
    						 OUT_DEFAULT_PRECIS,	 // OutputPrecision
    						 DEFAULT_QUALITY,		// Quality
    						 FF_MODERN,			 // Pitch and Family
    						 "Courier New",		 // Facename
    						 &Font)))			 // Font 
       {
    	 return false;
       }
    And the rendering code:
    Code:
    	//Font->DrawText("Demo", 0, &FontPosition, DT_CENTER, 0xffffffff);
       
    	// new method
    	Font->DrawText(NULL, "Demo", -1, &textRect, DT_LEFT, D3DCOLOR_XRGB(255,0,255));
    Note your RECT should be something like left = 0, top = 0, right = 100, bottom = 100.

    Your rect was all 0's which will not work. Read the SDK doc for more information. Basically the right side needs to be greater than the left and the bottom must be greater than the top.

    Also you didn't calculate your height for your font correctly. I replaced it with the correct formula. Look it up on MSDN if you want to know more under (CreateFont).


    You can rip out all of your HFONT stuff, no longer needed.

    Good luck
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  3. #3
    Yah. Morgul's Avatar
    Join Date
    Feb 2005
    Posts
    109
    It says:

    C:\Dev-Cpp\C++ Programs\futuregame.cpp In function `bool InitializeDirect3D(HWND__*, bool)':

    148 C:\Dev-Cpp\C++ Programs\futuregame.cpp invalid conversion from `int' to `HFONT__*'

    163 C:\Dev-Cpp\include\d3dx9core.h too many arguments to function `HRESULT D3DXCreateFont(IDirect3DDevice9*, HFONT__*, ID3DXFont**)'

    148 C:\Dev-Cpp\C++ Programs\futuregame.cpp at this point in file

    C:\Dev-Cpp\C++ Programs\futuregame.cpp In function `void RenderScence()':

    198 C:\Dev-Cpp\C++ Programs\futuregame.cpp no matching function for call to `ID3DXFont::DrawTextA(NULL, const char[5], int, RECT*, int, D3DCOLOR)'

    note C:\Dev-Cpp\include\d3dx9core.h:138 candidates are: virtual INT ID3DXFont::DrawTextA(const CHAR*, INT, tagRECT*, DWORD, D3DCOLOR)

    C:\Dev-Cpp\Makefile.win [Build Error] ["C++ Programs/futuregame.o"] Error 1
    it says I'm not using the prototype:
    Code:
    HRESULT WINAPI
        D3DXCreateFont(
            LPDIRECT3DDEVICE9   pDevice,
            HFONT               hFont,
            LPD3DXFONT*         ppFont);
    Last edited by Morgul; 04-17-2005 at 09:47 PM. Reason: More Errors
    Sic vis pacum para bellum. If you want peace, prepare for war.

  4. #4
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    Download the latest SDK (April 2005) and try again. I tried it on my machine and it works fine.
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  5. #5
    Registered User
    Join Date
    Jun 2003
    Posts
    361
    Before installing the new SDK though, what are you programming under? Anything after the October 2004 SDK is not compatible with Visual C++ 6.0.

    Here is my font code:
    Code:
    bool cDX::FontReset(int Height, int Weight, bool Italic, char* FontName)
    {
    	SafeRelease(FontDevice);
    
    	if(FAILED(D3DXCreateFont(
    		D3DDevice,
    		Height,
    		0,		//Width
    		Weight,
    		1,		//MipLevels
    		Italic,
    		DEFAULT_CHARSET,
    		OUT_DEFAULT_PRECIS,
    		ANTIALIASED_QUALITY,
    		DEFAULT_PITCH|FF_DONTCARE,
    		FontName,
    		&FontDevice)))
    		return false;
    
    	return true;
    }
    
    void cDX::FontRenderLine(int Left, int Top, char* Sentence, unsigned int Colour)
    {
    	RECT Rect;
    
    	SetRect(&Rect, Left, Top, 0, 0);
    
    	FontDevice->DrawText(NULL, Sentence, -1, &Rect, DT_LEFT|DT_NOCLIP, Colour);
    }
    The 0, 0 for width and height are okay since it just sizes the box on its own.

    It looks to me as if you're missing some includes, and depending on the way you're linking, some libraries too perhaps. Add these includes to the top of your program:
    Code:
    #include <Windows.h>
    #include <D3D9.h>
    #include <D3DX9.h> //This is the only one you already had
    
    #pragma comment(lib, "D3D9.lib")
    #pragma comment(lib, "D3DX9.lib")
    Pentium 4 - 2.0GHz, 512MB RAM
    NVIDIA GeForce4 MX 440
    WinXP
    Visual Studio .Net 2003
    DX9 October 2004 Update (R.I.P. VC++ 6.0 Compatability)

  6. #6
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    Visual C++ 6.0 is what I used to test my code. No problems.
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  7. #7
    Registered User
    Join Date
    Jun 2003
    Posts
    361
    And you run the latest SDK? That's...odd

    This download does NOT include [...] a D3dx.lib that is compatible with Visual Studio 6.0.
    DirectX 9.0 April 2005 SDK
    This has been the case since the December 2004 Update

    I guess if you've worked your way up from SDKs before Microsoft dropped VC++ 6.0, and if the .lib wasn't overwritten, then it would still be compatible. It's surprising, but awesome that it works My only advice then is to be careful while updating to ensure you don't lose the functionality.
    Last edited by Epo; 04-18-2005 at 12:03 AM.
    Pentium 4 - 2.0GHz, 512MB RAM
    NVIDIA GeForce4 MX 440
    WinXP
    Visual Studio .Net 2003
    DX9 October 2004 Update (R.I.P. VC++ 6.0 Compatability)

  8. #8
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    Well I've been using DirectX since around v6 (and v3 for NT) so yea, we have some history together. At any rate I use .NET 2003 for all my real development, I just use vc6 when I need to test something out quickly.
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  9. #9
    Registered User
    Join Date
    Apr 2005
    Location
    New Brunswick, Canada
    Posts
    8
    Try my example... I did a litle example that is really easy take a look:

    http://www.planet-source-code.com/vb...3511&lngWId=10

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. WS_POPUP, continuation of old problem
    By blurrymadness in forum Windows Programming
    Replies: 1
    Last Post: 04-20-2007, 06:54 PM
  2. Problem with DrawText (DirectX9)
    By Diod in forum C++ Programming
    Replies: 2
    Last Post: 04-11-2006, 07:21 PM
  3. Laptop Problem
    By Boomba in forum Tech Board
    Replies: 1
    Last Post: 03-07-2006, 06:24 PM
  4. problem with my font manager
    By hannibar in forum C Programming
    Replies: 1
    Last Post: 03-07-2006, 08:03 AM
  5. Replies: 5
    Last Post: 11-07-2005, 11:34 PM