• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            天行健 君子當自強而不息

            D3D中的網格模型(3)

            10.7 復制

            有時我們需要將一個mesh中的數據拷貝到另一個mesh中,這時可以使用ID3DXBaseMesh::CloneMeshFVF方法。

            HRESULT ID3DXMesh::CloneMeshFVF(

                   DWORD Options,

                   DWORD FVF,

                   LPDIRECT3DDEVICE9 pDevice,

                   LPD3DXMESH* ppCloneMesh

            );

            Options — 用來創建mesh的一個或多個創建標志。要了解所有標志信息請查看sdk文檔。現在列出一部分:

                    D3DXMESH_32BIT — mesh使用32位索引。

                    D3DXMESH_MANAGED — mesh數據將被放在托管的內存中。

                    D3DXMESH_WRITEONLY — mesh數據只能執行寫操作,不能執行讀操作。

                    D3DXMESH_DYNAMIC — mesh緩存將是動態的。

                    FVF — 創建復制mesh的靈活頂點格式。

                    pDevice — 與復制mesh有關的設備。

                    ppCloneMesh — 輸出復制的mesh。

             

            注意這個方法允許指定與原mesh不同的options和FVF。例如我們有頂點格式為D3DFVF_XYZ的mesh,現在想復制一個頂點格式為 D3DFVF_XYZ|D3DFVF_NORMAL的mesh。我們可以這樣寫:

            // 假設_mesh和device是有效的

            ID3DXMesh* clone = 0;

            Mesh->CloneMeshFVF(

                   Mesh->GetOptions(), // 使用與源模型同樣的選項

                   D3DFVF_XYZ | D3DFVF_NORMAL,// 指定克隆的FVF

                   Device,

                   &clone

            );


            10.8 創建一個Mesh(D3DXCreateMeshFVF)

            我們可以使用D3DXCreate*函數來創建mesh物體。然而,我們也可以使用D3DXCreateMeshFVF函數來創建一個空mesh。所謂空 mesh是指我們已經指定了頂點數和面數,函數D3DXCreateMeshFVF也分配了適當大小的內存給頂點、頂點索引、屬性緩沖區。有了這些緩沖區后,就可以手動填寫上下文數據了(需要分別向頂點緩存,索引緩存、屬性緩存提供頂點、索引、屬性數據)。

            我們使用D3DXCreateMeshFVF函數來創建空mesh:

            HRESULT D3DXCreateMeshFVF(

                   DWORD NumFaces,

                   DWORD NumVertices,

                   DWORD Options,

                   DWORD FVF,

                   LPDIRECT3DDEVICE9 pDevice,

                   LPD3DXMESH* ppMesh

            );

                    NumFaces — mesh將擁有的面數。該值必須大于0。

                    NumVertices — mesh將擁有的頂點數。該值必須大于0。

                    Options —用來創建mesh的一個或多個創建標志。要了解所有標志信息請查看sdk文檔,現在列出一部分:

                        D3DXMESH_32BIT — mesh使用32位索引。

                        D3DXMESH_MANAGED — mesh數據將被放在托管的內存中。

                        D3DXMESH_WRITEONLY — mesh數據只能執行寫操作,不能執行讀操作。

                        D3DXMESH_DYNAMIC — mesh緩存將是動態的。

                    FVF — mesh的頂點格式。

                    pDevice — 與mesh相關的設備。

                    ppMesh — 輸出創建好的mesh。

            另外,你也可以使用D3DXCreateMesh來創建空mesh。它的原型是:

            HRESULT D3DXCreateMesh(

                   DWORD NumFaces,

                   DWORD NumVertices,

                   DWORD Options,

                   CONST LPD3DVERTEXELEMENT9* pDeclaration,

                   LPDIRECT3DDEVICE9 pDevice,

                   LPD3DXMESH* ppMesh

            );

            這些參數和D3DXCreateMeshFVF的參數是非常相似的,除了第四個。作為替代指定的FVF,我們指定一個D3DVERTEXELEMENT9 結構,它描述了頂點格式。

            HRESULT D3DXDeclaratorFromFVF(

                   DWORD FVF, // input format

                   D3DVERTEXELEMENT9 Declaration[MAX_FVF_DECL_SIZE]//output format

            );

            這個函數通過輸入一個FVF返回一個D3DVERTEXELEMENT9結構的數組。注意MAX_FVF_DECL_SIZE的定義如下:< /p>

            typedef enum {

                   MAX_FVF_DECL_SIZE = 18

            } MAX_FVF_DECL_SIZE;


            10.9 實例程序:創建和渲染Mesh

            該實例程序是渲染一個立方體(如圖10.5):

            它演示了這一章中的大部分功能,包括如下一些操作:

            創建一個空mesh。

            用一個立方體幾何信息來填充mesh。

            根據mesh的每個面指定子集。

            產生mesh的鄰接信息。

            優化mesh。

            繪制mesh。

            /**************************************************************************************
              Demonstrates how to create an empty ID3DXMesh object with D3DXCreateMeshFVF, 
              how to fill the vertex, index, and attribute buffers, how to optimize a mesh
              and gnerate an attribute table, and how to render it.   
             *************************************************************************************
            */

            #include 
            <fstream>
            #include 
            <vector>
            #include 
            "d3dUtility.h"

            #pragma warning(disable : 
            4100)

            using namespace std;

            class cTextureVertex
            {
            public:
                
            float m_x,  m_y,  m_z;
                
            float m_nx, m_ny, m_nz;
                
            float m_u,  m_v;

                cTextureVertex() { }

                cTextureVertex(
            float x, float y, float z, 
                               
            float nx, float ny, float nz,
                               
            float u, float v)
                {
                    m_x  
            = x;  m_y  = y;  m_z  = z;
                    m_nx 
            = nx; m_ny = ny; m_nz = nz;
                    m_u  
            = u;  m_v  = v;
                }    
            };

            const DWORD TEXTURE_VERTEX_FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1;

            ////////////////////////////////////////////////////////////////////////////////////////////////////

            const int WIDTH  = 640;
            const int HEIGHT = 480;

            IDirect3DDevice9
            *        g_d3d_device;
            ID3DXMesh
            *                g_d3d_mesh;
            IDirect3DTexture9
            *        g_d3d_textures[3];    // texture for each subset
            const DWORD                g_num_subsets = 3;

            ofstream g_out_file;    
            // used to dump mesh data to file

            void dump_vertices(ofstream& outFile, ID3DXMesh* mesh);
            void dump_indices(ofstream& outFile, ID3DXMesh* mesh);
            void dump_attribute_buffer(ofstream& outFile, ID3DXMesh* mesh);
            void dump_adjacency_buffer(ofstream& outFile, ID3DXMesh* mesh);
            void dump_attribute_table(ofstream& outFile, ID3DXMesh* mesh);


            ////////////////////////////////////////////////////////////////////////////////////////////////////

            bool setup()
            {    
                
            // We are going to fill the empty mesh with the geometry of a box,
                
            // so we need 12 triangles and 24 vertices.
                if(FAILED(D3DXCreateMeshFVF(1224, D3DXMESH_MANAGED, TEXTURE_VERTEX_FVF, g_d3d_device, &g_d3d_mesh)))
                {
                    MessageBox(NULL, 
            "D3DXCreateMeshFVF() - FAILED",  "ERROR", MB_OK);
                    
            return false;
                }

                
            // fill in vertices of a box

                cTextureVertex
            * v;

                g_d3d_mesh
            ->LockVertexBuffer(0, (void**)&v);

                
            // fill in the front face vertex data
                v[0= cTextureVertex(-1.0f-1.0f-1.0f0.0f0.0f-1.0f0.0f0.0f);
                v[
            1= cTextureVertex(-1.0f,  1.0f-1.0f0.0f0.0f-1.0f0.0f1.0f);
                v[
            2= cTextureVertex( 1.0f,  1.0f-1.0f0.0f0.0f-1.0f1.0f1.0f);
                v[
            3= cTextureVertex( 1.0f-1.0f-1.0f0.0f0.0f-1.0f1.0f0.0f);

                
            // fill in the back face vertex data
                v[4= cTextureVertex(-1.0f-1.0f1.0f0.0f0.0f1.0f0.0f0.0f);
                v[
            5= cTextureVertex( 1.0f-1.0f1.0f0.0f0.0f1.0f0.0f1.0f);
                v[
            6= cTextureVertex( 1.0f,  1.0f1.0f0.0f0.0f1.0f1.0f1.0f);
                v[
            7= cTextureVertex(-1.0f,  1.0f1.0f0.0f0.0f1.0f1.0f0.0f);

                
            // fill in the top face vertex data
                v[8]  = cTextureVertex(-1.0f1.0f-1.0f0.0f1.0f0.0f0.0f0.0f);
                v[
            9]  = cTextureVertex(-1.0f1.0f,  1.0f0.0f1.0f0.0f0.0f1.0f);
                v[
            10= cTextureVertex( 1.0f1.0f,  1.0f0.0f1.0f0.0f1.0f1.0f);
                v[
            11= cTextureVertex( 1.0f1.0f-1.0f0.0f1.0f0.0f1.0f0.0f);

                
            // fill in the bottom face vertex data
                v[12= cTextureVertex(-1.0f-1.0f-1.0f0.0f-1.0f0.0f0.0f0.0f);
                v[
            13= cTextureVertex( 1.0f-1.0f-1.0f0.0f-1.0f0.0f0.0f1.0f);
                v[
            14= cTextureVertex( 1.0f-1.0f,  1.0f0.0f-1.0f0.0f1.0f1.0f);
                v[
            15= cTextureVertex(-1.0f-1.0f,  1.0f0.0f-1.0f0.0f1.0f0.0f);

                
            // fill in the left face vertex data
                v[16= cTextureVertex(-1.0f-1.0f,  1.0f-1.0f0.0f0.0f0.0f0.0f);
                v[
            17= cTextureVertex(-1.0f,  1.0f,  1.0f-1.0f0.0f0.0f0.0f1.0f);
                v[
            18= cTextureVertex(-1.0f,  1.0f-1.0f-1.0f0.0f0.0f1.0f1.0f);
                v[
            19= cTextureVertex(-1.0f-1.0f-1.0f-1.0f0.0f0.0f1.0f0.0f);

                
            // fill in the right face vertex data
                v[20= cTextureVertex( 1.0f-1.0f-1.0f1.0f0.0f0.0f0.0f0.0f);
                v[
            21= cTextureVertex( 1.0f,  1.0f-1.0f1.0f0.0f0.0f0.0f1.0f);
                v[
            22= cTextureVertex( 1.0f,  1.0f,  1.0f1.0f0.0f0.0f1.0f1.0f);
                v[
            23= cTextureVertex( 1.0f-1.0f,  1.0f1.0f0.0f0.0f1.0f0.0f);

                g_d3d_mesh
            ->UnlockVertexBuffer();

                
            // define the triangles of the box

                WORD
            * index;

                g_d3d_mesh
            ->LockIndexBuffer(0, (void**)&index);

                
            // fill in the front face index data
                index[0= 0; index[1= 1; index[2= 2;
                index[
            3= 0; index[4= 2; index[5= 3;

                
            // fill in the back face index data
                index[6= 4; index[7]  = 5; index[8]  = 6;
                index[
            9= 4; index[10= 6; index[11= 7;

                
            // fill in the top face index data
                index[12= 8; index[13=  9; index[14= 10;
                index[
            15= 8; index[16= 10; index[17= 11;

                
            // fill in the bottom face index data
                index[18= 12; index[19= 13; index[20= 14;
                index[
            21= 12; index[22= 14; index[23= 15;

                
            // fill in the left face index data
                index[24= 16; index[25= 17; index[26= 18;
                index[
            27= 16; index[28= 18; index[29= 19;

                
            // fill in the right face index data
                index[30= 20; index[31= 21; index[32= 22;
                index[
            33= 20; index[34= 22; index[35= 23;

                g_d3d_mesh
            ->UnlockIndexBuffer();

                
            // Specify the subset each triangle belongs to, in this example we will use three subsets, 
                
            // the first two faces of the cube specified will be in subset 0, the next two faces will 
                
            // be in subset 1 and the the last two faces will be in subset 2.

                DWORD
            * attr_buffer;

                g_d3d_mesh
            ->LockAttributeBuffer(0&attr_buffer);

                
            for(int i = 0; i < 4; i++)
                    attr_buffer[i] 
            = 0;

                
            for(int i = 4; i < 8; i++)
                    attr_buffer[i] 
            = 1;

                
            for(int i = 8; i < 12; i++)
                    attr_buffer[i] 
            = 2;

                g_d3d_mesh
            ->UnlockAttributeBuffer();

                
            // optimize the mesh to generate an attribute table

                vector
            <DWORD> adjacency_buffer(g_d3d_mesh->GetNumFaces() * 3);
                g_d3d_mesh
            ->GenerateAdjacency(0.0f&adjacency_buffer[0]);

                g_d3d_mesh
            ->OptimizeInplace(D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_COMPACT | D3DXMESHOPT_VERTEXCACHE,
                                            
            &adjacency_buffer[0], NULL, NULL, NULL);

                
            // dump the mesh data to file

                g_out_file.open(
            "Mesh Dump.txt");

                dump_vertices(g_out_file, g_d3d_mesh);
                dump_indices(g_out_file, g_d3d_mesh);
                dump_attribute_table(g_out_file, g_d3d_mesh);
                dump_attribute_buffer(g_out_file, g_d3d_mesh);
                dump_adjacency_buffer(g_out_file, g_d3d_mesh);

                g_out_file.close();

                
            // create the texture and set filters

                D3DXCreateTextureFromFile(g_d3d_device, 
            "brick0.jpg",    &g_d3d_textures[0]);
                D3DXCreateTextureFromFile(g_d3d_device, 
            "brick1.jpg",    &g_d3d_textures[1]);
                D3DXCreateTextureFromFile(g_d3d_device, 
            "checker.jpg",    &g_d3d_textures[2]);

                g_d3d_device
            ->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
                g_d3d_device
            ->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
                g_d3d_device
            ->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);

                
            // disable lighting
                g_d3d_device->SetRenderState(D3DRS_LIGHTING, FALSE);

                
            // set camera

                D3DXVECTOR3 pos(
            0.0f0.f, -4.0f);
                D3DXVECTOR3 target(
            0.0f0.0f0.0f);
                D3DXVECTOR3 up(
            0.0f1.0f0.0f);

                D3DXMATRIX view_matrix;
                D3DXMatrixLookAtLH(
            &view_matrix, &pos, &target, &up);
                g_d3d_device
            ->SetTransform(D3DTS_VIEW, &view_matrix);

                
            // set the projection matrix
                D3DXMATRIX proj;
                D3DXMatrixPerspectiveFovLH(
            &proj, D3DX_PI * 0.5f, (float)WIDTH/HEIGHT, 1.0f1000.0f);
                g_d3d_device
            ->SetTransform(D3DTS_PROJECTION, &proj);
                
                
            return true;
            }

            ///////////////////////////////////////////////////////////////////////////////////////////////////////

            void cleanup()
            {    
                safe_release
            <ID3DXMesh*>(g_d3d_mesh);
                safe_release
            <IDirect3DTexture9*>(g_d3d_textures[0]);
                safe_release
            <IDirect3DTexture9*>(g_d3d_textures[1]);
                safe_release
            <IDirect3DTexture9*>(g_d3d_textures[2]);
            }

            ///////////////////////////////////////////////////////////////////////////////////////////////////////

            bool display(float time_delta)
            {
                
            // update: rotate the cube

                
            static float y = 0.0f;

                D3DXMATRIX x_rot_matrix, y_rot_matrix;
                D3DXMatrixRotationX(
            &x_rot_matrix, D3DX_PI * 0.2f);
                D3DXMatrixRotationY(
            &y_rot_matrix, y);

                D3DXMATRIX world_matrix 
            = x_rot_matrix * y_rot_matrix;
                g_d3d_device
            ->SetTransform(D3DTS_WORLD, &world_matrix);

                y 
            += time_delta;
                
            if(y >= 6.28f)
                    y 
            = 0.0f;

                
            // render now

                g_d3d_device
            ->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000001.0f0);

                g_d3d_device
            ->BeginScene();

                
            for(int i = 0; i < g_num_subsets; i++)
                {
                    g_d3d_device
            ->SetTexture(0, g_d3d_textures[i]);
                    g_d3d_mesh
            ->DrawSubset(i);
                }

                g_d3d_device
            ->EndScene();

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

                
            return true;
            }

            ///////////////////////////////////////////////////////////////////////////////////////////////////////

            LRESULT CALLBACK wnd_proc(HWND hwnd, UINT msg, WPARAM word_param, LPARAM long_param)
            {
                
            switch(msg)
                {
                
            case WM_DESTROY:
                    PostQuitMessage(
            0);
                    
            break;

                
            case WM_KEYDOWN:
                    
            if(word_param == VK_ESCAPE)
                        DestroyWindow(hwnd);
                    
            break;
                }

                
            return DefWindowProc(hwnd, msg, word_param, long_param);
            }

            ///////////////////////////////////////////////////////////////////////////////////////////////////////

            int WINAPI WinMain(HINSTANCE inst, HINSTANCE, PSTR cmd_line, int cmd_show)
            {
                
            if(! init_d3d(inst, WIDTH, HEIGHT, true, D3DDEVTYPE_HAL, &g_d3d_device))
                {
                    MessageBox(NULL, 
            "init_d3d() - failed."0, MB_OK);
                    
            return 0;
                }

                
            if(! setup())
                {
                    MessageBox(NULL, 
            "Steup() - failed."0, MB_OK);
                    
            return 0;
                }

                enter_msg_loop(display);

                cleanup();
                g_d3d_device
            ->Release();

                
            return 0;
            }

            ///////////////////////////////////////////////////////////////////////////////////////////////////////

            void dump_vertices(ofstream& out_file, ID3DXMesh* mesh)
            {
                out_file 
            << "Vertices:" << endl;
                out_file 
            << "---------" << endl;

                cTextureVertex
            * v;

                mesh
            ->LockVertexBuffer(0, (void**)&v);

                
            for(unsigned int i = 0; i < mesh->GetNumVertices(); i++)
                {
                    out_file 
            << "Vertex " << i << ":(";
                    out_file 
            << v[i].m_x << "" << v[i].m_y << "" << v[i].m_z << "";
                    out_file 
            << v[i].m_nx << "" << v[i].m_ny << "" << v[i].m_nz << "";
                    out_file 
            << v[i].m_u << "" << v[i].m_v << ")" << endl;
                }

                mesh
            ->UnlockVertexBuffer();

                out_file 
            << endl << endl;
            }

            ///////////////////////////////////////////////////////////////////////////////////////////////////////

            void dump_indices(ofstream& out_file, ID3DXMesh* mesh)
            {
                out_file 
            << "Indices:" << endl;
                out_file 
            << "--------" << endl << endl;

                WORD
            * indices;

                mesh
            ->LockIndexBuffer(0, (void**)&indices);

                
            for(unsigned int i = 0; i < mesh->GetNumFaces(); i++)
                {
                    out_file 
            << "Triangle " << i << "";
                    out_file 
            << indices[i*3<< " " << indices[i*3 + 1<< " " << indices[i*3 + 2<< endl;
                }

                mesh
            ->UnlockIndexBuffer();

                out_file 
            << endl << endl;
            }

            ///////////////////////////////////////////////////////////////////////////////////////////////////////

            void dump_attribute_buffer(ofstream& out_file, ID3DXMesh* mesh)
            {
                out_file 
            << "Attribute Buffer:" << endl;
                out_file 
            << "-----------------" << endl << endl;

                DWORD
            * attr_buffer;

                mesh
            ->LockAttributeBuffer(0&attr_buffer);

                
            // an attribute for each face
                for(unsigned int i = 0; i < mesh->GetNumFaces(); i++)
                    out_file 
            << "Triangle " << i << " lives in subset " << attr_buffer[i] << endl;

                mesh
            ->UnlockAttributeBuffer();

                out_file 
            << endl << endl;
            }

            ///////////////////////////////////////////////////////////////////////////////////////////////////////

            void dump_adjacency_buffer(ofstream& out_file, ID3DXMesh* mesh)
            {
                out_file 
            << "Adjacency Buffer:" << endl;
                out_file 
            << "-----------------" << endl << endl;

                
            // three entries per face
                vector<DWORD> adjacency_buffer(mesh->GetNumFaces() * 3);

                mesh
            ->GenerateAdjacency(0.0f&adjacency_buffer[0]);

                
            for(unsigned int i = 0; i < mesh->GetNumFaces(); i++)
                {
                    out_file 
            << "Triangle's adjacent to triangle " << i << "";

                    out_file 
            << adjacency_buffer[i*3<< " "
                             
            << adjacency_buffer[i*3 + 1<< " "
                             
            << adjacency_buffer[i*3 + 2<< endl;
                }

                out_file 
            << endl << endl;
            }

            ///////////////////////////////////////////////////////////////////////////////////////////////////////

            void dump_attribute_table(ofstream& out_file, ID3DXMesh* mesh)
            {
                out_file 
            << "Attribute Table:" << endl;
                out_file 
            << "----------------" << endl << endl;

                DWORD num_entries;    
            // number of entries in the attribute table
                mesh->GetAttributeTable(0&num_entries);

                vector
            <D3DXATTRIBUTERANGE> table(num_entries);
                mesh
            ->GetAttributeTable(&table[0], &num_entries);

                
            for(unsigned int i = 0; i < num_entries; i++)
                {
                    out_file 
            << "Entry " << i << endl;
                    out_file 
            << "-----------" << endl;

                    out_file 
            << "Subset ID:    " << table[i].AttribId    << endl;
                    out_file 
            << "Face Start:   " << table[i].FaceStart   << endl;
                    out_file 
            << "Face Count:   " << table[i].FaceCount   << endl;
                    out_file 
            << "Vertex Start: " << table[i].VertexStart << endl;
                    out_file 
            << "Vertex Count: " << table[i].VertexCount << endl;
                    out_file 
            << endl;
                }

                out_file 
            << endl << endl;
            }

             

             

            下載源程序


            posted on 2008-03-27 15:52 lovedday 閱讀(2680) 評論(0)  編輯 收藏 引用

            公告

            導航

            統計

            常用鏈接

            隨筆分類(178)

            3D游戲編程相關鏈接

            搜索

            最新評論

            国产精久久一区二区三区| 一级做a爰片久久毛片毛片| 色99久久久久高潮综合影院| 亚洲乱码中文字幕久久孕妇黑人| 久久精品国产半推半就| 久久久精品国产免大香伊 | 人妻精品久久久久中文字幕69| 久久精品国产只有精品2020| 一本色道久久88综合日韩精品 | 日日狠狠久久偷偷色综合免费 | 久久亚洲视频| 久久午夜电影网| 亚洲国产一成人久久精品| 久久久久亚洲AV成人网人人网站| 99久久99久久精品免费看蜜桃| 久久久一本精品99久久精品88| 久久久黄片| 国产精品xxxx国产喷水亚洲国产精品无码久久一区 | 亚洲午夜久久影院| 国内精品伊人久久久久av一坑| 久久人妻AV中文字幕| 久久这里的只有是精品23| 久久人妻少妇嫩草AV无码蜜桃| 国产成人无码精品久久久免费 | 久久综合中文字幕| 久久亚洲精品人成综合网| 久久这里只有精品首页| 伊人情人综合成人久久网小说| 久久这里只有精品视频99| 成人亚洲欧美久久久久| 93精91精品国产综合久久香蕉| 久久―日本道色综合久久| 久久不射电影网| 色综合合久久天天综合绕视看| 国产一久久香蕉国产线看观看| 久久久精品人妻一区二区三区蜜桃| 亚洲乱码精品久久久久..| 亚洲国产欧美国产综合久久 | 国产精品99精品久久免费| 国内精品伊人久久久久av一坑| 99久久人妻无码精品系列|