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

            天行健 君子當自強而不息

            創建游戲內核(13)【OO改良版】

             

            本篇是創建游戲內核(12)【OO改良版】的續篇,關于該內核的細節說明請參閱創建游戲內核(13)


            接口:

            //================================================================================
            // Defines for structure MESH_INFO.
            //================================================================================
            typedef struct MESH_INFO
            {
                
            //------------------------------------------------------------------------------------
                // Constructor, initialize all member data.
                //------------------------------------------------------------------------------------
                MESH_INFO()
                {
                    memset(
            this, 0, sizeof(*this));       
                }

                
            //------------------------------------------------------------------------------------
                // Destructor, release all resouce.
                //------------------------------------------------------------------------------------
                ~MESH_INFO()
                {
                    release_com(m_d3d_mesh);
                    release_com(m_d3d_skin_mesh);
                    release_com(m_d3d_skin_info);

                    delete[] m_name;
                    delete[] m_d3d_materials;

                    
            if(m_d3d_textures)
                    {
                        
            for(DWORD i = 0; i < m_num_materials; i++)
                            release_com(m_d3d_textures[i]);

                        delete[] m_d3d_textures;
                    }

                    delete[] m_matrices;
                    delete[] m_frame_matrices;

                    delete m_next;
                }

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

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

                    
            // search next in list
                    if(m_next != NULL)
                    {
                        MESH_INFO*  _mesh_info;

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

                    
            return NULL;
                }

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

                
            //------------------------------------------------------------------------------------
                // Get material object.
                //------------------------------------------------------------------------------------
                D3DMATERIAL9* get_d3d_material(DWORD index)
                {
                    
            if(index >= m_num_materials || m_d3d_materials == NULL)
                        
            return NULL;

                    
            return &m_d3d_materials[index];
                }

                
            //------------------------------------------------------------------------------------
                // Get texture object.
                //------------------------------------------------------------------------------------
                IDirect3DTexture9* get_d3d_texture(DWORD index)
                {
                    
            if(index >= m_num_materials || m_d3d_textures == NULL)
                        
            return NULL;

                    
            return m_d3d_textures[index];
                }

                
            //------------------------------------------------------------------------------------
                // create frame transform matrices, recursively call.
                //------------------------------------------------------------------------------------
                void create_frame_transform_matrices()
                {        
                    DWORD _num_bones = get_num_bones();

                    
            if(_num_bones != 0 && m_matrices && m_frame_matrices)
                    {
                        
            for(DWORD i = 0; i < _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_d3d_skin_info->GetBoneOffsetMatrix(i), m_frame_matrices[i]);
                            
            else
                                D3DXMatrixIdentity(&m_matrices[i]);
                        }
                    }

                    
            // process next in list (recursively call)
                    if(m_next)
                        m_next->create_frame_transform_matrices();
                }

                
            //------------------------------------------------------------------------------------
                // Return number of bone in skin mesh information.
                //------------------------------------------------------------------------------------
                DWORD get_num_bones()
                {
                    
            return m_d3d_skin_info->GetNumBones();
                }

            public:
                
            char*               m_name;                     // name of mesh

                ID3DXMesh*          m_d3d_mesh;                 
            // mesh object
                ID3DXMesh*          m_d3d_skin_mesh;            // skin mesh object
                ID3DXSkinInfo*      m_d3d_skin_info;            // skin mesh information

                DWORD               m_num_materials;            
            // number of materials in mesh
                D3DMATERIAL9*       m_d3d_materials;            // array of materials
                IDirect3DTexture9** m_d3d_textures;             // array of textures

                D3DXMATRIX*         m_matrices;                 
            // bone matrices
                D3DXMATRIX**        m_frame_matrices;           // pointers to frame matrices

                D3DXVECTOR3         m_bound_min, m_bound_max;   
            // bounding box
                float               m_bound_radius;             // bounding sphere radius

                MESH_INFO*          m_next;                     
            // next mesh in list
            } *MESH_INFO_PTR;

            //================================================================================
            // Defines for structure FRAME_INFO.
            //================================================================================
            typedef struct FRAME_INFO
            {
            public:
                
            //------------------------------------------------------------------------------------
                // Constructor, initialize member data.
                //------------------------------------------------------------------------------------
                FRAME_INFO()
                {
                    memset(
            this, 0, sizeof(*this));
                    
                    D3DXMatrixIdentity(&m_mat_combined);
                    D3DXMatrixIdentity(&m_mat_transformed);
                    D3DXMatrixIdentity(&m_mat_original);
                }

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

                
            //------------------------------------------------------------------------------------
                // Find frame information with specified name, call recursively.
                //------------------------------------------------------------------------------------
                FRAME_INFO* find_frame_info(const char* name)
                {        
                    
            // return this instances if name is NULL
                    if(name == NULL)
                        
            return this;

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

                    FRAME_INFO* _frame_info;

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

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

                    
            return NULL;
                }

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

                    
            if(m_child)
                        m_child->reset_matrices();

                    
            if(m_sibling)
                        m_sibling->reset_matrices();
                }

                
            //------------------------------------------------------------------------------------
                // Add mesh information into mesh list.
                //------------------------------------------------------------------------------------
                void add_mesh_info(MESH_INFO* mesh_info)
                {       
                    mesh_info->m_next = m_mesh_info;
                    m_mesh_info       = mesh_info;        
                }

            public:
                
            char*           m_name;

                MESH_INFO_PTR   m_mesh_info;        
            // 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

                FRAME_INFO*     m_parent;           
            // parent frame
                FRAME_INFO*     m_child;            // child frame
                FRAME_INFO*     m_sibling;          // silbling frame
            } *FRAME_INFO_PTR;

            //================================================================================
            // Defines for class MESH.
            //================================================================================
            typedef class MESH
            {
            public:
                MESH();
                ~MESH();

                BOOL is_loaded();

                
            long get_num_frames();
                FRAME_INFO_PTR get_root_frame_info();
                FRAME_INFO_PTR get_frame_info(
            const char* name);

                
            long get_num_meshes();
                MESH_INFO_PTR get_root_mesh_info();
                MESH_INFO_PTR get_mesh_info(
            const 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(
            const char* filename, const char* texture_path);

                
            void free();

            private:
                
            void _parse_xfile_data(ID3DXFileData* _xfile_data, FRAME_INFO_PTR parent_frame_info, const char* texture_path);
                
            void _map_frame_matrix_to_bone(FRAME_INFO_PTR frame_info);

            private:
                
            long            m_num_meshes;           // number of meshes
                MESH_INFO_PTR   m_mesh_info;            // mesh information list

                
            long            m_num_frames;           // number of frames
                FRAME_INFO_PTR  m_frame_info;           // frame information list

                D3DXVECTOR3     m_bound_min;            
            // the lower-left corner of the bounding box
                D3DXVECTOR3     m_bound_max;            // the upper-right corner of the bounding box
                float           m_bound_radius;         // bounding box radius    
            } *MESH_PTR;
             

            實現:
            //-------------------------------------------------------------------
            // Constructor, initialize member data.
            //-------------------------------------------------------------------
            MESH::MESH()
            {   
                memset(
            this, 0, sizeof(*this));    
            }

            //-------------------------------------------------------------------
            // Destructor, release all resources.
            //-------------------------------------------------------------------
            MESH::~MESH()
            {
                free();
            }

            //-------------------------------------------------------------------
            // Release all resources.
            //-------------------------------------------------------------------
            void MESH::free()
            {    
                delete m_mesh_info;
                m_mesh_info = NULL;

                delete m_frame_info;
                m_frame_info = NULL;
            }

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

                
            // error checking
                if(g_d3d_device == 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 information object
                FRAME_INFO_PTR _frame_info = new FRAME_INFO();

                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(_xfile_data, _frame_info, texture_path);

                    release_com(_xfile_data);
                }

                
            // release used COM objects
                release_com(_xfile_enum);
                release_com(_xfile);

                
            // see if we should keep the frame information as root
                if(_frame_info->m_mesh_info != NULL)
                {
                    m_frame_info = _frame_info;

                    m_frame_info->m_name = 
            new char[7];
                    strcpy(m_frame_info->m_name, "%ROOT%");
                }
                
            else
                {
                    
            // Ok, now there is no any mesh in this frame, assign child frame as the root frame and release this frame.

                    m_frame_info = _frame_info->m_child;
                    FRAME_INFO_PTR _frame_info_ptr = m_frame_info;

                    
            // reset all child frames information of this frame, only under one level.
                    while(_frame_info_ptr != NULL)
                    {
                        _frame_info_ptr->m_parent = NULL;
                        _frame_info_ptr = _frame_info_ptr->m_sibling;
                    }

                    _frame_info->m_child = NULL;
                    delete _frame_info;
                }

                
            // map transformed matrix frames to bones
                _map_frame_matrix_to_bone(m_frame_info);

                MESH_INFO_PTR _mesh_info;

                
            // calculate bounding box and sphere
                if((_mesh_info = m_mesh_info) != NULL)
                {        
                    
            while(_mesh_info)
                    {
                        
            // set the lower-left corner of the bounding box as the most lower-left corner 
                        // of all meshes's bounding box
                        m_bound_min.x = min(m_bound_min.x, _mesh_info->m_bound_min.x);
                        m_bound_min.y = min(m_bound_min.y, _mesh_info->m_bound_min.y);
                        m_bound_min.z = min(m_bound_min.z, _mesh_info->m_bound_min.z);            

                        
            // set the upper-right corner of the bounding box as the most upper-right corner 
                        // of all meshes's bounding box
                        m_bound_max.x = max(m_bound_max.x, _mesh_info->m_bound_max.x);
                        m_bound_max.y = max(m_bound_max.y, _mesh_info->m_bound_max.y);
                        m_bound_max.z = max(m_bound_max.z, _mesh_info->m_bound_max.z);

                        
            // set bounding box radius as max radius of all meshes
                        m_bound_radius = max(m_bound_radius, _mesh_info->m_bound_radius);

                        _mesh_info = _mesh_info->m_next;
                    }
                }

                
            return TRUE;
            }

            //-------------------------------------------------------------------
            // Parse specified xfile data, recursive function.
            //-------------------------------------------------------------------
            void MESH::_parse_xfile_data(ID3DXFileData* xfile_data, FRAME_INFO_PTR parent_frame_info, const 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 information pointer
                FRAME_INFO_PTR _current_frame_info = parent_frame_info;

                
            // process the templates

                
            if(_type == TID_D3DRMFrame)  // it's a frame
                {
                    
            // create a new frame information structure
                    FRAME_INFO_PTR _frame_info = new FRAME_INFO();

                    
            // store the name
                    _frame_info->m_name = _name;
                    _name = NULL;
                    
                    
            // link to parent frame
                    _frame_info->m_parent  = parent_frame_info;
                    _frame_info->m_sibling = parent_frame_info->m_child;
                    parent_frame_info->m_child = _frame_info;

                    
            // increase frame count
                    m_num_frames++;

                    
            // set current frame as new frame        
                    _current_frame_info = _frame_info;
                }
                
            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_info->m_mat_original = *_frame_matrix;

                    xfile_data->Unlock();
                }
                
            else if(_type == TID_D3DRMMesh)  // it's a mesh
                {
                    ID3DXBuffer*    _material_buffer = NULL;
                    ID3DXBuffer*    _adjacency = NULL;
                    MESH_INFO*      _mesh_info = NULL;

                    
            // see if mesh already loaded
                    if(m_mesh_info == NULL || m_mesh_info->find_mesh_info(_name) == NULL)
                    {
                        
            // create a new mesh information structure
                        _mesh_info = new MESH_INFO();

                        
            // store the name
                        _mesh_info->m_name = _name;
                        _name = NULL;

                        
            // load mesh data
                        if(FAILED(D3DXLoadSkinMeshFromXof(xfile_data, 0, g_d3d_device, &_adjacency, &_material_buffer, NULL, 
                            &_mesh_info->m_num_materials, &_mesh_info->m_d3d_skin_info, &_mesh_info->m_d3d_mesh)))
                        {
                            delete[] _name;
                            delete _mesh_info;
                            
            return;
                        }
                        
                        BYTE* _ptr;
                        ID3DXMesh* _d3d_mesh      = _mesh_info->m_d3d_mesh;

                        
            // calculate the bounding box and sphere
                        if(SUCCEEDED(_d3d_mesh->LockVertexBuffer(D3DLOCK_READONLY, (void**) &_ptr)))
                        {
                            
            // computes a coordinate-axis oriented bounding box
                            D3DXComputeBoundingBox((D3DXVECTOR3*) _ptr, _d3d_mesh->GetNumVertices(),
                                _d3d_mesh->GetNumBytesPerVertex(), &_mesh_info->m_bound_min, &_mesh_info->m_bound_max);

                            
            // computes a bounding sphere for the mesh
                            D3DXComputeBoundingSphere((D3DXVECTOR3*) _ptr, 
                                _d3d_mesh->GetNumVertices(),_d3d_mesh->GetNumBytesPerVertex(), 
                                &D3DXVECTOR3(0.0f, 0.0f, 0.0f), &_mesh_info->m_bound_radius);

                            _d3d_mesh->UnlockVertexBuffer();
                        }
                        
                        
            // create a matching skinned mesh if bone exist
                        if(_mesh_info->m_d3d_skin_info && _mesh_info->get_num_bones() != 0)
                        {
                            DWORD _num_bones = _mesh_info->get_num_bones();

                            
            // clones a mesh using a flexible vertex format (FVF) code
                            if(FAILED(_d3d_mesh->CloneMeshFVF(0, _d3d_mesh->GetFVF(), g_d3d_device, &_mesh_info->m_d3d_skin_mesh)))
                            {
                                release_com(_mesh_info->m_d3d_skin_info);
                            }
                            
            else    // create an array of matrices to store bone transformations
                            {
                                
            // create the bone matrix array and clear it out
                                _mesh_info->m_matrices = new D3DXMATRIX[_num_bones];

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

                                
            // create the frame matrix pointer array and clear out
                                _mesh_info->m_frame_matrices = new D3DXMATRIX*[_num_bones];

                                
            for(DWORD i = 0; i < _num_bones; i++)
                                    _mesh_info->m_frame_matrices[i] = NULL;
                            }
                        }
                        
                        
            // load materials or create a default one if none
                        if(_mesh_info->m_num_materials == 0)
                        {
                            
            // create a default one
                            _mesh_info->m_d3d_materials = new D3DMATERIAL9[1];
                            _mesh_info->m_d3d_textures  = 
            new LPDIRECT3DTEXTURE9[1];

                            ZeroMemory(_mesh_info->m_d3d_materials, 
            sizeof(D3DMATERIAL9));

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

                            _mesh_info->m_d3d_textures[0] = NULL;

                            _mesh_info->m_num_materials = 1;
                        }   
                        
            else
                        {
                            
            // load the materials
                            D3DXMATERIAL* _x_materials = (D3DXMATERIAL*) _material_buffer->GetBufferPointer();

                            _mesh_info->m_d3d_materials = 
            new D3DMATERIAL9[_mesh_info->m_num_materials];
                            _mesh_info->m_d3d_textures  = 
            new LPDIRECT3DTEXTURE9[_mesh_info->m_num_materials];

                            
            char _path[MAX_PATH];

                            
            for(DWORD i = 0; i < _mesh_info->m_num_materials; i++)
                            {
                                _mesh_info->m_d3d_materials[i] = _x_materials[i].MatD3D;
                                _mesh_info->m_d3d_materials[i].Ambient = _mesh_info->m_d3d_materials[i].Diffuse;

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

                                
            if(FAILED(D3DXCreateTextureFromFile(g_d3d_device, _path, &_mesh_info->m_d3d_textures[i])))
                                    _mesh_info->m_d3d_textures[i] = NULL;
                            }
                        }

                        release_com(_material_buffer);
                        release_com(_adjacency);

                        
            // link to mesh
                        _mesh_info->m_next = m_mesh_info;
                        m_mesh_info = _mesh_info;
                        m_num_meshes++;
                    }
                    
            else
                        
            // Find mesh in list
                        _mesh_info = m_mesh_info->find_mesh_info(_name);

                    
            // add mesh information into frame
                    if(_mesh_info != NULL)
                        _current_frame_info->add_mesh_info(_mesh_info);
                } 
            // 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);

                    
            // parse child _xfile data object
                    _parse_xfile_data(_child_xfile_data, _current_frame_info, texture_path);

                    release_com(_child_xfile_data);
                }
            }

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

                
            // scan through meshes looking for bone matches

                MESH_INFO_PTR _mesh_info = m_mesh_info;

                
            while(_mesh_info != NULL)
                {
                    DWORD _num_bones = _mesh_info->get_num_bones();

                    
            if(_mesh_info->m_d3d_skin_info && _num_bones && _mesh_info->m_frame_matrices)
                    {
                        
            for(DWORD i = 0; i < _num_bones; i++)
                        {
                            
            if(STREQ(frame_info->m_name, _mesh_info->m_d3d_skin_info->GetBoneName(i)))
                            {
                                
            // pointer mesh's frame transform matrix to frame combined matrix
                                _mesh_info->m_frame_matrices[i] = &frame_info->m_mat_combined;
                                
            break;
                            }
                        }
                    }

                    _mesh_info = _mesh_info->m_next;
                }

                
            // scan through child frames    
                _map_frame_matrix_to_bone(frame_info->m_child);

                
            // scan throuogh sibling frames
                _map_frame_matrix_to_bone(frame_info->m_sibling);
            }

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

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

            //-------------------------------------------------------------------
            // Get root frame information.
            //-------------------------------------------------------------------
            FRAME_INFO_PTR MESH::get_root_frame_info()
            {
                
            return m_frame_info;
            }

            //-------------------------------------------------------------------
            // Find frame information with specified name.
            //-------------------------------------------------------------------
            FRAME_INFO_PTR MESH::get_frame_info(const char* name)
            {
                
            if(m_frame_info == NULL)
                    
            return NULL;

                
            return m_frame_info->find_frame_info(name);
            }

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

            //-------------------------------------------------------------------
            // Return root mesh information.
            //-------------------------------------------------------------------
            MESH_INFO_PTR MESH::get_root_mesh_info()
            {
                
            return m_mesh_info;
            }

            //-------------------------------------------------------------------
            // Get mesh information whih spefied name.
            //-------------------------------------------------------------------
            MESH_INFO_PTR MESH::get_mesh_info(const char* name)
            {
                
            if(m_mesh_info == NULL)
                    
            return NULL;

                
            return m_mesh_info->find_mesh_info(name);
            }

            //-------------------------------------------------------------------
            // Get bound box coordinate 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 = m_bound_min.x;
                
            if(min_y != NULL)   *min_y = m_bound_min.y;
                
            if(min_z != NULL)   *min_z = m_bound_min.z;

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

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

            測試代碼:
            /***********************************************************************************
            PURPOSE:
                Test for mesh class.
            ***********************************************************************************/


            #include "core_common.h"
            #include "core_framework.h"
            #include "core_graphics.h"

            class APP : public FRAMEWORK
            {
            public:
                BOOL init()
                {
                    
            // Create Direct3D and Direct3DDevice object
                    if(! create_display(g_hwnd, get_client_width(g_hwnd), get_client_height(g_hwnd), 16, TRUE, FALSE))
                        
            return FALSE;    

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

                    D3DXMATRIX _mat_view;

                    
            // 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));

                    g_d3d_device->SetTransform(D3DTS_VIEW, &_mat_view);

                    
            if(! m_mesh.load("warrior.x", ".\\"))
                        
            return FALSE;            

                    
            return TRUE;
                }

                BOOL frame()
                {
                    clear_display_buffer(D3DCOLOR_RGBA(0, 0, 0, 255));

                    
            if(SUCCEEDED(g_d3d_device->BeginScene()))
                    {
                        D3DXMATRIX _mat_world;

                        
            // create and set the world transformation matrix
                        // rotate object along z-axis
                        D3DXMatrixRotationY(&_mat_world, (float) (timeGetTime() / 1000.0));

                        g_d3d_device->SetTransform(D3DTS_WORLD, &_mat_world);

                        FRAME_INFO_PTR _frame_info = m_mesh.get_root_frame_info();
                        _draw_mesh(_frame_info);        

                        g_d3d_device->EndScene();
                    }

                    present_display();

                    
            return TRUE;
                }

                BOOL shutdown()
                {
                    release_com(g_d3d_device);
                    release_com(g_d3d);

                    
            return TRUE;
                }

            private:
                BOOL _draw_mesh(FRAME_INFO_PTR frame_info)
                {
                    D3DXMATRIX* _matrices = NULL;
                    ID3DXMesh*  _d3d_mesh_to_draw;  
                    MESH_INFO_PTR _mesh_info;
                            
                    
            if(frame_info == NULL)
                        
            return FALSE;

                    
            // draw meshes if any in frame
                    if((_mesh_info = frame_info->m_mesh_info) != NULL)
                    {           
                        
            // setup pointer to d3d mesh to draw
                        _d3d_mesh_to_draw = _mesh_info->m_d3d_mesh;

                        ID3DXMesh* _d3d_mesh = _mesh_info->m_d3d_mesh;
                        ID3DXMesh* _d3d_skin_mesh = _mesh_info->m_d3d_skin_mesh;
                        ID3DXSkinInfo* _d3d_skin_info = _mesh_info->m_d3d_skin_info;

                        
            // generate mesh from skinned mesh to draw with
                        if(_d3d_skin_mesh && _d3d_skin_info)
                        {
                            DWORD _num_bones = _d3d_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_vertices and destination vertex buffers

                            
            void* _source_vertices = NULL;
                            
            void* _dest_vertices = NULL;

                            
            // locks a vertex buffer and obtains a pointer to the vertex buffer memory
                            _d3d_mesh->LockVertexBuffer(0, &_source_vertices);
                            _d3d_skin_mesh->LockVertexBuffer(0, &_dest_vertices);

                            
            // Update skinned mesh, applies software skinning to the target vertices based on the current matrices.
                            _d3d_skin_info->UpdateSkinnedMesh(_matrices, NULL, _source_vertices, _dest_vertices);

                            
            // unlock buffers
                            _d3d_mesh->UnlockVertexBuffer();
                            _d3d_skin_mesh->UnlockVertexBuffer();
                            
                            
            // pointer to skin _mesh_info to draw
                            _d3d_mesh_to_draw = _d3d_skin_mesh;
                        }

                        
            // render the d3d mesh
                        for(DWORD i = 0; i < _mesh_info->get_num_materials(); i++)
                        {
                            
            // set the materials properties for the device            
                            g_d3d_device->SetMaterial(&_mesh_info->m_d3d_materials[i]);

                            
            // assign a texture to a stage for a device
                            g_d3d_device->SetTexture(0, _mesh_info->m_d3d_textures[i]);

                            
            // draw a subset of a _mesh_info
                            _d3d_mesh_to_draw->DrawSubset(i);
                        }

                        
            // free array of _matrices
                        delete[] _matrices;
                        _matrices = NULL;
                    }
                    
                    
            // draw child frames, recursively call.
                    _draw_mesh(frame_info->m_child);

                    
            return TRUE;
                }

            private:
                MESH m_mesh;
            };

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

                
            if(! build_window(inst, "MainClass", "MainWindow", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480))
                    
            return -1;
                
                app.run();

                
            return 0;
            }

            posted on 2007-10-07 19:23 lovedday 閱讀(350) 評論(0)  編輯 收藏 引用

            公告

            導航

            統計

            常用鏈接

            隨筆分類(178)

            3D游戲編程相關鏈接

            搜索

            最新評論

            亚洲综合精品香蕉久久网| 亚洲精品高清国产一久久| 国产成人精品久久亚洲| 久久精品亚洲日本波多野结衣 | 国产精品久久久久久搜索| 久久久久久精品免费看SSS| 一个色综合久久| 日韩亚洲欧美久久久www综合网 | 亚洲婷婷国产精品电影人久久| 99热成人精品免费久久| 91精品国产91热久久久久福利| 99热热久久这里只有精品68| 99热精品久久只有精品| 久久伊人色| 久久WWW免费人成一看片| 久久丫精品国产亚洲av不卡| 99久久精品国内| 久久九色综合九色99伊人| 伊色综合久久之综合久久| 亚洲狠狠婷婷综合久久蜜芽| 99久久精品费精品国产一区二区| 久久国产精品久久精品国产| 久久午夜无码鲁丝片午夜精品| 久久精品免费一区二区| 久久99精品国产麻豆| 精品多毛少妇人妻AV免费久久| 久久这里有精品视频| 国内精品伊人久久久久777| 久久婷婷国产麻豆91天堂| 伊人久久大香线蕉AV一区二区| 奇米综合四色77777久久| 国产精品无码久久四虎| 精产国品久久一二三产区区别| 久久精品国产网红主播| 久久久久国产一区二区三区| 欧美黑人激情性久久| 久久综合色之久久综合| 69久久夜色精品国产69| 久久精品成人欧美大片| 激情综合色综合久久综合| 久久99精品国产麻豆|