Wazoo Enterprises

Having fun in game development!

Archive for the ‘directx90c’


DXUT - EmptyProject

Empty Project

This tutorial is an introduction to getting a bare-bones DirectX9.0c
application configured and running. Note: While we could get started
on our own class framework to take care of the lower-level Windows initialization
for us, there really isn’t much point if the goal is to just learn
the beginning tasks of using DirectX.

EmptyProject == Hello World

For our basic “Hello World” type of tutorial using the DXUT framework, we’re going to create an
empty shell of an application which will:

  1. Launch the app and handle our registration with the Windows OS
  2. Query our video hardware to create a default Direct3D device
  3. Display a solid blue background to the monitor

DXUT

The DXUT (or my own nickname, the DirectX Utility Toolkit) set of classes / methods is a result
of feedback from the DirectX common framework that was included with the
DirectXSDK in 7.0 and 8.0/8.1. As with the previous common frameworks,
the DXUT is meant to be a quick way to spin up access to DirectX. However, instead
of using a class framework approach, where the developer must inherit from
a class such as CD3DApplication, the DXUT system revolves around using
a callback mechanism. The strength of this approach is that you can just about
drop DXUT right into an existing engine without too much work, whereas the
CD3DApplication approach might be incompatible with your current game’s engine.

The two other significant points about DXUT is that:

  • Unicode The project must be compiled to support the Unicode character set, opening up
    your project to multi-language environments.
  • Uses the D3DX helper library as a DLL For this reason, it’s important the
    properly version of DirectX9.0c is also installed on the client’s machine that you
    wish to deploy to.

Winmain - Launching the application

Every Windows application from games to business applications need to register
themselves properly with the Windows operating system, in order to fit properly
into the Windows event model of operations. The first step of this process
is to always define a WinMain entry point into your application.

INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
{
    // Enable run-time memory check for debug builds.
#if defined(DEBUG) | defined(_DEBUG)
    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif

    // Set the callback functions
    DXUTSetCallbackDeviceCreated( OnCreateDevice );
    DXUTSetCallbackDeviceReset( OnResetDevice );
    DXUTSetCallbackDeviceLost( OnLostDevice );
    DXUTSetCallbackDeviceDestroyed( OnDestroyDevice );
    DXUTSetCallbackMsgProc( MsgProc );
    DXUTSetCallbackFrameRender( OnFrameRender );
    DXUTSetCallbackFrameMove( OnFrameMove );

    // TODO: Perform any application-level initialization here

    // Initialize DXUT and create the desired Win32 window and Direct3D device for the application
    DXUTInit( true, true, true ); // Parse the command line, handle the default hotkeys, and show msgboxes
    DXUTSetCursorSettings( true, true ); // Show the cursor and clip it when in full screen
    DXUTCreateWindow( L"EmptyProject" ); // Make sure the string is converted to UNICODE using the L
    DXUTCreateDevice( D3DADAPTER_DEFAULT, true, 800, 600, IsDeviceAcceptable, ModifyDeviceSettings );

    // Start the render loop
    DXUTMainLoop();

    // TODO: Perform any application-level cleanup here

    return DXUTGetExitCode();
}

This is the “core” of a DXUT app; configuring the callback mechanism. Through the use
of a concept in C++ known as function pointers, you can just about drop
any function declaration into this method (provided they follow the base template
of course).

For example, take a quick look at our OnCreateDevice function declaration in the code…

//--------------------------------------------------------------------------------------
// Create any D3DPOOL_MANAGED resources here
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
{
    return S_OK;
}

So whenever the DXUT processing core hits the DXUTCallbackDeviceCreated function, it
is now pointing to the one declared in your application. Easy peasy.

Most of the DXUT framework appears similar to the virtual function methods provided
in the DirectX common frameworks of DirectX7 and DirectX8.0/8.1, so about the
only other interesting thing in this “EmptyProject” is the rendering callback,
OnFrameRender.

void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
    HRESULT hr;

    // Clear the render target and the zbuffer
    V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 45, 50, 170), 1.0f, 0) );

    // Render the scene
    if( SUCCEEDED( pd3dDevice->BeginScene() ) )
    {
        V( pd3dDevice->EndScene() );
    }
}

There isn’t really much more than that. The sample code chooses a default display mode for our use, but
you can leave this out if you want to force the user to select their video settings.

Further “tweaks”

In the current version of the sample code, if we’re specifying that we want a windowed device, then we
set the display parameters to match the width and height of the device. If we want a fullscreen device,
then we simply use the default parameters that we chose in the DXUTCreateDevice core.

DXUTCreateDevice( D3DADAPTER_DEFAULT, false, 800, 600, IsDeviceAcceptable, ModifyDeviceSettings );

That’s it for this lesson. We covered some of the basics behind the DXUT objects
which is a different approach from the class framework system used in the DirectX7
and DirectX8.0/8.1 SDKs, and we were able to get our first “Hello World” application up and running!

Download

Download the project files here: dxut-emptyproject

Feedback? Comments?

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

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.

Getting Started with DirectX9.0c

In many ways, the DirectX9.0c SDK is a radical migration of the DirectX game library than any of its previous versions. While the DirectX8.1 release marked some new refinements available to the developer (a marked improvement of the D3DX helper library for one thing, along with a re-tooled set of DirectPlay interfaces), DirectX9.0c takes things quite a bit further.

Continue Reading →