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

            天行健 君子當自強而不息

            創建3D圖形引擎(3)【OO改良版】

             

            本篇是創建3D圖形引擎(2)【OO改良版】的續篇,以創建游戲內核【OO改良版】中編寫的代碼為基礎進行開發,細節說明請參閱創建3D圖形引擎(3)

             

            接口:

            /*************************************************************************
            PURPOSE:
                Interface for node tree mesh.
            *************************************************************************/


            #ifndef _NODETREE_H
            #define _NODETREE_H

            #include "core_common.h"

            float closest_height_between_object_and_mesh(LPD3DXBASEMESH mesh, float x_pos, float y_pos, float z_pos);
            float closest_height_below_object(LPD3DXBASEMESH mesh, float x_pos, float y_pos, float z_pos);
            float closest_height_above_object(LPD3DXBASEMESH mesh, float x_pos, float y_pos, float z_pos);

            BOOL is_ray_intersect_mesh(LPD3DXBASEMESH mesh,
                                       
            float x_start, float y_start, float z_start,
                                       
            float x_end, float y_end, float z_end,
                                       
            float* distance);

            BOOL is_tow_sphere_intersect(
            float x_center_1, float y_center_1, float z_center_1,
                                         
            float radius1,
                                         
            float x_center_2, float y_center_2, float z_center_2,
                                         
            float radius2);

            ///////////////////////////////// define for calss NODE_TREE_MESH /////////////////////////////////

            // enumerate the two types of tree structures
            enum TREE_TYPES { QUADTREE = 0, OCTREE };

            //=====================================================================================
            // This calss encapsulate how to divide world space.
            //=====================================================================================
            typedef class NODE_TREE_MESH
            {
            private:    
                
            // The VERTEX_INFO structure is a custom vertex structure than contains only the 3D coordinates.
                // This is used to retrieve coordinate information from a mesh's vertex buffer.
                typedef struct VERTEX
                {
                    
            float x, y, z;
                } *VERTEX_PTR;

                
            // The POLYGON_INFO structure maintains a material group index,
                // the time it was last drawn (so youo don't redraw it many times over per frame),
                // and the three vertices used to render the polygon (which you'll read on later).
                typedef struct POLYGON
                {
                    
            ulong   mg_index;           // material group index
                    ulong   render_timer;

                    
            ushort  vertex_index_0;
                    
            ushort  vertex_index_1;
                    
            ushort  vertex_index_2;

                    POLYGON()
                    {
                        memset(
            this, 0, sizeof(*this));
                    }
                } *POLYGON_PTR;

                
            // The node structure keeps count of the number of polygons in its 3D space, polygon index list,
                // the 3D coordinates of the node (as well as the radius, which is the distance from the center to
                // one edge making the node a perfect cube), and pointers to the child nodes.
                typedef struct NODE
                {
                    
            float       x_pos, y_pos, z_pos;   // center coordinate of node
                    float       diameter;              // diameter of node

                    
            ulong       num_polys;              // number of polygons in node
                    ulong_ptr   poly_index_list;        // polygon index list

                    NODE*       child_nodes[8];         
            // child nodes information 4 = quad, 8 = oct.

                    // constructor used to clear out variables
                    NODE()
                    {
                        memset(
            this, 0, sizeof(*this));
                    }

                    
            // destructor to clear child nodes and variables
                    ~NODE()
                    {
                        delete[] poly_index_list;
                        poly_index_list = NULL;

                        
            // delete child nodes
                        for(short i = 0; i < 8; i++)
                        {
                            delete child_nodes[i];
                            child_nodes[i] = NULL;
                        }
                    }
                } *NODE_PTR;

                
            // The material group structure uses IDirect3DIndexBuffer9 to store polygons vertex index
                // that need to be rendered in a single frame, also it maintains the number of polygons in
                // a material group and how many polygons to draw each frame.
                typedef struct MATERIAL_GROUP
                {
                    
            ulong   num_polys;          // number of polygons in group
                    ulong   num_polys_to_draw;  // number of polygons to draw

                    IDirect3DIndexBuffer9*  index_buffer; 
                    ushort_ptr              index_ptr;

                    
            // clear out member data
                    MATERIAL_GROUP()
                    {
                        memset(
            this, 0, sizeof(*this));
                    }

                    
            // free index buffer
                    ~MATERIAL_GROUP()
                    {
                        
            if(index_buffer)
                            index_buffer->Release();

                        index_buffer = NULL;
                    }
                } *MATERIAL_GROUP_PTR;

            private:
                
            int                 m_tree_type;            // type of nodetree (QUADTREE or OCTREE)

                FRUSTUM_PTR         m_frustum;              
            // viewing frustum

                
            float               m_world_cube_diameter;  // diameter of world cube
                float               m_node_max_diameter;    // maximum node diameter

                NODE_PTR            m_root_node;            
            // node list

                
            ulong               m_num_mg;               // number of material group
                MATERIAL_GROUP_PTR  m_mg_list;              // material group list

                
            ulong               m_max_polys_per_node;   // maximum number of polygons per node allow

                
            ulong               m_num_polys;            // number of polygons in scene
                POLYGON_PTR         m_poly_list;            // list of polygons

                
            ulong               m_render_timer;         // current draw timer

                MESH_INFO_PTR       m_root_mesh_info;       
            // pointer to root mesh
                char_ptr            m_vertex_ptr;           // pointer to mesh vertices
                ulong               m_vertex_fvf;           // mesh vertex FVF
                ulong               m_num_bytes_per_vertex; // num bytes per vertex

            private:
                
            void _sort_node(NODE_PTR node,
                                
            float x_pos, float y_pos, float z_pos,
                                
            float diameter);

                
            void _add_node(NODE_PTR node);

               BOOL _polygon_contain_in_node(POLYGON_PTR poly, 
                                              
            float x_pos, float y_pos, float z_pos,
                                              
            float diameter);

                
            ulong _count_polygons_in_node(float x_pos, float y_pos, float z_pos,
                                              
            float diameter);

            public:
               NODE_TREE_MESH();
               ~NODE_TREE_MESH();

               BOOL create(MESH_PTR mesh,
                           
            int tree_type, float node_max_diameter, long max_polys_per_node);

               
            void free();

               BOOL render(FRUSTUM_PTR frustum, 
            float z_dist);

               
            float closest_height_between_object_and_mesh(float x_pos, float y_pos, float z_pos);
               
            float closest_height_below_object(float x_pos, float y_pos, float z_pos);
               
            float closest_height_above_object(float x_pos, float y_pos, float z_pos);

               BOOL is_ray_intersect_mesh(
            float x_start, float y_start, float z_start,
                                          
            float x_end, float y_end, float z_end,
                                          
            float* distance);    
            } *NODE_TREE_MESH_PTR;

            #endif

            實現:

            /*************************************************************************
            PURPOSE:
                Implement for node tree mesh.
            *************************************************************************/


            #include "core_common.h"
            #include "core_graphics.h"
            #include "frustum.h"
            #include "node_tree_mesh.h"

            //------------------------------------------------------------------------------
            // Get closest height above or below point.
            //------------------------------------------------------------------------------
            float closest_height_between_object_and_mesh(LPD3DXBASEMESH mesh, float x_pos, float y_pos, float z_pos)
            {
                
            float y_above, y_below;

                y_above = closest_height_above_object(mesh, x_pos, y_pos, z_pos);
                y_below = closest_height_below_object(mesh, x_pos, y_pos, z_pos);

                
            if(fabs(y_above - y_pos) < fabs(y_below - y_pos))
                    
            return y_above;

                
            return y_below;
            }

            //------------------------------------------------------------------------------
            // Get closet height below point.
            //------------------------------------------------------------------------------
            float closest_height_below_object(LPD3DXBASEMESH mesh, float x_pos, float y_pos, float z_pos)
            {
                BOOL is_hit;
                
            float u, v, dist;
                DWORD face_index;

                D3DXVECTOR3 ray_pos(x_pos, y_pos, z_pos);
                D3DXVECTOR3 ray_dir(0.0f, -1.0f, 0.0f);

                D3DXIntersect(mesh, &ray_pos, &ray_dir, &is_hit, &face_index, &u, &v, &dist, NULL, NULL);

                
            if(is_hit)
                    
            return y_pos - dist;

                
            return y_pos;
            }

            //------------------------------------------------------------------------------
            // Get closet height above point.
            //------------------------------------------------------------------------------
            float closest_height_above_object(LPD3DXBASEMESH mesh, float x_pos, float y_pos, float z_pos)
            {
                BOOL is_hit;
                
            float u, v, dist;
                DWORD face_index;

                D3DXVECTOR3 ray_pos(x_pos, y_pos, z_pos);
                D3DXVECTOR3 ray_dir(0.0f, 1.0f, 0.0f);

                D3DXIntersect(mesh, &ray_pos, &ray_dir, &is_hit, &face_index, &u, &v, &dist, NULL, NULL);

                
            if(is_hit)
                    
            return y_pos + dist;

                
            return y_pos;
            }

            //------------------------------------------------------------------------------
            // Check if a polygon blocks path from start to end.
            //------------------------------------------------------------------------------
            BOOL is_ray_intersect_mesh(LPD3DXBASEMESH mesh,
                                       
            float x_start, float y_start, float z_start,
                                       
            float x_end, float y_end, float z_end,
                                       
            float* distance)
            {
                
            float x_diff, y_diff, z_diff;

                x_diff = x_end - x_start;
                y_diff = y_end - y_start;
                z_diff = z_end - z_start;

                D3DXVECTOR3 ray_pos(x_start, y_start, z_start);

                D3DXVECTOR3 ray_dir;
                D3DXVec3Normalize(&ray_dir, &D3DXVECTOR3(x_diff, y_diff, z_diff));

                BOOL is_hit;
                
            float u, v, dist;
                DWORD face_index;

                
            // determins if a ray intersects with a mesh
                D3DXIntersect(mesh, &ray_pos, &ray_dir, &is_hit, &face_index, &u, &v, &dist, NULL, NULL);

                
            if(is_hit)
                {
                    
            float ray_length = (float) sqrt(x_diff * x_diff + y_diff * y_diff + z_diff * z_diff);

                    
            if(dist > ray_length)
                        
            return FALSE;
                    
            else
                    {
                        
            if(distance != NULL)
                            *distance = dist;
                    }
                }

                
            return TRUE;
            }

            //------------------------------------------------------------------------------
            // Check if two spheres intersect.
            //------------------------------------------------------------------------------
            BOOL is_tow_sphere_intersect(float x_center_1, float y_center_1, float z_center_1,
                                         
            float radius1,
                                         
            float x_center_2, float y_center_2, float z_center_2,
                                         
            float radius2)
            {
                
            float x_diff, y_diff, z_diff, dist;
                
                
            // calculate distance between two sphere center]
                
                x_diff = fabs(x_center_2 - x_center_1);
                y_diff = fabs(y_center_2 - y_center_1);
                z_diff = fabs(z_center_2 - z_center_1);

                dist = (
            float) sqrt(x_diff * x_diff + y_diff * y_diff + z_diff * z_diff); 

                
            // if two spheres intersect, retuen TRUE.
                if(dist <= radius1 + radius2)
                    
            return TRUE;

                
            return FALSE;
            }

            //------------------------------------------------------------------------------
            // Groups the polygons into nodes and splits the nodes into child nodes as needed.
            //------------------------------------------------------------------------------
            void NODE_TREE_MESH::_sort_node(NODE_PTR node,
                                            
            float x_pos, float y_pos, float z_pos,
                                            
            float diameter)
            {
                
            // error checking
                if(node == NULL)
                    
            return;

                
            // store node coordinates and size
                node->x_pos    = x_pos;
                node->y_pos    = (m_tree_type == QUADTREE) ? 0.0f : y_pos;
                node->z_pos    = z_pos;
                node->diameter = diameter;

                
            ulong num_polys_in_node;

                
            // see if there are any polygons in the node
                if((num_polys_in_node = _count_polygons_in_node(x_pos, y_pos, z_pos, diameter)) == 0)
                   
            return;

                
            // split node if diameter > m_node_max_diameter and too many polygons
                if(diameter > m_node_max_diameter && num_polys_in_node > m_max_polys_per_node)
                {
                    
            ulong divide_node_num = (m_tree_type == QUADTREE) ? 4 : 8;

                    
            for(ulong i = 0; i < divide_node_num; i++)
                    {
                        
            float x_off = (((i % 2) < 1) ? -1.0f : 1.0f) * (diameter / 4);
                        
            float z_off = (((i % 4) < 2) ? -1.0f : 1.0f) * (diameter / 4);
                        
            float y_off = (((i % 8) < 4) ? -1.0f : 1.0f) * (diameter / 4);

                        
            // see if any polygons in new node boudning box
                        if(_count_polygons_in_node(x_pos + x_off, y_pos + y_off, z_pos + z_off, diameter / 2))
                        {
                            node->child_nodes[i] = 
            new NODE;    // create new child node

                            // sort the polygons with the new child node
                            _sort_node(node->child_nodes[i], x_pos + x_off, y_pos + y_off, z_pos + z_off, diameter / 2);
                        }
                    }

                    
            return;
                }

                
            // allocate space for vertex index
                node->num_polys       = num_polys_in_node;
                node->poly_index_list = 
            new ulong[num_polys_in_node];

                
            // scan through polygon list, storing polygon index and assiging them.

                
            ulong poly_index = 0;

                
            for(ulong i = 0; i < m_num_polys; i++)
                {
                    
            // add polygon to node list if contained in 3D space
                    if(_polygon_contain_in_node(&m_poly_list[i], x_pos, y_pos, z_pos, diameter))
                        node->poly_index_list[poly_index++] = i;
                }
            }

            //------------------------------------------------------------------------------
            // Check whether polygon is in node.
            //------------------------------------------------------------------------------
            BOOL NODE_TREE_MESH::_polygon_contain_in_node(POLYGON_PTR poly, 
                                                          
            float x_pos, float y_pos, float z_pos,
                                                          
            float diameter)
            {
                
            // get the polygon's vertices

                VERTEX_PTR vertex[3];

                vertex[0] = (VERTEX_PTR) &m_vertex_ptr[m_num_bytes_per_vertex * poly->vertex_index_0];
                vertex[1] = (VERTEX_PTR) &m_vertex_ptr[m_num_bytes_per_vertex * poly->vertex_index_1];
                vertex[2] = (VERTEX_PTR) &m_vertex_ptr[m_num_bytes_per_vertex * poly->vertex_index_2];

                
            float x_min, x_max, y_min, y_max, z_min, z_max;

                
            // check against x axis of specified 3D space
                
                x_min = min(vertex[0]->x, min(vertex[1]->x, vertex[2]->x));
                x_max = max(vertex[0]->x, max(vertex[1]->x, vertex[2]->x));

                
            if(x_max < (x_pos - diameter / 2))
                    
            return FALSE;

                
            if(x_min >  (x_pos + diameter / 2))
                    
            return FALSE;

                
            // check against y axis of specified 3D space (only if octree tree type)
                if(m_tree_type == OCTREE)
                {
                    y_min = min(vertex[0]->y, min(vertex[1]->y, vertex[2]->y));
                    y_max = max(vertex[0]->y, max(vertex[1]->y, vertex[2]->y));

                    
            if(y_max < (y_pos - diameter / 2))
                        
            return FALSE;

                    
            if(y_min >  (y_pos + diameter / 2))
                        
            return FALSE;
                }

                
            // check against z axis of specified 3D space

                z_min = min(vertex[0]->z, min(vertex[1]->z, vertex[2]->z));
                z_max = max(vertex[0]->z, max(vertex[1]->z, vertex[2]->z));

                
            if(z_max < (z_pos - diameter / 2))
                    
            return FALSE;

                
            if(z_min >  (z_pos + diameter / 2))
                    
            return FALSE;

                
            return TRUE;
            }

            //------------------------------------------------------------------------------
            // Count the number of polygons in node.
            //------------------------------------------------------------------------------
            ulong NODE_TREE_MESH::_count_polygons_in_node(float x_pos, float y_pos, float z_pos,
                                                          
            float diameter)
            {
                
            // return if no polygons to process
                if(m_num_polys == 0)
                    
            return 0;

                
            // go through every polygon and keep count of those contained in the specified 3D space.

                
            ulong poly_num_in_node = 0;

                
            for(ulong i = 0; i < m_num_polys; i++)
                {
                    
            if(_polygon_contain_in_node(&m_poly_list[i], x_pos, y_pos, z_pos, diameter))
                        poly_num_in_node++;
                }

                
            return poly_num_in_node;
            }

            //------------------------------------------------------------------------------
            // Adds a node into the list of nodes to draw.
            //------------------------------------------------------------------------------
            void NODE_TREE_MESH::_add_node(NODE_PTR node)
            {
                
            if(node == NULL)
                    
            return;

                
            // perform frustum check based on tree type

                
            float y_pos;

                
            if(m_tree_type == QUADTREE)
                    y_pos = 0.0f;
                
            else
                    y_pos = node->y_pos;

                
            float node_radius = node->diameter / 2;
                BOOL  is_completely_contained = FALSE;

                
            if(! m_frustum->is_rectangle_in(node->x_pos, y_pos, node->z_pos, 
                                                node_radius, node_radius, node_radius,
                                                &is_completely_contained))
                {
                    
            return;
                }

                
            if(! is_completely_contained)
                {
                    
            // scan child nodes

                    
            short num = 0;
                    
            ulong child_nodes_num = (m_tree_type == QUADTREE) ? 4 : 8;

                    
            for(ulong i = 0; i < child_nodes_num; i++)
                    {
                        
            if(node->child_nodes[i])
                        {
                            num++;
                            _add_node(node->child_nodes[i]);
                        }
                    }

                    
            // do not need to go on if there was child nodes in this node
                    if(num != 0)
                        
            return;
                }

                
            // add contained polygons (if any)
                if(node->num_polys != 0)
                {
                    
            for(ulong i = 0; i < node->num_polys; i++)
                    {
                        
            ulong poly_index = node->poly_index_list[i];

                        
            // get pointer to polygon
                        POLYGON_PTR poly = &m_poly_list[poly_index];

                        
            // only draw if not done already 
                        if(poly->render_timer != m_render_timer)
                        {
                            poly->render_timer = m_render_timer;

                            
            // get material group index of polygon
                            ulong mg_index = poly->mg_index;

                            
            // make sure group is okay and material is not transparent
                            if(mg_index < m_num_mg && m_root_mesh_info->m_d3d_materials[mg_index].Diffuse.a != 0.0f)
                            {
                                
            // copy polygon's vertex indices into index buffer
                                *m_mg_list[mg_index].index_ptr++ = poly->vertex_index_0;
                                *m_mg_list[mg_index].index_ptr++ = poly->vertex_index_1;
                                *m_mg_list[mg_index].index_ptr++ = poly->vertex_index_2;

                                
            // increase count of polygons to draw in group
                                m_mg_list[mg_index].num_polys_to_draw++;
                            }
                        }
                    }
                }
            }

            //------------------------------------------------------------------------------
            // Constructor, initialize member data.
            //------------------------------------------------------------------------------
            NODE_TREE_MESH::NODE_TREE_MESH()
            {
                memset(
            this, 0, sizeof(*this));

                m_tree_type = OCTREE;
            }

            //------------------------------------------------------------------------------
            // Destructor, release allocated memory.
            //------------------------------------------------------------------------------
            NODE_TREE_MESH::~NODE_TREE_MESH()
            {
                free();
            }

            //------------------------------------------------------------------------------
            // Release allocated memory.
            //------------------------------------------------------------------------------
            void NODE_TREE_MESH::free()
            {
                delete m_root_node;
                m_root_node = NULL;

                m_num_polys = 0;
                delete[] m_poly_list;
                m_poly_list = NULL;

                m_num_mg = 0;
                delete[] m_mg_list;
                m_mg_list = NULL;
            }

            //------------------------------------------------------------------------------
            // Create a node-tree mesh from a source MESH object and free old node-tree mesh, 
            // specifying the maximum number of polygons in an area than the specific size 
            // which forcing node splits.
            //------------------------------------------------------------------------------
            BOOL NODE_TREE_MESH::create(MESH_PTR mesh,
                                        
            int tree_type, float node_max_diameter, long max_polys_per_node)
            {
                
            // free a prior mesh
                free();

                
            // error checking    
                if(g_d3d_device == NULL || mesh == NULL || mesh->get_root_mesh_info()->m_num_materials == 0)
                    
            return FALSE;

                
            // get mesh information

                m_root_mesh_info = mesh->get_root_mesh_info();
                ID3DXMesh* d3d_mesh = m_root_mesh_info->m_d3d_mesh;

                m_vertex_fvf           = d3d_mesh->GetFVF();
                m_num_bytes_per_vertex = D3DXGetFVFVertexSize(m_vertex_fvf);
                m_num_polys            = d3d_mesh->GetNumFaces();
                m_max_polys_per_node   = max_polys_per_node;

                
            // create the polygon list and group
                m_poly_list = new POLYGON[m_num_polys];
                m_num_mg    = m_root_mesh_info->m_num_materials;
                m_mg_list   = 
            new MATERIAL_GROUP[m_num_mg];

                ushort_ptr  index_ptr;
                ulong_ptr   attr_list;

                
            // lock the index and attribute buffers
                d3d_mesh->LockIndexBuffer(D3DLOCK_READONLY, (void**)&index_ptr);
                d3d_mesh->LockAttributeBuffer(D3DLOCK_READONLY, &attr_list);

                
            // load polygon information into structures
                for(ulong i = 0; i < m_num_polys; i++)
                {
                    
            ulong mg_index = attr_list[i];  // material group index

                    m_poly_list[i].vertex_index_0 = *index_ptr++;
                    m_poly_list[i].vertex_index_1 = *index_ptr++;
                    m_poly_list[i].vertex_index_2 = *index_ptr++;
                    m_poly_list[i].mg_index       = mg_index;
                    m_poly_list[i].render_timer   = 0;
                            
                    m_mg_list[mg_index].num_polys++;
                }

                
            // unlock buffers
                d3d_mesh->UnlockAttributeBuffer();
                d3d_mesh->UnlockIndexBuffer();

                
            // build the group vertex index buffers
                for(ulong i = 0; i < m_num_mg; i++)
                {
                    
            if(m_mg_list[i].num_polys != 0)
                    {
                        UINT index_buffer_length = m_mg_list[i].num_polys * 3 * 
            sizeof(ushort);

                        g_d3d_device->CreateIndexBuffer(index_buffer_length, D3DUSAGE_WRITEONLY,
                            D3DFMT_INDEX16, D3DPOOL_MANAGED, &m_mg_list[i].index_buffer, NULL);
                    }
                }

                
            // get the size of the bounding cube

                
            float bound_max_x, bound_max_y, bound_max_z;

                bound_max_x = (
            float) max(fabs(m_root_mesh_info->m_bound_min.x), fabs(m_root_mesh_info->m_bound_max.x));
                bound_max_y = (
            float) max(fabs(m_root_mesh_info->m_bound_min.y), fabs(m_root_mesh_info->m_bound_max.y));
                bound_max_z = (
            float) max(fabs(m_root_mesh_info->m_bound_min.z), fabs(m_root_mesh_info->m_bound_max.z));

                m_world_cube_diameter = max(bound_max_x, max(bound_max_y, bound_max_z)) * 2.0f;
                m_node_max_diameter   = node_max_diameter;

                
            // create the root node
                m_root_node = new NODE;

                
            // sort polygons into nodes

                d3d_mesh->LockVertexBuffer(D3DLOCK_READONLY, (
            void**)&m_vertex_ptr);

                _sort_node(m_root_node, 0.0f, 0.0f, 0.0f, m_world_cube_diameter);

                d3d_mesh->UnlockVertexBuffer();

                m_render_timer = 0;

                
            return TRUE;
            }

            //------------------------------------------------------------------------------
            // Render the current view using view transformation and overloaded distance of view.
            // Also specify to use a pre-calculate frustum or force a calculation of own frustum.
            //------------------------------------------------------------------------------
            BOOL NODE_TREE_MESH::render(FRUSTUM_PTR frustum, float z_dist)
            {
                
            // error checking
                if(g_d3d_device == NULL || m_root_node == NULL || m_num_polys == 0)
                    
            return FALSE;

                
            // construct the viewing frustum (if none passed)
                if((m_frustum = frustum) == NULL)
                {
                    FRUSTUM view_frustum;  
            // local viewing frustumn
                    view_frustum.create(z_dist);

                    m_frustum = &view_frustum;
                }

                D3DXMATRIX matrix;   
            // matrix used for calculations

                // set the world transformation matrix to identity,
                // so that level mesh is rendered around the origin it was disigned.
                D3DXMatrixIdentity(&matrix);
                g_d3d_device->SetTransform(D3DTS_WORLD, &matrix);

                
            // lock material group index buffer
                for(ulong i = 0; i < m_num_mg; i++)
                {
                    
            if(m_mg_list[i].num_polys != 0)
                    {
                        UINT total_vert_index_size = m_mg_list[i].num_polys * 3 * 
            sizeof(ushort);

                        m_mg_list[i].index_buffer->Lock(0, total_vert_index_size, (
            void**) &m_mg_list[i].index_ptr, 0);
                    }       

                    m_mg_list[i].num_polys_to_draw = 0;
                }

                
            // increase render frame timer
                m_render_timer++;

                
            // add polygons to be drawn into material group list
                _add_node(m_root_node);

                IDirect3DVertexBuffer9* vertex_buffer = NULL;

                
            // get vertex buffer pointer
                m_root_mesh_info->m_d3d_mesh->GetVertexBuffer(&vertex_buffer);

                
            // set vertex shader and source
                g_d3d_device->SetStreamSource(0, vertex_buffer, 0, m_num_bytes_per_vertex);
                g_d3d_device->SetFVF(m_vertex_fvf);  

                UINT num_vertices = m_root_mesh_info->m_d3d_mesh->GetNumVertices();

                
            // unlock vertex buffers and draw
                for(ulong i = 0; i < m_num_mg; i++)
                {
                    
            if(m_mg_list[i].num_polys != 0)
                        m_mg_list[i].index_buffer->Unlock();

                    
            if(m_mg_list[i].num_polys_to_draw != 0)
                    {
                        UINT num_polys_to_draw = m_mg_list[i].num_polys_to_draw;

                        g_d3d_device->SetMaterial(&m_root_mesh_info->m_d3d_materials[i]);
                        g_d3d_device->SetTexture(0, m_root_mesh_info->m_d3d_textures[i]);
                        g_d3d_device->SetIndices(m_mg_list[i].index_buffer);
                        g_d3d_device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, num_vertices, 0, num_polys_to_draw);
                    }
                }

                
            // release vertex buffer
                if(vertex_buffer)
                    vertex_buffer->Release();

                
            return TRUE;
            }

            //------------------------------------------------------------------------------
            // Get closest height above or below point.
            //------------------------------------------------------------------------------
            float NODE_TREE_MESH::closest_height_between_object_and_mesh(float x_pos, float y_pos, float z_pos)
            {
                
            return ::closest_height_between_object_and_mesh(m_root_mesh_info->m_d3d_mesh, x_pos, y_pos, z_pos);
            }

            //------------------------------------------------------------------------------
            // Get closest height below point.
            //------------------------------------------------------------------------------
            float NODE_TREE_MESH::closest_height_below_object(float x_pos, float y_pos, float z_pos)
            {
                
            return ::closest_height_below_object(m_root_mesh_info->m_d3d_mesh, x_pos, y_pos, z_pos);
            }

            //------------------------------------------------------------------------------
            // Get closest height above point.
            //------------------------------------------------------------------------------
            float NODE_TREE_MESH::closest_height_above_object(float x_pos, float y_pos, float z_pos)
            {
                
            return ::closest_height_above_object(m_root_mesh_info->m_d3d_mesh, x_pos, y_pos, z_pos);
            }

            //------------------------------------------------------------------------------
            // Check if a polygon blocks path from start to end.
            //------------------------------------------------------------------------------
            BOOL NODE_TREE_MESH::is_ray_intersect_mesh(float x_start, float y_start, float z_start,
                                                 
            float x_end, float y_end, float z_end,
                                                 
            float* distance)
            {
                
            return ::is_ray_intersect_mesh(m_root_mesh_info->m_d3d_mesh, 
                                               x_start, y_start, z_start,
                                               x_end, y_end, z_end,
                                               distance);
            }
             

            posted on 2007-10-25 14:41 lovedday 閱讀(350) 評論(0)  編輯 收藏 引用

            公告

            導航

            統計

            常用鏈接

            隨筆分類(178)

            3D游戲編程相關鏈接

            搜索

            最新評論

            久久精品国产69国产精品亚洲| 91麻豆精品国产91久久久久久| 2020最新久久久视精品爱| 偷窥少妇久久久久久久久| 777米奇久久最新地址| 久久露脸国产精品| 色综合久久中文字幕无码| 99久久久久| 精品久久久久久99人妻| 久久夜色精品国产噜噜亚洲AV| 久久精品国产半推半就| 国产精品久久久福利| 99久久综合国产精品二区| 亚洲中文久久精品无码ww16| 国产福利电影一区二区三区久久久久成人精品综合 | 久久亚洲AV无码精品色午夜| 亚洲AⅤ优女AV综合久久久| 久久国产热精品波多野结衣AV | 久久99精品久久久久久hb无码 | 99久久综合狠狠综合久久止| 国产精品久久久久天天影视| 久久精品男人影院| 久久精品国产一区二区| 国产亚洲精品美女久久久| 久久综合九色综合97_久久久| 亚洲av日韩精品久久久久久a| 久久精品人人做人人妻人人玩| 久久综合九色综合网站| 国产亚州精品女人久久久久久 | 久久精品人人做人人爽电影| 国产成人精品久久一区二区三区av | 久久久WWW成人免费毛片| 中文国产成人精品久久亚洲精品AⅤ无码精品| 久久亚洲精品无码AV红樱桃| 久久99精品国产| 一本久久免费视频| 国产精品久久精品| 超级碰碰碰碰97久久久久| 色综合久久天天综合| 亚洲综合伊人久久综合| 三级片免费观看久久|