1. #include <windows.h>
  2. #include <d3d9.h>
  3. #include <D3DX9Mesh.h>
  4.  
  5. #define THROW_ERROR_AND_EXIT(x) { \
  6.     MessageBox(0,x,0,0); \
  7.     return -1; \
  8.     }
  9.  
  10. LRESULT CALLBACK WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
  11. {
  12.     // Handle close event
  13.     switch( msg )
  14.     {
  15.     case WM_DESTROY:
  16.         PostQuitMessage( 0 );
  17.         return 0;
  18.     }
  19.     return DefWindowProc( hWnd, msg, wParam, lParam );
  20. }
  21.  
  22. int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
  23. {
  24.     // Registering class
  25.     WNDCLASSEX wcex;
  26.  
  27.     wcex.cbSize = sizeof(WNDCLASSEX);
  28.     wcex.style= CS_HREDRAW | CS_VREDRAW;
  29.     wcex.lpfnWndProc= (WNDPROC)WndProc;
  30.     wcex.cbClsExtra= 0;
  31.     wcex.cbWndExtra= 0;
  32.     wcex.hInstance= hInstance;
  33.     wcex.hIcon= 0;
  34.     wcex.hCursor= LoadCursor(NULL, IDC_ARROW);
  35.     wcex.hbrBackground= (HBRUSH)(COLOR_WINDOW+1);
  36.     wcex.lpszMenuName= 0;
  37.     wcex.lpszClassName= "MyMeshViewer";
  38.     wcex.hIconSm= 0;
  39.  
  40.     RegisterClassEx(&wcex);
  41.  
  42.     // Creating Window
  43.     HWND hWnd = CreateWindow("MyMeshViewer", "MyMeshViewer", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
  44.  
  45.     // Creating Direct3D object
  46.     LPDIRECT3D9 d3dObject=NULL;
  47.     LPDIRECT3DDEVICE9 d3dDevice=NULL;
  48.  
  49.     d3dObject=Direct3DCreate9(D3D_SDK_VERSION);
  50.  
  51.     // Creating Direct3D device
  52.     if(NULL == d3dObject)
  53.         THROW_ERROR_AND_EXIT("NULL == d3dObject");
  54.     D3DPRESENT_PARAMETERS presParams;
  55.     ZeroMemory(&presParams,sizeof(presParams));
  56.     presParams.Windowed=TRUE;
  57.     presParams.SwapEffect=D3DSWAPEFFECT_DISCARD;
  58.     presParams.BackBufferFormat=D3DFMT_UNKNOWN;
  59.     presParams.PresentationInterval=D3DPRESENT_INTERVAL_ONE;
  60.     HRESULT hr=d3dObject->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &presParams, &d3dDevice);
  61.     if(FAILED(hr))
  62.         THROW_ERROR_AND_EXIT("d3dObject->CreateDevice");
  63.  
  64.     // Loading the mesh
  65.     LPD3DXBUFFER materialBuffer = NULL;
  66.     DWORD numMaterials = 0;
  67.     LPD3DXMESH mesh = NULL;
  68.     hr=D3DXLoadMeshFromX("d:\\temp\\tiger.x", D3DXMESH_SYSTEMMEM,
  69.         d3dDevice, NULL,
  70.         &materialBuffer,NULL, &numMaterials,
  71.         &mesh );
  72.     if(FAILED(hr))
  73.         THROW_ERROR_AND_EXIT("hr=D3DXLoadMeshFromX");
  74.  
  75.     // Loading the material buffer
  76.     D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)materialBuffer->GetBufferPointer();
  77.     // Holding material and texture pointers
  78.     D3DMATERIAL9 *meshMaterials = new D3DMATERIAL9[numMaterials];
  79.     LPDIRECT3DTEXTURE9 *meshTextures  = new LPDIRECT3DTEXTURE9[numMaterials];  
  80.     // Filling material and texture arrays
  81.     for (DWORD i=0; i<numMaterials; i++)
  82.     {
  83.         // Copy the material
  84.         meshMaterials[i] = d3dxMaterials[i].MatD3D;
  85.  
  86.         // Set the ambient color for the material (D3DX does not do this)
  87.         meshMaterials[i].Ambient = meshMaterials[i].Diffuse;
  88.  
  89.         // Create the texture if it exists - it may not
  90.         meshTextures[i] = NULL;
  91.         if (d3dxMaterials[i].pTextureFilename)
  92.             D3DXCreateTextureFromFile(d3dDevice, d3dxMaterials[i].pTextureFilename, &meshTextures[i]);
  93.     }
  94.  
  95.     materialBuffer->Release();
  96.  
  97.     // Show Window
  98.     ShowWindow(hWnd, nCmdShow);
  99.     UpdateWindow(hWnd);
  100.  
  101.     // Handle messages
  102.     MSG msg;
  103.     ZeroMemory( &msg, sizeof(msg) );
  104.     while( msg.message!=WM_QUIT )
  105.     {
  106.         if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
  107.         {
  108.             TranslateMessage( &msg );
  109.             DispatchMessage( &msg );
  110.         }
  111.         else
  112.         {
  113.             // Rendering
  114.             d3dDevice->Clear(0,NULL,D3DCLEAR_TARGET, D3DCOLOR_XRGB(255,255,255),1.0f,0);
  115.             // Turn on wireframe mode
  116.             d3dDevice->SetRenderState(D3DRS_FILLMODE,D3DFILL_WIREFRAME);
  117.             d3dDevice->BeginScene();
  118.  
  119.             for (DWORD i=0; i<numMaterials; i++)
  120.             {
  121.                 // Set the material and texture for this subset
  122.                 d3dDevice->SetMaterial(&meshMaterials[i]);
  123.                 d3dDevice->SetTexture(0,meshTextures[i]);
  124.                 // Draw the mesh subset
  125.                 mesh->DrawSubset( i );
  126.             }
  127.  
  128.             d3dDevice->EndScene();
  129.             d3dDevice->Present(NULL, NULL, NULL, NULL);
  130.             Sleep(0);
  131.         }
  132.     }
  133.     return (int)msg.wParam;
  134. }