• 01/25/06 04:02 PM
    Sign in to follow this  

    Direct3D 9.0 with Allegro

    General and Gameplay Programming

    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

    • The DirectX 9.0 SDK which you can get from http://www.microsoft.com
    • The Allegro Game Programming Library which you can get from http://www.talula.demon.co.uk/allegro/. (We'll be using the Stable 4.03 build but later versions may work). If you want to get a precompiled version 4.03 you may get it at http://www.allegro.cc, just click on "Files" section on the upper left hand corner of the site.
    • Microsoft Visual C++ (We'll be using version 6.0 here but other versions may work)

    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.

    Pseoudocode

    Basically, here's what our program will do:

    1. Initialize Allegro
    2. Initialize DirectX
    3. Load Mesh Data (the X file)
    4. Setup Orientation
    5. Render Mesh Data
    6. Upon press of a key, the rendering stops
    7. Then we free all resources
    8. Program Exits

    Defines, Includes and Libs

    Since 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            //the allegro header
    #include           //Windows specific allegro header
    #include               //direct x header
    #include              //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")
    

    Allegro

    In 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 );
    }
    

    DirectX

    In 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

    Acknowledgments

    I 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.

    Biography

    Homer 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.



      Report Article
    Sign in to follow this  


    User Feedback

    Create an account or sign in to leave a review

    You need to be a member in order to leave a review

    Create an account

    Sign up for a new account in our community. It's easy!

    Register a new account

    Sign in

    Already have an account? Sign in here.

    Sign In Now

    There are no reviews to display.