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.
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 WindowWhen 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 objectThis 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; } |
|