Direct3D 9.0 with Allegro
This article is actually based from an excellent article written by Michael Conway not too long ago. If you haven't read the article then you can click here. This tutorial aims to utilize Direct3D 9 while using Allegro's input and timer functionality instead of writing your own API-based code. Now, let me tell you a little something about Shawn Hargreave's Allegro Game Programming Library. Allegro, just like SDL, is a cross-platform game library which gives you access to graphics, windowing, audio, timer and input handling without the complexity of touching a single operating system API. If you want to learn more about Allegro you can visit Allegro's Community Site by clicking here or its website here. Now let's get started! What you Need
For this tutorial we'll imitate the Mesh example demo from the DirectX 9.0 SDK tutorial. We will be using the Tiger.X file used by Microsoft in their DX9 tutorial example. PseoudocodeBasically, here's what our program will do:
Defines, Includes and LibsSince we're exposing allegro to some windows specific stuff we'll need to define this before anything else. #define ALLEGRO_NO_MAGIC_MAIN Which means we will not be using the allegro int main(void) format but instead we'll use this format as our entrypoint: int WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT) Then we need to include these: #include <allegro.h> //the allegro header #include <winalleg.h> //Windows specific allegro header #include <d3d9.h> //direct x header #include <d3dx9.h> //d3dx utility header We will then need to link with the files alleg.lib, d3d9.lib and d3dx9.lib or define these as a shortcut: #pragma comment(lib, "alleg.lib") #pragma comment(lib, "d3dx9.lib") #pragma comment(lib, "d3d9.lib") AllegroIn this section we'll be discussing all the Allegro related methods in the demo program. Since we'll be using the allegro timer routines, we also need to define these: DWORD g_nCounter = 0; void my_timer_handler() { g_nCounter++; } This will work just like timeGetTime() in the SDK version of the demo; g_nCounter will increment by 1 everytime the handler is called. Here is our function to initialize allegro. We'll need to initialize allegro before we intitialize DirectX. We'll be using the 800x600 video mode. int StartAllegro(void) { allegro_init(); // start allegro // create a window which can be used DirectX. If you don't create this the allegro input // routines won't work if (set_gfx_mode(GFX_DIRECTX_WIN, 800, 600, 0, 0) < 0) { MessageBox(win_get_window(), allegro_error, "Error setting video mode", MB_OK); return 1; } // by the way you may also use the option GFX_GDI instead of GFX_DIRECTX_WIN install_timer(); //we'll be using the allegro routines for our timer so we call this install_keyboard(); //we'll also be using the allegro keyboard routines install_mouse(); //in order to hide the mouse pointer we'll need to call this first show_mouse(NULL); //then hide the mouse pointer //we'll call my_timer_handler() every 1 millisecond which would make g_nCounter //work just like timeGetTime() in the SDK version of the example install_int(my_timer_handler, 1); return 0; } Here is our main program loop: while(!keypressed()) { //keypressed is an Allegro function similar to kbhit(), returns //true until a key is pressed SetupMatrices(); //setup our orientation //Clear the backbuffer and the zbuffer g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0 ); //Begin the scene if(SUCCEEDED(g_pd3dDevice->BeginScene())) { RenderX(); //Render our model // End the scene g_pd3dDevice->EndScene(); } // Present the backbuffer contents to the display g_pd3dDevice->Present( NULL, NULL, NULL, NULL ); } DirectXIn this section we'll be discussing all the DirectX related methods in the demo program. These things are a must for our Example: LPDIRECT3D9 g_pD3D = NULL; // Used to create the D3DDevice LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; // Our rendering device LPD3DXMESH g_pMesh = NULL; // Our mesh object in sysmem D3DMATERIAL9 *g_pMeshMaterials = NULL; // Materials for our mesh LPDIRECT3DTEXTURE9 *g_pMeshTextures = NULL; // Textures for our mesh DWORD g_dwNumMaterials = 0L; // Number of mesh materials Here is the routine to Initialize Direct X, we'll be using the 800x600 video mode. int StartDirectX(void) { D3DPRESENT_PARAMETERS d3dpp; //creating direct3D object g_pD3D = Direct3DCreate9(D3D_SDK_VERSION); if (g_pD3D == NULL) { MessageBox(win_get_window(),"Error Creating Direct3D Object","D3D Object Error",MB_OK); return 1; } //setting parameters that will be needed to created direct3D device ZeroMemory(&d3dpp, sizeof(d3dpp)); d3dpp.Windowed = false; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.EnableAutoDepthStencil = true; d3dpp.AutoDepthStencilFormat = D3DFMT_D16; d3dpp.hDeviceWindow = win_get_window(); d3dpp.BackBufferWidth = 800; d3dpp.BackBufferHeight = 600; d3dpp.BackBufferFormat = D3DFMT_R5G6B5; d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; //creating direct3D device if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, win_get_window(), D3DCREATE_SOFTWARE_VERTEXPROCESSING,&d3dpp, &g_pd3dDevice))) { MessageBox(win_get_window(),"Error Creating Direct3D Device","D3D Device Error",MB_OK); return 1; } // Turn on the zbuffer g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE ); // Turn on ambient lighting g_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0xffffffff ); return 0; } We used the allegro function win_get_window() in this routine to let DirectX use the window created by Allegro. This simple routine will be in-charge of loading the .X mesh for us. int LoadX(char *szFile) { ... } This will setup the orientation of our model per frame. There's nothing special about this routine except that we used g_nCounter instead of timeGetTime(). void SetupMatrices(void) { ... D3DXMatrixRotationY( &matWorld, g_nCounter/1000.0f ); ... } This routine would free all the resources we used up and stop our program void EndDirectX(void) { ... } You can download the complete demo project here. I hope this tutorial has helped anyone. To give feedback, complaints or suggestions just shoot me an e-mail at the_temporal@yahoo.com AcknowledgmentsI would like to thank the people of http://www.allegro.cc for all their assistance when I was still beginning to use Allegro. Now I would like to give something back in return. I would also like to thank the people of Anino Entertainment for letting me experience how it feels like to work for a game development company and for helping me learn DirectX. BiographyHomer Cuevas is a hobbyist programmer from the Philippines who's interests lie in Graphics, AI and game development in general. He has experience in C/C++, Visual Basic, Java, Allegro, ASP, OpenGL and DirectX. Discuss this article in the forums
See Also: © 1999-2011 Gamedev.net. All rights reserved. Terms of Use Privacy Policy
|