1 2 3 4 5 6 7
Setting up your Compiler Our Generic Windows Skeleton A Simple Cube Matrices Wazoo of Borg FullScreen Ahead Mr. Crusher On screen. Magnify.

 

 

 

Tutorial #5 D3D8: On screen. Magnify.


Version History
Date Version Description Font Color
Sept. 22nd, 2001 1.0 General Public Release White



Wow, already we're at Tutorial #5! I can hardly believe it myself!
Well at this point, we've got several cool features in our code. So far, we can:
  • Initialize/Run and Shutdown our game
  • Run with either Fullscreen or Windowed mode
  • Texture map objects on our screen

However, we have one curious thing missing: TEXT!..so far there's no way to alert the user with any kind of status message in our application.

Well, we're about to change all that. I am pleased to announce that this tutorial will cover the usage of text in Direct3D8! Yes, yes, thank you, thank you.

For starters, we're going to create a class which will allow us to encapsulate all of this text functionality. Now, I realize that up until now, our code has been written in pretty much straight C. As you can see though, our projects are starting to get a teeny bit cluttered up, and it's beginning to get a little difficult tracing our way through the code. Not to worry though, as the class that we'll need for this tutorial is pretty simple and basic. No real surprises.
We'll first create a new project, using the steps from our Tutorial #0

Okay we are going to be working from our Windows skeleton here so make sure you back up your original and only modify a copy..making it easier to reuse the skeleton in later applications.
Now, we are going to define a small base class entitled GraphicsObject, which we will derive future graphics manipulation classes from. (Note: If you don't understand the Object Orientated concepts of base classes or Inheritance, then check the bottom of this tutorial for some more informational links).

Okay, so first, add a new .h file to the project, and call it GraphicsObject.h, and use the source below:
#ifndef __GRAPHICSOBJECT_H_
#define __GRAPHICSOBJECT_H_
/////////////////////////////
// GraphicsObject
/////////////////////////////
// Our pure virtual base class
// which we MUST inherit from before
// we can use properly..
//
/////////////////////////////
#include <windows.h>
#include <d3d8.h>
#include <d3dx8.h>

class GraphicsObject {

protected:
	LPDIRECT3DDEVICE8 m_lpDevice;

public:
	GraphicsObject(LPDIRECT3DDEVICE8 pDevice){ m_lpDevice = pDevice; };
	virtual ~GraphicsObject();

	virtual void destroyObject() = 0;

};

#endif//__GRAPHICSOBJECT_H_
And that's about it. Not much to talk about here, other than the fact we're trying to design a small utilizeable network of graphics classes, all derived from GraphicsObject.
Now add another new .h file to the project, and call it GraphicsText.h, which we'll define below:
#ifndef __GRAPHICSTEXT_H_
#define __GRAPHICSTEXT_H_
//////////////////////////
// GraphicsText
//////////////////////////
// Our class to encapsulate our text
// functionality within Direct3D8
//
//////////////////////////
#include "GraphicsObject.h"

class GraphicsText : public GraphicsObject {

protected:
	LPD3DXFONT		m_pD3DXFont;
	HFONT			m_hFont;

public:
	GraphicsText(LPDIRECT3DDEVICE8);
	~GraphicsText();

	HRESULT createGraphicsText();
	void renderGraphicsText(TCHAR*, LPRECT, D3DCOLOR);

	//methods inherited from the parent class
	//of GraphicsObject
	void destroyObject();


};
#endif //__GRAPHICSTEXT_H_

So we've derived a new class from the GraphicsObject class, which will allow us to render text to our display. Now add another new .h file to the project, and call it GraphicsText.cpp, which we'll define below:
#include "GraphicsText.h"

GraphicsText::GraphicsText(LPDIRECT3DDEVICE8 pDevice) : GraphicsObject(pDevice){

	//This is our constructor function
	//Notice how we just need to pass of the LPDIRECT3DDEVICE8 object
	//into our constructor for our GraphicsObject
	m_hFont     = NULL;
	m_pD3DXFont = NULL;

}

GraphicsText::~GraphicsText(){}

HRESULT GraphicsText::createGraphicsText(){

	//use the WIN32 font functions to create a font
	//object type of font type "Arial"
	m_hFont = CreateFont(12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, PROOF_QUALITY, 0, "arial");

	//Now use the D3DXFONT object from our
	//DirectX8 Utility Library, which will allow us to create a displayable
	//font from our WIN32 font object from above..
	D3DXCreateFont(this->m_lpDevice,
			m_hFont,
			&m_pD3DXFont);


	//Everything's okay, so return to caller
	return S_OK;
}

void GraphicsText::renderGraphicsText(TCHAR *szMessage,
				LPRECT pDisplayRect,
				D3DCOLOR color){

	//This function is responsible
	//for rendering our text string into a location on
	//the device, identified by the RECT object
	m_pD3DXFont->DrawText(szMessage,
						  -1,
						  pDisplayRect,
						  DT_LEFT,
						  color);

}

void GraphicsText::destroyObject(){

	//This function is used for
	//deleting and cleaning up any used objects that this
	//class might have used.
	if(m_pD3DXFont){
		m_pD3DXFont->Release();
		m_pD3DXFont = NULL;
	}

	if( m_hFont ) {
		DeleteObject( m_hFont );
		m_hFont = NULL;
	}

}

And that's about it for our classes that we need for this tutorial!

Now it's time to put all this into action! No problem here, we can just literally implement a simple Hello World program with our text here.

Now we just have to do the following:
  • properly include our GraphicsText class
  • define a GraphicsText object
  • initialize our object
  • have our object paint a phrase to the device
  • destroy and cleanup our object

As you can see, it's NOT that bad...a few easy chores is all it'll take Hudson.

First, open up our .cpp file with our Game_Init function. At the top of the source code, underneath previous objects and include file definitions, add the following:
#include "GraphicsText.h"

GraphicsText	*GRText = NULL;

Okay, all we've done is let our compiler know just WHICH file contains the definition for our GraphicsText class.

Now, somewhere INSIDE the Game_Init function, add in the following:
//Now it's time to add our text support!
GRText = new GraphicsText(g_pd3dDevice);
if(FAILED(GRText->createGraphicsText())){
	return E_FAIL;
}
Well that was painless and simple right? All we did was allocate new memory for our class on the system heap, initializing it with our LPDIRECT3DDEVICE8 object.

Now it's time to actually USE our class!! If you've been using the source files I've provided with each tutorial, then our Game_Run function will be in the same file as our Game_Init function. Go to our Game_Run function, and within our rendering loop add in the following code:
g_pd3dDevice->BeginScene(); //begin our rendering!

//somewhere after the BeginScene is called and BEFORE
//the EndScene method is called, add the following..

//a RECT structure defining where on the device we wish to render
RECT rTemp4 = { 5, 5, 600, 30 };

//param1:this is the string we want to render
//param2:the location on the screen to render our text
//param3:we want our text to appear in white
GRText->renderText("Hello World!",
	&rTemp4,
	D3DCOLOR_RGBA(255, 255, 255, 255));

//other stuff to process here....

g_pd3dDevice->BeginScene(); //end the scene!

That was handy yet easy right?? Right! Nothing much to it here...we first define a RECT structure which contains our screen co-ordinate area of where we wish to render our string. Next we call our class method for rendering text, renderText, which contains parameters that are pretty important to us...
  • The string we wish to render
  • The location to render it to
  • The color to render our text in

Now we just need to move on to the cleanup area where we destroy our class, and deallocate any used memory. In our source code, move down into the Game_Shutdown section of the code, and add the following inside it.
	if(GRText){
		GRText->destroyObject();
		delete GRText;
		GRText = NULL;
	}

And that's all we have to worry about! We're just checking to see if our GraphicsText object exists. If it does, invoke our destroyObject method, which will clean up our objects that we used within the class.

Now we've got a way to display our text to the user! Please note that this definitely is not the fastest way to go at this point in time, but it's enough to get us started with rendering text onto the screen.

For more help/information on using C++, check out the C++ Faq-Lite site.


Back To Index

 

[top]

 
 
© 2003, Silver.
Wind, two Tears, and a Funeral...