• <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>

            天行健 君子當(dāng)自強(qiáng)而不息

            創(chuàng)建游戲內(nèi)核(13)


             

            本篇是 創(chuàng)建游戲內(nèi)核(12)的續(xù)篇,其中涉及到的網(wǎng)格繪制知識請參閱D3D中網(wǎng)格模型的運(yùn)用

             

            使用MESH加載網(wǎng)格

            創(chuàng)建MESH類的目的是為了幫助程序員將那些小守護(hù)程序(demon加載到一連串易于使用的類中,然后同其他將網(wǎng)格渲染到顯示器上的對象結(jié)合起來使用。

            點(diǎn)擊下載源碼和工程

            首先定義一個(gè)結(jié)構(gòu)體S_MESH來封裝ID3DXMesh和ID3DXSkinInfo,以及材質(zhì)、紋理、變換矩陣等;這個(gè)結(jié)構(gòu)體被定位為鏈表結(jié)構(gòu)。

            struct S_MESH
            {
            public:
                
            char*               m_name;             // name of mesh

                ID3DXMesh*          m_mesh;             
            // mesh object
                ID3DXMesh*          m_skin_mesh;        // skin mesh object
                ID3DXSkinInfo*      m_skin_info;        // skin mesh information

                DWORD               m_num_materials;    
            // number of materials in mesh
                D3DMATERIAL9*       m_materials;        // array of materials
                IDirect3DTexture9** m_textures;         // array of textures

                DWORD               m_num_bones;        
            // number of bones
                D3DXMATRIX*         m_matrices;         // bone matrices
                D3DXMATRIX**        m_frame_matrices;   // pointers to frame matrices

                D3DXVECTOR3         m_min, m_max;       
            // bounding box
                float               m_radius;           // bounding sphere radius

                S_MESH*              m_next;             
            // next mesh in list

                //------------------------------------------------------------------------------------
                // Constructor, initialize all member data.
                //------------------------------------------------------------------------------------
                S_MESH()
                {
                    m_name = NULL;
                    m_mesh = NULL;
                    m_skin_mesh = NULL;
                    m_skin_info = NULL;
                    m_materials = NULL;
                    m_textures  = NULL;
                    m_matrices  = NULL;
                    m_frame_matrices = NULL;
                    m_next           = NULL;

                    m_num_materials  = 0;
                    m_num_bones      = 0;
                    m_radius         = 0.0f;

                    m_min.x = m_min.y = m_min.z = m_max.x = m_max.y = m_max.z = 0.0f;
                }

                
            //------------------------------------------------------------------------------------
                // Destrcutor, release all resouce.
                //------------------------------------------------------------------------------------
                ~S_MESH()
                {
                    Release_COM(m_mesh);
                    Release_COM(m_skin_mesh);
                    Release_COM(m_skin_info);

                    delete[] m_name;
                    delete[] m_materials;

                    
            if(m_textures)
                    {
                        
            for(DWORD i = 0; i < m_num_materials; i++)
                            Release_COM(m_textures[i]);

                        delete[] m_textures;
                    }

                    delete[] m_matrices;
                    delete[] m_frame_matrices;

                    delete m_next;
                }

                
            //------------------------------------------------------------------------------------
                // Find mesh object with specified name.
                //------------------------------------------------------------------------------------
                S_MESH* Find_Mesh(char* name)
                {        
                    
            // return first instance if name is NULL
                    if(name == NULL)
                        
            return this;

                    
            // compare names and return if exact match
                    if(m_name && !strcmp(name, m_name))
                        
            return this;

                    
            // search next in list
                    if(m_next != NULL)
                    {
                        S_MESH*  mesh;

                        
            // recursively call
                        if((mesh = m_next->Find_Mesh(name)) != NULL)
                            
            return mesh;
                    }

                    
            return NULL;
                }

                
            //------------------------------------------------------------------------------------
                // Get number of materials.
                //------------------------------------------------------------------------------------
                DWORD Get_Num_Materials()
                {
                    
            return m_num_materials;
                }

                
            //------------------------------------------------------------------------------------
                // Get material object.
                //------------------------------------------------------------------------------------
                D3DMATERIAL9* Get_Material(unsigned long index)
                {
                    
            if(index >= m_num_materials || m_materials == NULL)
                        
            return NULL;

                    
            return &m_materials[index];
                }

                
            //------------------------------------------------------------------------------------
                // Get texture object.
                //------------------------------------------------------------------------------------
                IDirect3DTexture9* Get_Texture(unsigned long index)
                {
                    
            if(index >= m_num_materials || m_textures == NULL)
                        
            return NULL;

                    
            return m_textures[index];
                }

                
            //------------------------------------------------------------------------------------
                // Copy all matrics from frames to local matrix array.
                //------------------------------------------------------------------------------------
                void Copy_Frame_To_Bone_Matrices()
                {        
                    
            if(m_num_bones != 0 && m_matrices && m_frame_matrices)
                    {
                        
            for(DWORD i = 0; i < m_num_bones; i++)
                        {
                            
            if(m_frame_matrices[i])
                                
            // gets the bone offset matrix and multiply it with frame transformed matrix
                                D3DXMatrixMultiply(&m_matrices[i], m_skin_info->GetBoneOffsetMatrix(i), m_frame_matrices[i]);
                            
            else
                                D3DXMatrixIdentity(&m_matrices[i]);
                        }
                    }

                    
            // process next in list (recursively call)
                    if(m_next != NULL)
                        m_next->Copy_Frame_To_Bone_Matrices();
                }
            };

            接著定義一個(gè)結(jié)構(gòu)體S_MESH_LIST來封裝S_MESH,這個(gè)結(jié)構(gòu)體也被定義為鏈表結(jié)構(gòu)。
             
            struct S_MESH_LIST
            {
            public:
                S_MESH*         m_mesh;
                S_MESH_LIST*    m_next;

                S_MESH_LIST()
                {
                    m_mesh = NULL;
                    m_next = NULL;
                }
                
                ~S_MESH_LIST()
                {
                    delete m_next;
                }
            };

            再接著定義一個(gè)結(jié)構(gòu)體S_FRAME表示框架層次,它也是鏈表結(jié)構(gòu),該結(jié)構(gòu)體包含了S_MESH_LIST列表。
             
            struct S_FRAME
            {
            public:
                
            char*   m_name;

                S_MESH_LIST*    m_mesh_list;        
            // list of meshes attached to this frame

                D3DXMATRIX      m_mat_combined;     
            // combined trasnformation matrix
                D3DXMATRIX      m_mat_transformed;  // currently transformed matrix
                D3DXMATRIX      m_mat_original;     // original .x File matrix

                S_FRAME*        m_parent;           
            // parent frame
                S_FRAME*        m_child;            // child frame
                S_FRAME*        m_sibling;          // silbling frame

                //------------------------------------------------------------------------------------
                // Constructor, initialize member data.
                //------------------------------------------------------------------------------------
                S_FRAME()
                {
                    m_name = NULL;
                    m_mesh_list = NULL;

                    D3DXMatrixIdentity(&m_mat_combined);
                    D3DXMatrixIdentity(&m_mat_transformed);
                    D3DXMatrixIdentity(&m_mat_original);

                    m_parent = m_sibling = m_child = NULL;           
                }

                
            //------------------------------------------------------------------------------------
                // Destructor, release all resource.
                //------------------------------------------------------------------------------------
                ~S_FRAME()
                {
                    delete m_name;
                    delete m_mesh_list;
                    delete m_child;
                    delete m_sibling;
                }

                
            //------------------------------------------------------------------------------------
                // Find frame with specified name.
                //------------------------------------------------------------------------------------
                S_FRAME* Find_Frame(char* name)
                {        
                    
            // return this instances if name is NULL
                    if(name == NULL)
                        
            return this;

                    
            // compare names and return if exact match
                    if(m_name && !strcmp(name, m_name))
                        
            return this;

                    S_FRAME* frame;

                    
            // search child lists, recursively call.
                    if(m_child != NULL)
                    {
                        
            if((frame = m_child->Find_Frame(name)) != NULL)
                            
            return frame;
                    }

                    
            // search sibling lists, recursively call.
                    if(m_sibling != NULL)
                    {
                        
            if((frame = m_sibling->Find_Frame(name)) != NULL)
                            
            return frame;
                    }

                    
            return NULL;
                }

                
            //------------------------------------------------------------------------------------
                // Reset transformed matrices to original matrices, recursively call.
                //------------------------------------------------------------------------------------
                void Reset_Matrices()
                {
                    m_mat_transformed = m_mat_original;

                    
            if(m_child != NULL)
                        m_child->Reset_Matrices();

                    
            if(m_sibling != NULL)
                        m_sibling->Reset_Matrices();
                }

                
            //------------------------------------------------------------------------------------
                // Add mesh into mesh list.
                //------------------------------------------------------------------------------------
                void Add_Mesh(S_MESH* mesh)
                {
                    S_MESH_LIST* mesh_list = 
            new S_MESH_LIST();

                    mesh_list->m_mesh = mesh;
                    mesh_list->m_next = m_mesh_list;

                    m_mesh_list = mesh_list;
                }
            };
             
            在以上已經(jīng)定義好的結(jié)構(gòu)體基礎(chǔ)上,我們定義一個(gè)類MESH來實(shí)現(xiàn)網(wǎng)格文件的加載。

             
            class MESH
            {
            private:
                GRAPHICS*   _graphics;

                
            long        _num_meshes;
                S_MESH*      _meshes;

                
            long        _num_frames;
                S_FRAME*    _frames;

                D3DXVECTOR3 _min, _max;
                
            float       _radius;

                
            void _Parse_XFile_Data(ID3DXFileData* xfile_data, S_FRAME* parent_frame, char* texture_path);
                
            void _Map_Frames_To_Bones(S_FRAME* frame);

            public:
                MESH();
                ~MESH();

                BOOL Is_Loaded();

                
            long Get_Num_Frames();
                S_FRAME* Get_Parent_Frame();
                S_FRAME* Get_Frame(
            char* name);

                
            long Get_Num_Meshes();
                S_MESH* Get_Parent_Mesh();
                S_MESH* Get_Mesh(
            char* name);

                
            void Get_Bounds(float* min_x, float* min_y, float* min_z, float* max_x, float* max_y, float* max_z, float* radius);

                BOOL Load(GRAPHICS* graphics, 
            char* filename, char* texture_path = ".\\");

                
            void Free();
            };

            這是類MESH的實(shí)現(xiàn):
             
            //-------------------------------------------------------------------
            // Constructor, initialize member data.
            //-------------------------------------------------------------------
            MESH::MESH()
            {
                _graphics   = NULL;
                _meshes     = NULL;
                _frames     = NULL;

                _num_meshes = 0;
                _num_frames = 0;
                _radius     = 0.0f;

                _min.x = _min.y = _min.z = _max.x = _max.y = _max.z = 0.0f;
            }

            //-------------------------------------------------------------------
            // Destructor, release all resource.
            //-------------------------------------------------------------------
            MESH::~MESH()
            {
                Free();
            }

            //-------------------------------------------------------------------
            // Release all resource.
            //-------------------------------------------------------------------
            void MESH::Free()
            {
                _graphics = NULL;

                _num_meshes = 0;
                delete _meshes; _meshes = NULL;

                _num_frames = 0;
                delete _frames; _frames = NULL;

                _min.x = _min.y = _min.z = _max.x = _max.y = _max.z = 0.0f;

                _radius = 0.0f;
            }

            //-------------------------------------------------------------------
            // Load .x File from specified filename.
            //-------------------------------------------------------------------
            BOOL MESH::Load(GRAPHICS* graphics, char* filename, char* texture_path)
            {
                
            // free prior mesh object data
                Free();

                
            // error checking
                if((_graphics = graphics) == NULL || filename == NULL)
                    
            return FALSE;

                ID3DXFile* xfile = NULL;

                
            // create the file object
                if(FAILED(D3DXFileCreate(&xfile)))
                    
            return FALSE;

                
            // register the templates
                if(FAILED(xfile->RegisterTemplates((LPVOID) D3DRM_XTEMPLATES, D3DRM_XTEMPLATE_BYTES)))
                {
                    xfile->Release();
                    
            return FALSE;
                }

                ID3DXFileEnumObject* xfile_enum = NULL;

                
            // create an enumeration object
                if(FAILED(xfile->CreateEnumObject((LPVOID) filename, DXFILELOAD_FROMFILE, &xfile_enum)))
                {
                    xfile->Release();
                    
            return FALSE;
                }

                
            // create a frame
                S_FRAME* frame = new S_FRAME();

                ID3DXFileData* xfile_data = NULL;
                SIZE_T num_child;

                
            // retrieve the number of children in this file data object
                xfile_enum->GetChildren(&num_child);

                
            // loop through all objects looking for the frames and meshes
                for(SIZE_T i = 0; i < num_child; i++)
                {
                    
            if(FAILED(xfile_enum->GetChild(i, &xfile_data)))
                        
            return FALSE;

                    
            // parse xfile data
                    _Parse_XFile_Data(xfile_data, frame, texture_path);

                    Release_COM(xfile_data);
                }

                
            // release used COM objects
                Release_COM(xfile_enum);
                Release_COM(xfile);

                
            // see if we should keep the frame as root
                if(frame->m_mesh_list != NULL)
                {
                    _frames = frame;

                    _frames->m_name = 
            new char[7];
                    strcpy(_frames->m_name, "%ROOT%");
                }
                
            else
                {
                    
            // assign the root frame and release frame
                    _frames = frame->m_child;
                    S_FRAME* frame_ptr = _frames;

                    
            while(frame_ptr != NULL)
                    {
                        frame_ptr->m_parent = NULL;
                        frame_ptr = frame_ptr->m_sibling;
                    }

                    frame->m_child = NULL;
                    delete frame;
                }

                
            // map transformed matrix frames to bones
                _Map_Frames_To_Bones(_frames);

                S_MESH* mesh;

                
            // calculate bounding box and sphere
                if((mesh = _meshes) != NULL)
                {
                    
            while(mesh != NULL)
                    {
                        _min.x = min(_min.x, mesh->m_min.x);
                        _min.y = min(_min.y, mesh->m_min.y);
                        _min.z = min(_min.z, mesh->m_min.z);
                        _max.x = min(_max.x, mesh->m_max.x);
                        _max.y = min(_max.y, mesh->m_max.y);
                        _max.z = min(_max.z, mesh->m_max.z);

                        _radius = max(_radius, mesh->m_radius);

                        mesh = mesh->m_next;
                    }
                }

                
            return TRUE;
            }

            //-------------------------------------------------------------------
            // Parse specified xfile data, recursive function.
            //-------------------------------------------------------------------
            void MESH::_Parse_XFile_Data(ID3DXFileData* xfile_data, S_FRAME* parent_frame, char* texture_path)
            {
                
            // get the template type

                GUID type;

                
            // retrieve the globally unique identifier (GUID) of the object's template
                if(FAILED(xfile_data->GetType(&type)))
                    
            return;

                
            // get the template name (if any)

                DWORD size;

                
            if(FAILED(xfile_data->GetName(NULL, &size)))
                    
            return;

                
            char* name = NULL;

                
            if(size != 0)
                {
                    
            if((name = new char[size]) != NULL)
                        xfile_data->GetName(name, &size);
                }

                
            // give template a default name if none found
                if(name == NULL)
                {
                    
            if((name = new char[9]) == NULL)
                        
            return;

                    strcpy(name, "$NoName$");
                }

                
            // set current frame
                S_FRAME* current_frame = parent_frame;

                
            // process the templates

                
            if(type == TID_D3DRMFrame)  // it's a frame
                {
                    
            // create a new frame structure
                    S_FRAME* frame = new S_FRAME();

                    
            // store the name
                    frame->m_name = name;
                    name = NULL;
                    
                    
            // add to parent frame
                    frame->m_parent  = parent_frame;
                    frame->m_sibling = parent_frame->m_child;
                    parent_frame->m_child = frame;

                    
            // increase frame count
                    _num_frames++;

                    
            // set current frame with parent frame        
                    current_frame = frame;
                }
                
            else if(type == TID_D3DRMFrameTransformMatrix)  // it's a frame transformation matrix
                {
                    D3DXMATRIX* frame_matrix = NULL;

                    
            // get frame transformation matrix
                    if(FAILED(xfile_data->Lock(&size, (LPCVOID*) &frame_matrix)))
                        
            return;

                    
            // set original matrix
                    parent_frame->m_mat_original = *frame_matrix;

                    xfile_data->Unlock();
                }
                
            else if(type == TID_D3DRMMesh)  // it's a mesh
                {
                    ID3DXBuffer*    material_buffer = NULL;
                    ID3DXBuffer*    adjacency = NULL;
                    S_MESH*         mesh = NULL;

                    
            // see if mesh already loaded
                    if(_meshes == NULL || _meshes->Find_Mesh(name) == NULL)
                    {
                        
            // create a new mesh structure
                        mesh = new S_MESH();

                        
            // store the name
                        mesh->m_name = name;
                        name = NULL;

                        
            // load mesh data
                        if(FAILED(D3DXLoadSkinMeshFromXof(xfile_data, 0, _graphics->Get_Device_COM(),
                            &adjacency, &material_buffer, NULL, &mesh->m_num_materials, &mesh->m_skin_info, &mesh->m_mesh)))
                        {
                            delete[] name;
                            delete mesh;
                            
            return;
                        }

                        BYTE** ptr;

                        
            // calculate the bounding box and sphere
                        if(SUCCEEDED(mesh->m_mesh->LockVertexBuffer(D3DLOCK_READONLY, (void**) &ptr)))
                        {
                            
            // computes a coordinate-axis oriented bounding box
                            D3DXComputeBoundingBox((D3DXVECTOR3*) ptr, mesh->m_mesh->GetNumVertices(),
                                mesh->m_mesh->GetNumBytesPerVertex(), &mesh->m_min, &mesh->m_max);

                            
            // computes a bounding sphere for the mesh
                            D3DXComputeBoundingSphere((D3DXVECTOR3*) ptr, mesh->m_mesh->GetNumVertices(),
                                mesh->m_mesh->GetNumBytesPerVertex(), &D3DXVECTOR3(0.0f, 0.0f, 0.0f), &mesh->m_radius);

                            mesh->m_mesh->UnlockVertexBuffer();
                        }

                        
            // store number of bones (if any)
                        if(mesh->m_skin_info)
                            mesh->m_num_bones = mesh->m_skin_info->GetNumBones();

                        
            // create a matching skinned mesh if bone exist
                        if(mesh->m_skin_info != NULL && mesh->m_num_bones != 0)
                        {
                            
            // clones a mesh using a flexible vertex format (FVF) code
                            if(FAILED(mesh->m_mesh->CloneMeshFVF(0, mesh->m_mesh->GetFVF(), _graphics->Get_Device_COM(),
                                                                 &mesh->m_skin_mesh)))
                            {
                                Release_COM(mesh->m_skin_info);
                            }
                            
            else    // create an array of matrices to store bone transformations
                            {
                                
            // create the bone matrix array and clear it out
                                mesh->m_matrices = new D3DXMATRIX[mesh->m_num_bones];

                                
            for(DWORD i = 0; i < mesh->m_num_bones; i++)
                                    D3DXMatrixIdentity(&mesh->m_matrices[i]);

                                
            // create the frame mapping matrix array and clear out
                                mesh->m_frame_matrices = new D3DXMATRIX*[mesh->m_num_bones];

                                
            for(DWORD i = 0; i < mesh->m_num_bones; i++)
                                    mesh->m_frame_matrices[i] = NULL;
                            }
                        }
                        
                        
            // load meterials or create a default one if none
                        if(mesh->m_num_materials == 0)
                        {
                            
            // create a default one
                            mesh->m_materials = new D3DMATERIAL9[1];
                            mesh->m_textures  = 
            new LPDIRECT3DTEXTURE9[1];

                            ZeroMemory(mesh->m_materials, 
            sizeof(D3DMATERIAL9));

                            mesh->m_materials[0].Diffuse.r = 1.0f;
                            mesh->m_materials[0].Diffuse.g = 1.0f;
                            mesh->m_materials[0].Diffuse.b = 1.0f;
                            mesh->m_materials[0].Diffuse.a = 1.0f;
                            mesh->m_materials[0].Ambient   = mesh->m_materials[0].Diffuse;
                            mesh->m_materials[0].Specular  = mesh->m_materials[0].Diffuse;

                            mesh->m_textures[0] = NULL;

                            mesh->m_num_materials = 1;
                        }   
                        
            else
                        {
                            
            // load the materials
                            D3DXMATERIAL* materials = (D3DXMATERIAL*) material_buffer->GetBufferPointer();

                            mesh->m_materials = 
            new D3DMATERIAL9[mesh->m_num_materials];
                            mesh->m_textures  = 
            new LPDIRECT3DTEXTURE9[mesh->m_num_materials];

                            
            char path[MAX_PATH];

                            
            for(DWORD i = 0; i < mesh->m_num_materials; i++)
                            {
                                mesh->m_materials[i] = materials[i].MatD3D;
                                mesh->m_materials[i].Ambient = mesh->m_materials[i].Diffuse;

                                
            // build a texture path and load it
                                sprintf(path, "%s%s", texture_path, materials[i].pTextureFilename);

                                
            if(FAILED(D3DXCreateTextureFromFile(_graphics->Get_Device_COM(), path, &mesh->m_textures[i])))
                                    mesh->m_textures[i] = NULL;
                            }
                        }

                        Release_COM(material_buffer);
                        Release_COM(adjacency);

                        
            // link in mesh
                        mesh->m_next = _meshes;
                        _meshes = mesh;
                        _num_meshes++;
                    }
                    
            else
                        
            // Find mesh in list
                        mesh = _meshes->Find_Mesh(name);

                    
            // add mesh to frame
                    if(mesh != NULL)    
                        parent_frame->Add_Mesh(mesh);
                } 
            // end if(type == TID_D3DRMMesh)
                else if(type == TID_D3DRMAnimationSet || type == TID_D3DRMAnimation || type == TID_D3DRMAnimationKey)
                {
                    
            // skip animation sets and animations
                    delete[] name;
                    
            return;
                }

                
            // release name buffer
                delete[] name;

                ID3DXFileData* child_xfile_data = NULL;
                SIZE_T num_child;

                xfile_data->GetChildren(&num_child);

                
            // scan for embedded templates
                for(SIZE_T i = 0; i < num_child; i++)
                {        
                    xfile_data->GetChild(i, &child_xfile_data);

                    
            // process embedded references
                    _Parse_XFile_Data(child_xfile_data, current_frame, texture_path);

                    Release_COM(child_xfile_data);
                }
            }

            //-------------------------------------------------------------------
            // Map frame transformation matrix to match bone, recursively call.
            //-------------------------------------------------------------------
            void MESH::_Map_Frames_To_Bones(S_FRAME *frame)
            {
                
            // return if no more frames to map
                if(frame == NULL || frame->m_name == NULL)
                    
            return;

                
            // scan through meshes looking for bone matches
                S_MESH* mesh = _meshes;

                
            while(mesh != NULL)
                {
                    
            if(mesh->m_skin_info && mesh->m_num_bones && mesh->m_matrices && mesh->m_frame_matrices)
                    {
                        
            for(DWORD i = 0; i < mesh->m_num_bones; i++)
                        {
                            
            if(!strcmp(frame->m_name, mesh->m_skin_info->GetBoneName(i)))
                            {
                                mesh->m_frame_matrices[i] = &frame->m_mat_combined;
                                
            break;
                            }
                        }
                    }

                    mesh = mesh->m_next;
                }

                
            // scan through child frames    
                _Map_Frames_To_Bones(frame->m_child);

                
            // scan throuogh sibling frames
                _Map_Frames_To_Bones(frame->m_sibling);
            }

            //-------------------------------------------------------------------
            // Judge whether the mesh has been loaded successfully.
            //-------------------------------------------------------------------
            BOOL MESH::Is_Loaded()
            {
                
            return (_meshes != NULL && _frames != NULL);
            }

            //-------------------------------------------------------------------
            // Get number of frame.
            //-------------------------------------------------------------------
            long MESH::Get_Num_Frames()
            {
                
            return _num_frames;
            }

            //-------------------------------------------------------------------
            // Get root frame.
            //-------------------------------------------------------------------
            S_FRAME* MESH::Get_Parent_Frame()
            {
                
            return _frames;
            }

            //-------------------------------------------------------------------
            // Find frame with specified name.
            //-------------------------------------------------------------------
            S_FRAME* MESH::Get_Frame(char *name)
            {
                
            if(_frames == NULL)
                    
            return NULL;

                
            return _frames->Find_Frame(name);
            }

            //-------------------------------------------------------------------
            // Get number of mesh.
            //-------------------------------------------------------------------
            long MESH::Get_Num_Meshes()
            {
                
            return _num_meshes;
            }

            //-------------------------------------------------------------------
            // Get root mesh.
            //-------------------------------------------------------------------
            S_MESH* MESH::Get_Mesh(char *name)
            {
                
            if(_meshes == NULL)
                    
            return NULL;

                
            return _meshes->Find_Mesh(name);
            }

            //-------------------------------------------------------------------
            // Get bound box coordiante and radius.
            //-------------------------------------------------------------------
            void MESH::Get_Bounds(float *min_x, float *min_y, float *min_z, float *max_x, float *max_y, float *max_z, float *radius)
            {
                
            if(min_x != NULL)   *min_x = _min.x;
                
            if(min_y != NULL)   *min_y = _min.y;
                
            if(min_z != NULL)   *min_z = _min.z;

                
            if(max_x != NULL)   *max_x = _max.x;
                
            if(max_y != NULL)   *max_y = _max.y;
                
            if(max_z != NULL)   *max_z = _max.z;

                
            if(radius != NULL)  *radius = _radius;
            }

            接著我們編寫一段測試代碼來測試MESH類:
            /*****************************************************************************
            PURPOSE:
                Test for class MESH.
            *****************************************************************************/


            #include "Core_Global.h"

            #pragma warning(disable : 4996)

            //===========================================================================
            // Defines class APP which public inherits from class APPLICATION.
            //===========================================================================
            class APP : public APPLICATION
            {
            private:
                GRAPHICS        _graphics;
                MESH            _mesh;

                BOOL _Draw_Mesh(S_FRAME* frame);
                
            public:    
                BOOL Init();
                BOOL Shutdown();
                BOOL Frame();
            };

            //-----------------------------------------------------------------------------
            // Initialize graphics, set display mode, set vertex buffer, load texture file.
            //-----------------------------------------------------------------------------
            BOOL APP::Init()
            {    
                D3DXMATRIX mat_view;

                
            // initialize graphics
                if (! _graphics.Init())
                    
            return FALSE;    

                
            // set display mode for graphics
                if(! _graphics.Set_Mode(Get_Hwnd(), TRUE, FALSE, 400, 400, 16))
                    
            return FALSE;

                
            // disable D3D lighting
                _graphics.Enable_Lighting(FALSE);

                
            // set perspective projection transform matrix.
                _graphics.Set_Perspective(D3DX_PI/4.0f, 1.33333f, 1.0f, 1000.0f);

                
            // create and set the view matrix
                D3DXMatrixLookAtLH(&mat_view, 
                                   &D3DXVECTOR3(0.0, 50.0, -150.0),
                                   &D3DXVECTOR3(0.0, 50.0,  0.0), 
                                   &D3DXVECTOR3(0.0, 1.0,   0.0));

                _graphics.Get_Device_COM()->SetTransform(D3DTS_VIEW, &mat_view);

                
            // load mesh
                if(! _mesh.Load(&_graphics, "warrior.x"))
                    
            return FALSE;

                
            return TRUE;
            }

            //-----------------------------------------------------------------------------
            // Release all d3d resource.
            //-----------------------------------------------------------------------------
            BOOL APP::Shutdown()
            {
                
            return TRUE;
            }

            //-----------------------------------------------------------------------------
            // Render a frame.
            //-----------------------------------------------------------------------------
            BOOL APP::Frame()
            {
                D3DXMATRIX mat_world;

                
            // clear display with specified color
                _graphics.Clear_Display(D3DCOLOR_RGBA(0, 0, 0, 255));

                
            // begin scene
                if(_graphics.Begin_Scene())
                {
                    
            // create and set the world transformation matrix
                    // rotate object along z-axis
                    D3DXMatrixRotationY(&mat_world, (float) (timeGetTime() / 1000.0));

                    _graphics.Get_Device_COM()->SetTransform(D3DTS_WORLD, &mat_world);        

                    
            // get root frame
                    S_FRAME* root_frame = _mesh.Get_Parent_Frame();

                    
            // draw mesh
                    _Draw_Mesh(root_frame);
                    
                    
            // end the scene
                    _graphics.End_Scene();       
                }

                
            // display video buffer
                _graphics.Display();
                
                
            return TRUE;
            }

            //-----------------------------------------------------------------------------
            // Draw mesh, call recursively.
            //-----------------------------------------------------------------------------
            BOOL APP::_Draw_Mesh(S_FRAME* frame)
            {
                D3DXMATRIX* matrices = NULL;
                ID3DXMesh*  mesh_to_draw;  
                S_MESH* mesh;
                
                
            // return if no frame
                if(frame == NULL)
                    
            return FALSE;

                
            if(frame->m_mesh_list != NULL)
                {
                    
            // draw meshes if any in frame
                    if((mesh = frame->m_mesh_list->m_mesh) != NULL)
                    {
                        
            // setup pointer to mesh to draw
                        mesh_to_draw = mesh->m_mesh;

                        
            // generate mesh from skinned mesh to draw with
                        if(mesh->m_skin_mesh != NULL && mesh->m_skin_info != NULL)
                        {
                            DWORD num_bones = mesh->m_skin_info->GetNumBones();

                            
            // allocate an array of matrices to orient bones
                            matrices = new D3DXMATRIX[num_bones];

                            
            // set all bones orientation to identity
                            for(DWORD i = 0; i < num_bones; i++)
                                D3DXMatrixIdentity(&matrices[i]);

                            
            // lock source and destination vertex buffers

                            
            void* source = NULL;
                            
            void* dest = NULL;

                            
            // locks a vertex buffer and obtains a pointer to the vertex buffer memory
                            mesh->m_mesh->LockVertexBuffer(0, &source);
                            mesh->m_skin_mesh->LockVertexBuffer(0, &dest);

                            
            // Update skinned mesh, applies software skinning to the target vertices based on the current matrices.
                            mesh->m_skin_info->UpdateSkinnedMesh(matrices, NULL, source, dest);

                            
            // unlock buffers
                            mesh->m_mesh->UnlockVertexBuffer();
                            mesh->m_skin_mesh->UnlockVertexBuffer();
                            
                            
            // pointer to skin mesh to draw
                            mesh_to_draw = mesh->m_skin_mesh;
                        }

                        
            // render the mesh
                        for(DWORD i = 0; i < mesh->Get_Num_Materials(); i++)
                        {
                            
            // set the materials properties for the device            
                            _graphics.Get_Device_COM()->SetMaterial(&mesh->m_materials[i]);

                            
            // assign a texture to a stage for a device
                            _graphics.Get_Device_COM()->SetTexture(0, mesh->m_textures[i]);

                            
            // draw a subset of a mesh
                            mesh_to_draw->DrawSubset(i);
                        }

                        
            // free array of matrices
                        delete[] matrices;
                        matrices = NULL;
                    }
                }
                
                
            // draw child frames, recursively call.
                _Draw_Mesh(frame->m_child);

                
            return TRUE;
            }


            int PASCAL WinMain(HINSTANCE inst, HINSTANCE, LPSTR cmd_line, int cmd_show)
            {
                APP app;

                
            return app.Run();
            }

            運(yùn)行截圖:
             


            posted on 2007-09-09 01:50 lovedday 閱讀(524) 評論(0)  編輯 收藏 引用


            只有注冊用戶登錄后才能發(fā)表評論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            公告

            導(dǎo)航

            統(tǒng)計(jì)

            常用鏈接

            隨筆分類(178)

            3D游戲編程相關(guān)鏈接

            搜索

            最新評論

            久久久久久亚洲AV无码专区| 国产精品久久久久jk制服| 99久久99这里只有免费的精品| 久久午夜综合久久| 91精品婷婷国产综合久久| 国内精品久久久久影院优| 亚洲综合日韩久久成人AV| 亚洲第一永久AV网站久久精品男人的天堂AV | 久久棈精品久久久久久噜噜| 性做久久久久久久久老女人| 久久久久久国产精品免费免费| 色成年激情久久综合| 午夜不卡888久久| 香蕉久久一区二区不卡无毒影院| 久久99精品久久只有精品| 好久久免费视频高清| 免费观看成人久久网免费观看| 88久久精品无码一区二区毛片| 青青青青久久精品国产h| 99久久夜色精品国产网站| 91性高湖久久久久| 欧美精品福利视频一区二区三区久久久精品 | 久久综合九色综合97_久久久| 99久久99久久| 精品熟女少妇aⅴ免费久久| 久久亚洲国产精品五月天婷| 模特私拍国产精品久久| 国产成年无码久久久免费| 久久精品99久久香蕉国产色戒 | 亚洲日韩中文无码久久| 国产人久久人人人人爽| 国产精品热久久无码av| 亚洲午夜无码久久久久小说| 日日噜噜夜夜狠狠久久丁香五月 | 久久精品国产99国产精品澳门| 观看 国产综合久久久久鬼色 欧美 亚洲 一区二区 | 久久天天躁狠狠躁夜夜2020一 | 国产精品女同一区二区久久| 亚洲v国产v天堂a无码久久| 亚洲精品国产美女久久久| 精品一区二区久久|