Upcoming Events
Unite 2010
11/10 - 11/12 @ Montréal, Canada

GDC China
12/5 - 12/7 @ Shanghai, China

Asia Game Show 2010
12/24 - 12/27  

GDC 2011
2/28 - 3/4 @ San Francisco, CA

More events...
Quick Stats
114 people currently visiting GDNet.
2406 articles in the reference section.

Help us fight cancer!
Join SETI Team GDNet!
Link to us Events 4 Gamers
Intel sponsors gamedev.net search:

Direct3D 9.0 with SDL


Let's face it, Windows code is a pain! Who wants to piece together hundreds of lines of archaic WinAPI code just to initialize a window. Wouldn't it be wonderful if it were possible to initialize a window, setup Direct3D 9.0, render some primitives to the screen, and construct a basic input handling system without having to touch a single line of obfuscated WinAPI code?

Well, guess what...with Sam Lantinga's SDL library, it can, and with less than 100 lines of code at that! SDL is a powerful cross platform library which allows you to perform windowing, complex graphic operations, music, input handling, and multithreading while compiling with the same code on a myriad of operating systems including Windows, Linux, and Macintosh. In this tutorial however, we will be using SDL for its elegant windowing and input. Despite your initial hopes and inclinations, since we are using Direct3D the code will not be cross platform. Sam is brilliant, but I don't think he is that brilliant! :)  With that brief and informative history, let's get started!

Assuming you have the DirectX 9.0 SDK installed all you need to do is head over to http://www.libsdl.org, the official website for SDL, and download the source. If it makes you more comfortable, skim the very informative DOC project to get a general feel for how SDL works, although this is not really necessary. For this project we will be including the following headers: windows.h, d3d9.h, d3dx9.h, and sdl.h. Additionally we will link to the following libraries: sdl.lib, sdlmain.lib,  d3d9.lib, and d3dx9.lib.

Due to the simplicity and direct nature of this program, the only function defined is the main one, main(), so let's define it and declare all the variables this program will be using. I have commented the purpose of each variable and hope the meanings are somewhat conceptually clear in an abstract sense.

// this is the type used to describe a single vertex
// each vertex has x,y,z coords and a color associated with it
struct D3DVERTEX
{
  float fX,fY,fZ;
   DWORD dwColor;
};

int main( int argc, char* argv[] )
{
   SDL_Event               event;              //used to poll for events and handle input
   LPDirect3D9             Direct3D_object;    //used to create a direct 3d device
   LPDirect3DDEVICE9       Direct3D_device;    //basic rendering object
   D3DPRESENT_PARAMETERS   present_parameters; //stores the important attributes and 
   D3DXMATRIX              projection_matrix;  //   properties your Direct3D_device will have
   LPDirect3DVERTEXBUFFER9 tri_buffer = NULL;  //data buffer which the Direct3D_device can draw from
   VOID* pData;                                //pointer to beginning of vertex buffer
   //actual data to be fed to the vertex buffer
   D3DVERTEX aTriangle[ ] = {{-2.0f,1.0f,10.0f,0xffff0000},
                             {-3.0f,-1.0f,10.0f,0xff00ff00},
                             {-1.0f,-1.0f,10.0f,0xff0000ff}};

Now you may be wondering why a win32 app would use a console style main() function. The answer is that as part of SDL's cross platform code, it takes care of the WinMain() function and layers main() over it. So effectively your entry point is main() just as it in a console program.

With that confusion settled it's time to discuss the basic Direct3D initialization process.

  1. initialize a window
  2. create a Direct3D object
  3. set the important parameters for the Direct3D device you want to make
  4. using the Direct3D object, parameters, and a handle to your window
  5. create the Direct3D device
  6. establish projection matrix, lighting, culling, depth buffer, and vertex format
  7. load in primitive data

When all those steps are taken care of, you want to generate your central game loop which will render graphics each frame as well as handle messages and input.

This will be covered in the 7th and final step.

Initialize a Window

When programming with the Windows API, making windows is a pain in the arse. You have to register a window class, define callback procedures, and set a million parameters. All of this when you only want a simple window to serve as a rendering context. Fortunately for us, SDL can do all of this for us. The following lines of code will initialize the SDL_VIDEO subsystem, and create an 800 by 600 video mode. Of course you are free to adjust the resolution to your needs.

if( SDL_Init( SDL_INIT_VIDEO  ) < 0 || !SDL_GetVideoInfo() )
   return 0;
SDL_SetVideoMode( 800, 600, SDL_GetVideoInfo()->vfmt->BitsPerPixel, SDL_RESIZABLE );

That's it! A window has been created, and to get a handle to it all you need to do is call GetActiveWindow().

Create a Direct3D object

This couldn't be any easier...

Direct3D_object = Direct3DCreate9(D3D_SDK_VERSION);
if( Direct3D_object == NULL )
{
   MessageBox(GetActiveWindow(),"Could not create Direct3D Object","D3D_OBJ ERR",MB_OK);
   return 0;
}




Page 2


Contents
  Page 1
  Page 2

  Source code
  Printable version
  Discuss this article