Wazoo Enterprises

Having fun in game development!

Archive for January, 2008


Fixed Function Geometry Pipeline

How a vertex becomes a pixel

In the graphics libraries of OpenGL and Direct3D (*pre-DirectX10), the
common method for learning how to properly compute the position, and
other properties, of a vertex has been through the implementation of
the Fixed Function Geometry Pipeline.

This is the main pipeline in which the graphics engine calculates the
proper rendering to a vertex in the system.
This pipeline can be dissected into different sub-phases:

  1. Model Transformation

    This is the initial entry point of
    a vertex into the pipeline. At this stage, no transformations have yet
    been applied to the vertex, and the vertex is currently using a local
    coordinate system. In other words, you have drawn a 3D model and
    have everything done to a local coordinate system relative to that model.

  2. World Transformation

    During the first phase through the
    pipeline, the geometry engine must translate the vertex from the local
    coordinate system it’s using to that of the coordinate system used by the
    current “World”. The coordinates of the vertex after the tranformation are
    referred to be using world coordinates.

  3. View Transformation

    The next stage through the pipeline, is
    where the geometry engine calculates the vertex information with respect
    to the camera for the scene. In other words, when your game chooses a
    “point-of-view” to render the world, the world coordinates of all the
    vertices are re-aligned to properly reflect the camera.

  4. Projection Transformation

    takes place after the View
    Transformation stage, in which the geometry pipeline calculates the
    proper depth of the vertex. This information is used to scale the vertex
    according to distance from the camera, such that closer vertices appear
    larger than vertices further away.

  5. Viewport Clipping
  6. is the final stage of the geometry pipeline
    in which a final “acid” test is given to the vertex; if it’s position
    lies outside of the viewport (created by the Camera), then the vertex
    is tossed from the scene and removed.

*Post DirectX9.0c Information

Until DirectX9.0c, both Direct3D and OpenGL used the Fixed Function
Geometry Pipeline for vertex calculations. As the development of
programmable shaders (introduced in DirectX8.1) grew, there became
a seperation from the pipeline in which programmable vertices were able
to bypass some of the fixed function tranformation stages and inject
themselves into the View Transformation stage directly.

However, as of DirectX9.0c, I believe that “under the covers” of Direct3D,
the entire Fixed Function Geometry pipeline has been replaced by one aimed at
taking advantage of programmable vertices, however the engine will still
always accept the “old” way of positioning your objects.

Feedback? Comments?

Either comment to this posting, or use our contact form to get in
touch with us.

Cartesian Coordinate System

Everyone uses them!

In this tutorial, we’ll focus on the concept of a Coordinate System which is used as our very foundation for positioning every object that we need to draw. Whether we’re rendering a menu system, our player avatar, explosion sprites or
even our high score list, we’re taking advantage of the coordinate system to ensure everything’s in the right place.

While there’s some slight variance between the two implementations, both OpenGL and Direct3D use the same coordinate system, known as the Cartesian Coordinate System. It may ring some bells, because it’s the same coordinate system that you were taught in grade…5 or 6(?).

With the origin of our world always at (0,0,0), the positive Y-axis points straight up and the positive X-axis points to the right. The positive Z-axis either points away from you (into the screen) or towards you (out of the screen). This Z-axis difference depends upon if you are using the Left-Handed or Right-Handed system.

Left-Handed vs. Right-Handed

The only difference between the coordinate system implementation of OpenGL vs. the coordinate system implementation of Direct3D is the direction of the positive Z-axis. The Left-Handed coordinate system is used by Direct3D so as you travel further into your scene, you are increasing the Z-coordinate. Contrast that with the Right-Handed coordinate system employed by OpenGL in which as you travel further into your scene, you are decreasing the Z-coordinate.

Feedback? Comments?

Either comment to this posting, or use our contact form to get in
touch with us.

The Singleton

The Singleton

In most cases for a software codebase there is the need to usually ensure that there
is one single instantiation of an object. In other words, usually a fairly important object
which would wreck havoc on the application if there were more than one.

In the days of C, this was accomplished with the use of a global variable. While
not pretty, it does do the job it is meant for. One problem with using a global variable
this way, is that the object is always consuming resources. For example, what
if we have a class design in which the Singleton object need only be created when
certain circumstances / conditions are met?

In the C++ language, we can create a small Singleton object that we can
then use for future objects in our system. In other words we can create a base
object to generalize any common handling of Singletons.

Da Code!

/**
* Template class for creating single-instance global classes.
* The code in this file is taken from article 1.3 in the the book:
* Game Programming Gems from Charles River Media with the
* copyright notice going to Scott Bilas.
*/
template  class ISingleton
{
protected:

	/** The static member object */
	static T* ms_Singleton;

public:
/**
* Constructor
*/
ISingleton( void )
{
    assert( !ms_Singleton );
    ms_Singleton = static_cast< T* >( this );
}

/**
* Destructor
*/
~ISingleton( void )
    {  assert( ms_Singleton );  ms_Singleton = 0;  }

	/**
	* This method just returns the internal member by
	* reference
	* @return T& - reference to internal abstract Type
	*/
	static T& getSingleton( void )
	{	assert( ms_Singleton );  return ( *ms_Singleton ); }

	/**
	* This method just returns the internal member by
	* a pointer
	* @return T* - pointer to the internal abstract Type
	*/
	static T* getSingletonPtr( void )
	{ return ms_Singleton; }
};

That’s pretty much all we need defined for our lowest-level base class.
To see this object in use, be sure to check out the other tutorials
on this site. Most of them employ this Singleton object to
work with objects such as our FileLogger

Feedback? Comments?

Either comment to this posting, or use our contact form to get in touch with us.

Downloads

ISingleton.h

Displaying Text

Basic Font

With the introduction to the DirectX sample framework covered in the
previous tutorial, we can build on that to focus on another crucial task…printing
text. We can use text to display status messages for debugging our game, or
for printing out scores to the player. While there are a few methods of getting
text up and running within DirectX, we’re going to cover a powerful font object that comes
bundled with the Direct sample framework, CD3DFont.

Continue Reading →

Using Boost for managing a list of pointers

One of the popular uses of the Standard Template Library (STL) in the C++ language is to manage a dynamic list of pointers. For example, if you have a rendering system for your game which works with a common base object that every drawable object is derived from.

If you were using STL, then typically you would create something like the following:

#include <iostream>
#include <list>

using namespace std;

class IRenderObj
{
public:
float x;
float y;
float z;
};

main()
{
list<IRenderObj*> drawList;
list<IRenderObj*>::iterator drawListIter;

IRenderObj *a= new IRenderObj;
IRenderObj *b= new IRenderObj;
IRenderObj *c= new IRenderObj;

a->x = 0.0f; a->y = 0.0f; a->z = 0.0f;
b->x = 0.0f; b->y = 1.0f; b->z = 0.0f;
c->x = 1.0f; c->y = 0.0f; c->z = -10.0f;

drawList.push_back(a);
drawList.push_back(b);
drawList.push_back(c);

for (drawListIter = drawList.begin();
drawListIter != drawList.end();
drawListIter++)
{
//draw, translate each vector
glTranslatef( (*drawListIter)->x, (*drawListIter)->y, (*drawListIter)->z );

}

// Now Free pointers
for (drawListIter = drawList.begin();
drawListIter != drawList.end();
drawListIter++)
{
delete *drawListIter;
}

drawList.clear(); // List is deleted.

}

Continue Reading →