obj模型显示示例

    技术2026-03-27  6

     

     

               #include "Obj.h"           #include <Windows.h>#include <mmsystem.h>#include <d3dx9.h>#pragma warning( disable : 4996 ) // disable deprecated warning #include <strsafe.h>#pragma warning( default : 4996 )

    #include   <shlobj.h>

    struct VERTEX{D3DXVECTOR3 pos;D3DXVECTOR3 normal;D3DXVECTOR2 uv;

    static const DWORD   FVF=D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1;};

    //-----------------------------------------------------------------------------// Global variables//-----------------------------------------------------------------------------LPDIRECT3D9             g_pD3D           = NULL; // Used to create the D3DDeviceLPDIRECT3DDEVICE9       g_pd3dDevice     = NULL; // Our rendering device

    LPD3DXMESH              g_pMesh          = NULL; // Our mesh object in sysmemD3DMATERIAL9*           g_pMeshMaterials = NULL; // Materials for our meshLPDIRECT3DTEXTURE9*     g_pMeshTextures = NULL; // Textures for our meshDWORD                   g_dwNumMaterials = 0L;   // Number of mesh materialsLPDIRECT3DVERTEXBUFFER9 *g_pSubBuffer    =NULL;           //group for each subLPDIRECT3DINDEXBUFFER9 *g_pIndexBuffer =NULL;int*                     g_pNumVerts     =NULL;int*                     g_pNumFaces     =NULL;

    //-----------------------------------------------------------------------------// Name: InitD3D()// Desc: Initializes Direct3D//-----------------------------------------------------------------------------HRESULT InitD3D( HWND hWnd ){// Create the D3D object.if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )   return E_FAIL;

    // Set up the structure used to create the D3DDevice. Since we are now// using more complex geometry, we will create a device with a zbuffer.D3DPRESENT_PARAMETERS d3dpp; ZeroMemory( &d3dpp, sizeof(d3dpp) );d3dpp.Windowed = TRUE;d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;d3dpp.EnableAutoDepthStencil = TRUE;d3dpp.AutoDepthStencilFormat = D3DFMT_D16;

    // Create the D3DDeviceif( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,   D3DCREATE_SOFTWARE_VERTEXPROCESSING,   &d3dpp, &g_pd3dDevice ) ) ){   return E_FAIL;}

    g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);// Turn on the zbufferg_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );

    // Turn on ambient lighting g_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0xffffffff );

    return S_OK;}

    //typedef   struct   _browseinfo   {     // HWND   hwndOwner; // LPCITEMIDLIST   pidlRoot;     // LPSTR   pszDisplayName;     // LPCSTR   lpszTitle;     // UINT   ulFlags;     // BFFCALLBACK   lpfn;     // LPARAM   lParam;     // int   iImage;     //}   BROWSEINFO,   *PBROWSEINFO,   *LPBROWSEINFO;

    //void find(char * lpPath)//{// char szFind[MAX_PATH];// WIN32_FIND_DATA FindFileData;//// strcpy(szFind,lpPath);// strcat(szFind,"//*.*");//// HANDLE hFind=::FindFirstFile(szFind,&FindFileData);// if(INVALID_HANDLE_VALUE == hFind)    return;//// while(TRUE)// {//   if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)//   {//    if(FindFileData.cFileName[0]!='.')//    {//     strcpy(szFind,lpPath);//     strcat(szFind,"//");//     strcat(szFind,FindFileData.cFileName);//     find(szFind);//    }//   }//   else//   {//    cout << FindFileData.cFileName;//   }//   if(!FindNextFile(hFind,&FindFileData))    break;// }// FindClose(hFind);//}

    void getNamePath(char* path){ITEMIDLIST   *ppidl;   SHGetSpecialFolderLocation(NULL,   CSIDL_DESKTOP   ,&ppidl);   if   (   ppidl   ==   NULL)   {      AfxMessageBox("启动路径浏览失败");     }  

    BROWSEINFO   *bi=new   BROWSEINFO;   bi->hwndOwner=NULL;   bi->pidlRoot=ppidl;       bi->pszDisplayName=NULL;             bi->lpszTitle = "输入文件路径及名称(OBJ)";             bi->lpfn=NULL;   bi->ulFlags=/*BIF_BROWSEINCLUDEFILES|*/BIF_EDITBOX |BIF_RETURNONLYFSDIRS;   ppidl   =   SHBrowseForFolder(bi);     SHGetPathFromIDList(ppidl,path);   delete   bi;

    }

    //char*   GetNamePath()//{// BROWSEINFO   bi;   // char   buffer[MAX_PATH];   // ZeroMemory(buffer,   MAX_PATH);   // bi.hwndOwner = NULL;   // bi.pidlRoot   =   NULL;   // bi.pszDisplayName   =   buffer;   //// bi.lpszTitle   =   "选择一个文件夹";   // bi.ulFlags   =   BIF_EDITBOX;   // bi.lpfn   =   NULL;   // bi.lParam   =   0;   // bi.iImage   =   0;   //// LPITEMIDLIST   pList   =   NULL;   // if   ((pList   =   SHBrowseForFolder(&bi))   !=   NULL)   // {   //   char   path[MAX_PATH];   //   ZeroMemory(path,   MAX_PATH);   //   SHGetPathFromIDList(pList,   path);   //   //path就是選中的目錄   // }//};

    ///

    //-----------------------------------------------------------------------------// Name: InitGeometry()// Desc: Load the mesh and build the material and texture arrays//-----------------------------------------------------------------------------HRESULT InitGeometry(){t3DModel temp={0};

    // Load the mesh from the specified fileCLoadObj loader;

    char str[128] = "";getNamePath(str);//GetPrivateProfileString("PATH", "name", "hua.3ds", str, 64, "cofig.dat");

    //   loader.Import3DS(&temp, str);

    loader.ImportObj(&temp, str);

    char strTex[128];strncpy_s(strTex, str, strlen(str)-4);sprintf(strTex, "%s_tex.png", strTex);

    g_dwNumMaterials=temp.numOfObjects;// We need to extract the material properties and texture names from the // pD3DXMtrlBufferg_pMeshMaterials = new D3DMATERIAL9[g_dwNumMaterials];g_pMeshTextures = new LPDIRECT3DTEXTURE9[g_dwNumMaterials];g_pSubBuffer     = new LPDIRECT3DVERTEXBUFFER9[g_dwNumMaterials];g_pIndexBuffer   = new LPDIRECT3DINDEXBUFFER9[g_dwNumMaterials];g_pNumVerts      = new int[g_dwNumMaterials]; g_pNumFaces      = new int[g_dwNumMaterials];DWORD i;for( i=0; i<g_dwNumMaterials; i++ ){   int id=0;   id=temp.pObject[i].materialID;   // Copy the material   D3DCOLORVALUE set={0.7,0.5,0.8,1};   g_pMeshMaterials[i].Ambient=set;   g_pMeshMaterials[i].Diffuse=set;   g_pMeshMaterials[i].Specular=set;   g_pMeshMaterials[i].Emissive.b=g_pMeshMaterials[i].Emissive.r=g_pMeshMaterials[i].Emissive.g=0;   g_pMeshMaterials[i].Emissive.a=1;   g_pMeshMaterials[i].Power=1;

       //if(id>-1)   //{   // g_pMeshMaterials[i].Diffuse.r=temp.pMaterials[id].color[0]/255.0f;   // g_pMeshMaterials[i].Diffuse.g=temp.pMaterials[id].color[1]/255.0f;   // g_pMeshMaterials[i].Diffuse.b=temp.pMaterials[id].color[2]/255.0f;   // g_pMeshMaterials[i].Ambient=g_pMeshMaterials[i].Diffuse;   //}

       if( !temp.pObject[i].bHasTexture )   {    // Create the texture    // If texture is not in current folder, try parent folder

        if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice,      strTex,      &g_pMeshTextures[i] ) ) )    {     g_pMeshTextures[i] = NULL;    }   }

       else if(temp.pObject[i].bHasTexture && strlen(temp.pMaterials[id].strFile)>0)   {    // Create the texture    // If texture is not in current folder, try parent folder    if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice,      temp.pMaterials[id].strFile,      &g_pMeshTextures[i] ) ) )    {     MessageBox(NULL, "Could not find texture map", "Meshes.exe", MB_OK);    }   }

       g_pNumVerts[i]=temp.pObject[i].numOfVerts;   g_pNumFaces[i]=temp.pObject[i].numOfFaces;   //fill sub buffer   if( FAILED(g_pd3dDevice->CreateVertexBuffer(sizeof(VERTEX)*g_pNumVerts[i],D3DUSAGE_WRITEONLY,VERTEX::FVF,    D3DPOOL_DEFAULT,&g_pSubBuffer[i],NULL)))    return E_FAIL;   //为了方便暂时使用 inde32 格式 可以自己来优化   if( FAILED(g_pd3dDevice->CreateIndexBuffer(sizeof(DWORD)*g_pNumFaces[i]*3,    D3DUSAGE_WRITEONLY,D3DFMT_INDEX32,D3DPOOL_DEFAULT,&g_pIndexBuffer[i],NULL)))    return E_FAIL;

       VERTEX* pverts;   int j;   g_pSubBuffer[i]->Lock(0,0,(void**)&pverts,0);   for(j=0;j<temp.pObject[i].numOfVerts;j++)   {    pverts[j].pos.x=temp.pObject[i].pVerts[j].x;    pverts[j].pos.y=temp.pObject[i].pVerts[j].y;    pverts[j].pos.z=-temp.pObject[i].pVerts[j].z;

        if(temp.pObject[i].pNormals!=NULL)    {     pverts[j].normal.x=temp.pObject[i].pNormals[j].x;     pverts[j].normal.y=temp.pObject[i].pNormals[j].y;     pverts[j].normal.z=-temp.pObject[i].pNormals[j].z;    }    else    {     pverts[j].normal.x=0;     pverts[j].normal.y=1;     pverts[j].normal.z=0;    }    if(temp.pObject[i].pTexVerts!=NULL)    {     pverts[j].uv.x=temp.pObject[i].pTexVerts[j].x;     pverts[j].uv.y=temp.pObject[i].pTexVerts[j].y;    }    else    {     pverts[j].uv.x=0;     pverts[j].uv.y=0;    }   }   g_pSubBuffer[i]->Unlock();

       DWORD *index;   g_pIndexBuffer[i]->Lock(0,0,(void**)&index,0);   for(j=0;j<temp.pObject[i].numOfFaces;j++)   {    index[j*3]=temp.pObject[i].pFaces[j].vertIndex[0];    index[j*3+1]=temp.pObject[i].pFaces[j].vertIndex[1];    index[j*3+2]=temp.pObject[i].pFaces[j].vertIndex[2];   }   g_pIndexBuffer[i]->Unlock();}

    return S_OK;}

     

    //-----------------------------------------------------------------------------// Name: Cleanup()// Desc: Releases all previously initialized objects//-----------------------------------------------------------------------------VOID Cleanup(){if( g_pMeshMaterials != NULL )    delete[] g_pMeshMaterials;DWORD i;if( g_pMeshTextures ){   for(i = 0; i < g_dwNumMaterials; i++ )   {    if( g_pMeshTextures[i] )     g_pMeshTextures[i]->Release();   }   delete[] g_pMeshTextures;}

    if(g_pSubBuffer){   for( i= 0; i < g_dwNumMaterials; i++ )   {    if(g_pSubBuffer[i])     g_pSubBuffer[i]->Release();   }   delete[] g_pSubBuffer; }

    if(g_pIndexBuffer){   for( i= 0; i < g_dwNumMaterials; i++ )   {    if(g_pIndexBuffer[i])     g_pIndexBuffer[i]->Release();   }   delete[] g_pIndexBuffer; }

    if(g_pNumVerts)   delete []g_pNumVerts;if(g_pNumFaces)   delete []g_pNumFaces;

    if( g_pMesh != NULL )   g_pMesh->Release();

    if( g_pd3dDevice != NULL )   g_pd3dDevice->Release();

    if( g_pD3D != NULL )   g_pD3D->Release();}

     

    //-----------------------------------------------------------------------------// Name: SetupMatrices()// Desc: Sets up the world, view, and projection transform matrices.//-----------------------------------------------------------------------------VOID SetupMatrices(){// Set up world matrixD3DXMATRIXA16 matWorld;D3DXMatrixRotationY( &matWorld, timeGetTime()/1000.0f );g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );

    // Set up our view matrix. A view matrix can be defined given an eye point,// a point to lookat, and a direction for which way is up. Here, we set the// eye five units back along the z-axis and up three units, look at the // origin, and define "up" to be in the y-direction.D3DXVECTOR3 vEyePt( 0.0f, 3.0f,-3.0f );D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );D3DXMATRIXA16 matView;D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );

    // For the projection matrix, we set up a perspective transform (which// transforms geometry from 3D view space to 2D viewport space, with// a perspective divide making objects smaller in the distance). To build// a perpsective transform, we need the field of view (1/4 pi is common),// the aspect ratio, and the near and far clipping planes (which define at// what distances geometry should be no longer be rendered).D3DXMATRIXA16 matProj;D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 600.0f );g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );}

     

    //-----------------------------------------------------------------------------// Name: Render()// Desc: Draws the scene//-----------------------------------------------------------------------------VOID Render(){// Clear the backbuffer and the zbufferg_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,    D3DCOLOR_XRGB(0,0,0), 1.0f, 0 );

    // Begin the sceneif( SUCCEEDED( g_pd3dDevice->BeginScene() ) ){   // Setup the world, view, and projection matrices   SetupMatrices();

       // Meshes are divided into subsets, one for each material. Render them in   // a loop   for( DWORD i=0; i<g_dwNumMaterials; i++ )   {    // Set the material and texture for this subset    g_pd3dDevice->SetMaterial( &g_pMeshMaterials[i] );    g_pd3dDevice->SetTexture( 0, g_pMeshTextures[i] );

        // Draw the mesh subset    g_pd3dDevice->SetStreamSource(0,g_pSubBuffer[i],0,sizeof(VERTEX));    g_pd3dDevice->SetFVF(VERTEX::FVF);    g_pd3dDevice->SetIndices(g_pIndexBuffer[i]);    g_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,g_pNumVerts[i],0,g_pNumFaces[i]);   }

       // End the scene   g_pd3dDevice->EndScene();}

    // Present the backbuffer contents to the displayg_pd3dDevice->Present( NULL, NULL, NULL, NULL );}

     

    //-----------------------------------------------------------------------------// Name: MsgProc()// Desc: The window's message handler//-----------------------------------------------------------------------------LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ){switch( msg ){case WM_DESTROY:   Cleanup();   PostQuitMessage( 0 );   return 0;}

    return DefWindowProc( hWnd, msg, wParam, lParam );}

     

    //-----------------------------------------------------------------------------// Name: WinMain()// Desc: The application's entry point//-----------------------------------------------------------------------------INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT ){// Register the window classWNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,    GetModuleHandle(NULL), NULL, NULL, NULL, NULL,   "D3D Tutorial", NULL };RegisterClassEx( &wc );

    // Create the application's windowHWND hWnd = CreateWindow( "D3D Tutorial", "D3D Tutorial 3ds Rendering",    WS_OVERLAPPEDWINDOW, 100, 100, 600, 500,   NULL, NULL, wc.hInstance, NULL );

    // Initialize Direct3Dif( SUCCEEDED( InitD3D( hWnd ) ) ){    // Create the scene geometry   if( SUCCEEDED( InitGeometry() ) )   {    // Show the window    ShowWindow( hWnd, SW_SHOWDEFAULT );    UpdateWindow( hWnd );

        // Enter the message loop    MSG msg;     ZeroMemory( &msg, sizeof(msg) );    while( msg.message!=WM_QUIT )    {     if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )     {      TranslateMessage( &msg );      DispatchMessage( &msg );     }     else      Render();    }   }}

    UnregisterClass( "D3D Tutorial", wc.hInstance );return 0;}

    最新回复(0)