www.xbdev.net
xbdev - software development
Friday April 19, 2024
home | contact | Support | DirectX.. Its doing all the hard work for us...


Prtx. Loading and displaying DirectX.8 .x files..
by bkenwright@xbdev.net

Well using the built in DirectX loader API's you can just load in 3D files in the .x format and render them to the screen as easy as pie!... (download full source code).

Again... simple is good!  Didn't want to complicate things for you.  So I created a single function which basically loads in the .x file (square.x in this case) and then renders it to the screen and before leaving the function...deletes everything.

You should really think about saving your loaded in data, then you won't have to load and destroy your file over and over again as I'm doing here in this example.  Just wanted to demonstrate the stages involved easily without to much code in the way!  You should be able to go away and write your own CXLoader class now.

Here is the code that accomplishes it:

/***************************************************************************/

/*                                                                         */

/* File: game.cpp                                                          */

/*                                                                         */

/***************************************************************************/

 

#include <d3dx8.h>

#include <d3d8.h>

 

// Added a camera, as you'll find if you don't you'll be squashed up against your

// shape that you've loaded in.

void set_camera()

{

    // [1] D3DTS_VIEW

    D3DXMATRIX v;

    g_pD3DDevice->SetTransform(D3DTS_VIEW, D3DXMatrixLookAtLH(&v, &D3DXVECTOR3(0,0,-5),

                                                                  &D3DXVECTOR3(0,0,0),

                                                                 &D3DXVECTOR3(0,1,0))); 

    // [2] D3DTS_PROJECTION

    D3DXMATRIX p;

    g_pD3DDevice->SetTransform( D3DTS_PROJECTION, D3DXMatrixPerspectiveFovLH( &p, 

                                    D3DX_PI/4,  1.0f, 0.0f, 100.0f));

};

 

/***************************************************************************/

 /***    ***  *******  ***  ***      *******     *****   ******

   *** ***    ***      ***  ***      ***            ***  ***  **

    *****     *******  ***  ***      *******     ******  ***  **

   *** ***    ***      ***  ***      ***            ***  ***  **

 ***     ***  ***      ***  *******  *******  *  *****   ******/

/***************************************************************************/

// Okay this function loads the .x file, draws it to the screen and then tidies up

// before exiting the function!  Its only done this way so you can see all the stages

// in one nice tidy functino!  You should really init and de-init the parts of this

// into a class or seperate functions etc.  As everytime its called its loading and

// destroying the file!  At 50fps its not the best way to do it :)

void DrawXFile()

{

      LPD3DXBUFFER pMtrlBuffer = NULL;

      DWORD numMaterials;

      LPD3DXMESH mesh;

 

      // File Name ---------+

      //                    |

      //                   \|/

      //                    |

      D3DXLoadMeshFromX( "square.x", D3DXMESH_SYSTEMMEM, g_pD3DDevice,

                                    NULL, &pMtrlBuffer, &numMaterials, &mesh);

 

     

 

      //Create two arrays. One to hold the materials and only to hold the textures

    D3DMATERIAL8* pMeshMaterials = new D3DMATERIAL8[numMaterials];

    LPDIRECT3DTEXTURE8* pMeshTextures  = new LPDIRECT3DTEXTURE8[numMaterials];

      D3DXMATERIAL* matMaterials = (D3DXMATERIAL*)pMtrlBuffer->GetBufferPointer();

      // Loads of allocation etc here!

      for(DWORD i = 0; i < numMaterials; i++)

    {

        //Copy the material

        pMeshMaterials[i] = matMaterials[i].MatD3D;

        //Set the ambient color for the material (D3DX does not do this)

        pMeshMaterials[i].Ambient = pMeshMaterials[i].Diffuse;

        //Create the texture

        if(FAILED(D3DXCreateTextureFromFile(g_pD3DDevice,

                                            matMaterials[i].pTextureFilename,

                                            &pMeshTextures[i])))

            {

            pMeshTextures[i] = NULL;

        };

    }

 

      // Actually drawing something here!

      for(DWORD i = 0; i < numMaterials; i++)

    {

            g_pD3DDevice->SetMaterial(&pMeshMaterials[i]);

            g_pD3DDevice->SetTexture(0, pMeshTextures[i]);

       

            mesh->DrawSubset(i);

    }

 

      // Tidy up!

      for(DWORD i = 0; i < numMaterials; i++)

    {

            if(pMeshTextures[i] != NULL)

                  pMeshTextures[i]->Release();

      }

      delete[] pMeshMaterials;

      delete[] pMeshTextures;

      pMtrlBuffer->Release();

      mesh->Release()  // ** BUG FIX!  DONT FORGET TO RELEASE RESOURCES

 

}

 

// Well if we need to do any drawing or rendering triangles we can do it in here!

void Render()

{

      if(!g_pD3DDevice)return;

     

      // Some stuff to setup or graphics card!

      //Turn off lighting becuase we are specifying that our vertices have colour

    g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);

 

      g_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);

      g_pD3DDevice->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_DIFFUSE);

 

     

 

      // Clear the back buffer to a blue color

      g_pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,255), 1.0f, 0 );

 

      // Just to rotate our shape!  See it rotate.

      static float angle = 0.0f;

      angle += 0.001f;

      //~~~*~~~~ Create a matrix

      D3DXMATRIX mx;

      //~~~*~~~~ Do somthing to our empty matrix.

      D3DXMatrixRotationY(&mx, angle ); // angle in radians...eg. 1 degree = PI/180

      //~~~*~~~~ Use the matrix! No use having a matrix if we don't use it!

      g_pD3DDevice->SetTransform(D3DTS_WORLD, &mx);

 

      set_camera();

 

      //DRAW 3D X FILE DRAWING FILE DRAWING FILE DRAWING 3D FILE HERE.

      DrawXFile();

 

      // After rendering the scene we display it.

      g_pD3DDevice->Present( NULL, NULL, NULL, NULL );

 

 

}

 

void mainloop()

{

      Render();

}

Well its a lot of padding around our nice DrawXFile() function, even then I added in the loading in of materials... you could skip this...Just to show how simple your code can go... you could change your DrawXFile() to the following:

 

void DrawXFile()

{

      LPD3DXBUFFER pMtrlBuffer = NULL;

      DWORD numMaterials;

      LPD3DXMESH mesh;

 

      // File Name ---------+

      //                    |

      //                   \|/

      //                    |

      D3DXLoadMeshFromX( "square.x", D3DXMESH_SYSTEMMEM, g_pD3DDevice,

                                    NULL, &pMtrlBuffer, &numMaterials, &mesh);

 

     

      // Draws our vertices here! (put 0 for all).

    mesh->DrawSubset(0);

 

   pMtrlBuffer->Release();

}

I know what you mean!  There's nothing there!.. well thats how simple it is... this will produce the same results... it just means our textures aren't applied... you could set a texture, and then call this DrawXFile() function and the selected texture would be rendered onto the shape!

 

 

 

 
Advert (Support Website)

 
 Visitor:
Copyright (c) 2002-2024 xbdev.net - All rights reserved.
Designated articles, tutorials and software are the property of their respective owners.