⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 t3dlib8.cpp

📁 3D游戏编程大师技巧第十章的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
              vertex_ccodes[2] = CLIP_CODE_GZ;
              } 
           else
           if (curr_poly->tvlist[2].z < cam->near_clip_z)
              {
              vertex_ccodes[2] = CLIP_CODE_LZ;
              }
           else
              {
              vertex_ccodes[2] = CLIP_CODE_IZ;
              num_verts_in++;
              } 
           
          // test for trivial rejections, polygon completely beyond far or near
          // z clipping planes
          if ( ((vertex_ccodes[0] == CLIP_CODE_GZ) && 
                (vertex_ccodes[1] == CLIP_CODE_GZ) && 
                (vertex_ccodes[2] == CLIP_CODE_GZ) ) ||

               ((vertex_ccodes[0] == CLIP_CODE_LZ) && 
                (vertex_ccodes[1] == CLIP_CODE_LZ) && 
                (vertex_ccodes[2] == CLIP_CODE_LZ) ) )

             {
             // clip the poly completely out of frustrum
             SET_BIT(curr_poly->state, POLY4DV2_STATE_CLIPPED);
             
             // move on to next polygon
             continue;
             } // end if

          // test if any vertex has protruded beyond near clipping plane?
          if ( ( (vertex_ccodes[0] | vertex_ccodes[1] | vertex_ccodes[2]) & CLIP_CODE_LZ) )
          {
          // at this point we are ready to clip the polygon to the near 
          // clipping plane no need to clip to the far plane since it can't 
          // possible cause problems. We have two cases: case 1: the triangle 
          // has 1 vertex interior to the near clipping plane and 2 vertices 
          // exterior, OR case 2: the triangle has two vertices interior of 
          // the near clipping plane and 1 exterior

          // step 1: classify the triangle type based on number of vertices
          // inside/outside
          // case 1: easy case :)
          if (num_verts_in == 1)
             {
             // we need to clip the triangle against the near clipping plane
             // the clipping procedure is done to each edge leading away from
             // the interior vertex, to clip we need to compute the intersection
             // with the near z plane, this is done with a parametric equation of 
             // the edge, once the intersection is computed the old vertex position
             // is overwritten along with re-computing the texture coordinates, if
             // there are any, what's nice about this case, is clipping doesn't 
             // introduce any added vertices, so we can overwrite the old poly
             // the other case below results in 2 polys, so at very least one has
             // to be added to the end of the rendering list -- bummer
 
             // step 1: find vertex index for interior vertex
             if ( vertex_ccodes[0] == CLIP_CODE_IZ)
                { v0 = 0; v1 = 1; v2 = 2; }
             else 
             if (vertex_ccodes[1] == CLIP_CODE_IZ)
                { v0 = 1; v1 = 2; v2 = 0; }
             else
                { v0 = 2; v1 = 0; v2 = 1; }

            // step 2: clip each edge
            // basically we are going to generate the parametric line p = v0 + v01*t
            // then solve for t when the z component is equal to near z, then plug that
            // back into to solve for x,y of the 3D line, we could do this with high
            // level code and parametric lines, but to save time, lets do it manually

            // clip edge v0->v1
            VECTOR4D_Build(&curr_poly->tvlist[v0].v, &curr_poly->tvlist[v1].v, &v);                          

            // the intersection occurs when z = near z, so t = 
            t1 = ( (cam->near_clip_z - curr_poly->tvlist[v0].z) / v.z );
      
            // now plug t back in and find x,y intersection with the plane
            xi = curr_poly->tvlist[v0].x + v.x * t1;
            yi = curr_poly->tvlist[v0].y + v.y * t1;

            // now overwrite vertex with new vertex
            curr_poly->tvlist[v1].x = xi;
            curr_poly->tvlist[v1].y = yi;
            curr_poly->tvlist[v1].z = cam->near_clip_z; 
         
            // clip edge v0->v2
            VECTOR4D_Build(&curr_poly->tvlist[v0].v, &curr_poly->tvlist[v2].v, &v);                          

            // the intersection occurs when z = near z, so t = 
            t2 = ( (cam->near_clip_z - curr_poly->tvlist[v0].z) / v.z );
      
            // now plug t back in and find x,y intersection with the plane
            xi = curr_poly->tvlist[v0].x + v.x * t2;
            yi = curr_poly->tvlist[v0].y + v.y * t2;

            // now overwrite vertex with new vertex
            curr_poly->tvlist[v2].x = xi;
            curr_poly->tvlist[v2].y = yi;
            curr_poly->tvlist[v2].z = cam->near_clip_z; 

            // now that we have both t1, t2, check if the poly is textured, if so clip
            // texture coordinates
            if (curr_poly->attr & POLY4DV2_ATTR_SHADE_MODE_TEXTURE)
               {
               ui = curr_poly->tvlist[v0].u0 + (curr_poly->tvlist[v1].u0 - curr_poly->tvlist[v0].u0)*t1;
               vi = curr_poly->tvlist[v0].v0 + (curr_poly->tvlist[v1].v0 - curr_poly->tvlist[v0].v0)*t1;
               curr_poly->tvlist[v1].u0 = ui;
               curr_poly->tvlist[v1].v0 = vi;

               ui = curr_poly->tvlist[v0].u0 + (curr_poly->tvlist[v2].u0 - curr_poly->tvlist[v0].u0)*t2;
               vi = curr_poly->tvlist[v0].v0 + (curr_poly->tvlist[v2].v0 - curr_poly->tvlist[v0].v0)*t2;
               curr_poly->tvlist[v2].u0 = ui;
               curr_poly->tvlist[v2].v0 = vi;
               } // end if textured

               // finally, we have obliterated our pre-computed normal length
               // it needs to be recomputed!!!!
 
              // build u, v
              VECTOR4D_Build(&curr_poly->tvlist[v0].v, &curr_poly->tvlist[v1].v, &u);
              VECTOR4D_Build(&curr_poly->tvlist[v0].v, &curr_poly->tvlist[v2].v, &v);

              // compute cross product
              VECTOR4D_Cross(&u, &v, &n);

              // compute length of normal accurately and store in poly nlength
              // +- epsilon later to fix over/underflows
              curr_poly->nlength = VECTOR4D_Length_Fast(&n); 

             } // end if
          else
          if (num_verts_in == 2)
             { // num_verts = 2

             // must be the case with num_verts_in = 2 
             // we need to clip the triangle against the near clipping plane
             // the clipping procedure is done to each edge leading away from
             // the interior vertex, to clip we need to compute the intersection
             // with the near z plane, this is done with a parametric equation of 
             // the edge, however unlike case 1 above, the triangle will be split
             // into two triangles, thus during the first clip, we will store the 
             // results into a new triangle at the end of the rendering list, and 
             // then on the last clip we will overwrite the triangle being clipped

             // step 0: copy the polygon
             memcpy(&temp_poly, curr_poly, sizeof(POLYF4DV2) );

             // step 1: find vertex index for exterior vertex
             if ( vertex_ccodes[0] == CLIP_CODE_LZ)
                { v0 = 0; v1 = 1; v2 = 2; }
             else 
             if (vertex_ccodes[1] == CLIP_CODE_LZ)
                { v0 = 1; v1 = 2; v2 = 0; }
             else
                { v0 = 2; v1 = 0; v2 = 1; }

             // step 2: clip each edge
             // basically we are going to generate the parametric line p = v0 + v01*t
             // then solve for t when the z component is equal to near z, then plug that
             // back into to solve for x,y of the 3D line, we could do this with high
             // level code and parametric lines, but to save time, lets do it manually

             // clip edge v0->v1
             VECTOR4D_Build(&curr_poly->tvlist[v0].v, &curr_poly->tvlist[v1].v, &v);                          

             // the intersection occurs when z = near z, so t = 
             t1 = ( (cam->near_clip_z - curr_poly->tvlist[v0].z) / v.z );
      
             // now plug t back in and find x,y intersection with the plane
             x01i = curr_poly->tvlist[v0].x + v.x * t1;
             y01i = curr_poly->tvlist[v0].y + v.y * t1;
         
             // clip edge v0->v2
             VECTOR4D_Build(&curr_poly->tvlist[v0].v, &curr_poly->tvlist[v2].v, &v);                          

             // the intersection occurs when z = near z, so t = 
             t2 = ( (cam->near_clip_z - curr_poly->tvlist[v0].z) / v.z );
      
             // now plug t back in and find x,y intersection with the plane
             x02i = curr_poly->tvlist[v0].x + v.x * t2;
             y02i = curr_poly->tvlist[v0].y + v.y * t2; 

             // now we have both intersection points, we must overwrite the inplace
             // polygon's vertex 0 with the intersection point, this poly 1 of 2 from
             // the split

             // now overwrite vertex with new vertex
             curr_poly->tvlist[v0].x = x01i;
             curr_poly->tvlist[v0].y = y01i;
             curr_poly->tvlist[v0].z = cam->near_clip_z; 

             // now comes the hard part, we have to carefully create a new polygon
             // from the 2 intersection points and v2, this polygon will be inserted
             // at the end of the rendering list, but for now, we are building it up
             // in  temp_poly

             // so leave v2 alone, but overwrite v1 with v01, and overwrite v0 with v02
             temp_poly.tvlist[v1].x = x01i;
             temp_poly.tvlist[v1].y = y01i;
             temp_poly.tvlist[v1].z = cam->near_clip_z;              

             temp_poly.tvlist[v0].x = x02i;
             temp_poly.tvlist[v0].y = y02i;
             temp_poly.tvlist[v0].z = cam->near_clip_z;    

            // now that we have both t1, t2, check if the poly is textured, if so clip
            // texture coordinates
            if (curr_poly->attr & POLY4DV2_ATTR_SHADE_MODE_TEXTURE)
               {
               // compute poly 1 new texture coordinates from split
               u01i = curr_poly->tvlist[v0].u0 + (curr_poly->tvlist[v1].u0 - curr_poly->tvlist[v0].u0)*t1;
               v01i = curr_poly->tvlist[v0].v0 + (curr_poly->tvlist[v1].v0 - curr_poly->tvlist[v0].v0)*t1;

               // compute poly 2 new texture coordinates from split
               u02i = curr_poly->tvlist[v0].u0 + (curr_poly->tvlist[v2].u0 - curr_poly->tvlist[v0].u0)*t2;
               v02i = curr_poly->tvlist[v0].v0 + (curr_poly->tvlist[v2].v0 - curr_poly->tvlist[v0].v0)*t2;

               // write them all at the same time         
               // poly 1
               curr_poly->tvlist[v0].u0 = u01i;
               curr_poly->tvlist[v0].v0 = v01i;

               // poly 2
               temp_poly.tvlist[v0].u0 = u02i;
               temp_poly.tvlist[v0].v0 = v02i;
               temp_poly.tvlist[v1].u0 = u01i;
               temp_poly.tvlist[v1].v0 = v01i;

               } // end if textured


               // finally, we have obliterated our pre-computed normal lengths
               // they need to be recomputed!!!!
 
               // poly 1 first, in place
 
               // build u, v
               VECTOR4D_Build(&curr_poly->tvlist[v0].v, &curr_poly->tvlist[v1].v, &u);
               VECTOR4D_Build(&curr_poly->tvlist[v0].v, &curr_poly->tvlist[v2].v, &v);

               // compute cross product
               VECTOR4D_Cross(&u, &v, &n);

               // compute length of normal accurately and store in poly nlength
               // +- epsilon later to fix over/underflows
               curr_poly->nlength = VECTOR4D_Length_Fast(&n); 

               // now poly 2, temp_poly
               // build u, v
               VECTOR4D_Build(&temp_poly.tvlist[v0].v, &temp_poly.tvlist[v1].v, &u);
               VECTOR4D_Build(&temp_poly.tvlist[v0].v, &temp_poly.tvlist[v2].v, &v);

               // compute cross product
               VECTOR4D_Cross(&u, &v, &n);

               // compute length of normal accurately and store in poly nlength
               // +- epsilon later to fix over/underflows
               temp_poly.nlength = VECTOR4D_Length_Fast(&n); 

             // now we are good to go, insert the polygon into list
             // if the poly won't fit, it won't matter, the function will
             // just return 0
             Insert_POLYF4DV2_RENDERLIST4DV2(rend_list, &temp_poly);

             } // end else
        
           } // end if near_z clipping has occured
             
          } // end if z planes

    } // end for poly

} // end Clip_Polys_RENDERLIST4DV2

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

int Generate_Terrain_OBJECT4DV2(OBJECT4DV2_PTR obj,     // pointer to object
                                float twidth,            // width in world coords on x-axis
                                float theight,           // height (length) in world coords on z-axis
                                float vscale,           // vertical scale of terrain
                                char *height_map_file,  // filename of height bitmap encoded in 256 colors
                                char *texture_map_file, // filename of texture map
                                int rgbcolor,           // color of terrain if no texture        
                                VECTOR4D_PTR pos,       // initial position
                                VECTOR4D_PTR rot,       // initial rotations
                                int poly_attr)          // the shading attributes we would like
{
// this function generates a terrain of width x height in the x-z plane
// the terrain is defined by a height field encoded as color values 
// of a 256 color texture, 0 being ground level 255 being 1.0, this value
// is scaled by vscale for the height of each point in the height field
// the height field generated will be composed of triangles where each vertex
// in the height field is derived from the height map, thus if the height map
// is 256 x 256 points then the final mesh will be (256-1) x (256-1) polygons 
// with a absolute world size of width x height (in the x-z plane)
// also if there is a texture map file then it will be mapped onto the terrain
// and texture coordinates will be generated

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -