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

📄 t3dlib5.cpp

📁 3D游戏编程大师技巧第十章的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:

      case TRANSFORM_LOCAL_TO_TRANS:
      {
      // transform each local/model vertex of the render list and store result
      // in "transformed" vertex list
      for (int poly = 0; poly < rend_list->num_polys; poly++)
          {
          // acquire current polygon
          POLYF4DV1_PTR curr_poly = rend_list->poly_ptrs[poly];

          // is this polygon valid?
          // transform this polygon if and only if it's not clipped, not culled,
          // active, and visible, note however the concept of "backface" is 
          // irrelevant in a wire frame engine though
          if ((curr_poly==NULL) || !(curr_poly->state & POLY4DV1_STATE_ACTIVE) ||
              (curr_poly->state & POLY4DV1_STATE_CLIPPED ) ||
              (curr_poly->state & POLY4DV1_STATE_BACKFACE) )
             continue; // move onto next poly

          // all good, let's transform 
          for (int vertex = 0; vertex < 3; vertex++)
              {
              // transform the vertex by mt
              Mat_Mul_VECTOR4D_4X4(&curr_poly->vlist[vertex], mt, &curr_poly->tvlist[vertex]);
              } // end for vertex
 
          } // end for poly

      } break;

      default: break;

} // end switch

} // end Transform_RENDERLIST4DV1

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

void Model_To_World_RENDERLIST4DV1(RENDERLIST4DV1_PTR rend_list, 
                                  POINT4D_PTR world_pos, 
                                  int coord_select)
{
// NOTE: Not matrix based
// this function converts the local model coordinates of the
// sent render list into world coordinates, the results are stored
// in the transformed vertex list (tvlist) within the renderlist

// interate thru vertex list and transform all the model/local 
// coords to world coords by translating the vertex list by
// the amount world_pos and storing the results in tvlist[]
// is this polygon valid?

if (coord_select == TRANSFORM_LOCAL_TO_TRANS)
   {
   for (int poly = 0; poly < rend_list->num_polys; poly++)
       {
       // acquire current polygon
       POLYF4DV1_PTR curr_poly = rend_list->poly_ptrs[poly];

       // transform this polygon if and only if it's not clipped, not culled,
       // active, and visible, note however the concept of "backface" is 
       // irrelevant in a wire frame engine though
       if ((curr_poly==NULL) || !(curr_poly->state & POLY4DV1_STATE_ACTIVE) ||
           (curr_poly->state & POLY4DV1_STATE_CLIPPED ) ||
           (curr_poly->state & POLY4DV1_STATE_BACKFACE) )
          continue; // move onto next poly

   // all good, let's transform 
   for (int vertex = 0; vertex < 3; vertex++)
       {
       // translate vertex
       VECTOR4D_Add(&curr_poly->vlist[vertex], world_pos, &curr_poly->tvlist[vertex]);
       } // end for vertex

   } // end for poly
} // end if local
else // TRANSFORM_TRANS_ONLY
{
for (int poly = 0; poly < rend_list->num_polys; poly++)
    {
    // acquire current polygon
    POLYF4DV1_PTR curr_poly = rend_list->poly_ptrs[poly];

   // transform this polygon if and only if it's not clipped, not culled,
   // active, and visible, note however the concept of "backface" is 
   // irrelevant in a wire frame engine though
   if ((curr_poly==NULL) || !(curr_poly->state & POLY4DV1_STATE_ACTIVE) ||
       (curr_poly->state & POLY4DV1_STATE_CLIPPED ) ||
       (curr_poly->state & POLY4DV1_STATE_BACKFACE) )
        continue; // move onto next poly

   for (int vertex = 0; vertex < 3; vertex++)
       {
       // translate vertex
       VECTOR4D_Add(&curr_poly->tvlist[vertex], world_pos, &curr_poly->tvlist[vertex]);
       } // end for vertex

    } // end for poly

} // end else

} // end Model_To_World_RENDERLIST4DV1

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

void Convert_From_Homogeneous4D_RENDERLIST4DV1(RENDERLIST4DV1_PTR rend_list)
{
// this function convertes all valid polygons vertices in the transformed
// vertex list from 4D homogeneous coordinates to normal 3D coordinates
// by dividing each x,y,z component by w

for (int poly = 0; poly < rend_list->num_polys; poly++)
{
// acquire current polygon
POLYF4DV1_PTR curr_poly = rend_list->poly_ptrs[poly];

// is this polygon valid?
// transform this polygon if and only if it's not clipped, not culled,
// active, and visible, note however the concept of "backface" is 
// irrelevant in a wire frame engine though
if ((curr_poly==NULL) || !(curr_poly->state & POLY4DV1_STATE_ACTIVE) ||
     (curr_poly->state & POLY4DV1_STATE_CLIPPED ) ||
     (curr_poly->state & POLY4DV1_STATE_BACKFACE) )
       continue; // move onto next poly

// all good, let's transform 
for (int vertex = 0; vertex < 3; vertex++)
    {
    // convert to non-homogenous coords
    VECTOR4D_DIV_BY_W(&curr_poly->tvlist[vertex]); 
    } // end for vertex

} // end for poly

} // end Convert_From_Homogeneous4D_RENDERLIST4DV1

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

void World_To_Camera_RENDERLIST4DV1(RENDERLIST4DV1_PTR rend_list, 
                                 CAM4DV1_PTR cam)
{
// NOTE: this is a matrix based function
// this function transforms each polygon in the global render list
// to camera coordinates based on the sent camera transform matrix
// you would use this function instead of the object based function
// if you decided earlier in the pipeline to turn each object into 
// a list of polygons and then add them to the global render list
// the conversion of an object into polygons probably would have
// happened after object culling, local transforms, local to world
// and backface culling, so the minimum number of polygons from
// each object are in the list, note that the function assumes
// that at LEAST the local to world transform has been called
// and the polygon data is in the transformed list tvlist of
// the POLYF4DV1 object

// transform each polygon in the render list into camera coordinates
// assumes the render list has already been transformed to world
// coordinates and the result is in tvlist[] of each polygon object

for (int poly = 0; poly < rend_list->num_polys; poly++)
{
// acquire current polygon
POLYF4DV1_PTR curr_poly = rend_list->poly_ptrs[poly];

// is this polygon valid?
// transform this polygon if and only if it's not clipped, not culled,
// active, and visible, note however the concept of "backface" is 
// irrelevant in a wire frame engine though
if ((curr_poly==NULL) || !(curr_poly->state & POLY4DV1_STATE_ACTIVE) ||
     (curr_poly->state & POLY4DV1_STATE_CLIPPED ) ||
     (curr_poly->state & POLY4DV1_STATE_BACKFACE) )
       continue; // move onto next poly

// all good, let's transform 
for (int vertex = 0; vertex < 3; vertex++)
    {
    // transform the vertex by the mcam matrix within the camera
    // it better be valid!
    POINT4D presult; // hold result of each transformation

    // transform point
    Mat_Mul_VECTOR4D_4X4(&curr_poly->tvlist[vertex], &cam->mcam, &presult);

    // store result back
    VECTOR4D_COPY(&curr_poly->tvlist[vertex], &presult); 
    } // end for vertex

} // end for poly

} // end World_To_Camera_RENDERLIST4DV1

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

void Camera_To_Perspective_RENDERLIST4DV1(RENDERLIST4DV1_PTR rend_list, 
                                               CAM4DV1_PTR cam)
{
// NOTE: this is not a matrix based function
// this function transforms each polygon in the global render list
// into perspective coordinates, based on the 
// sent camera object, 
// you would use this function instead of the object based function
// if you decided earlier in the pipeline to turn each object into 
// a list of polygons and then add them to the global render list

// transform each polygon in the render list into camera coordinates
// assumes the render list has already been transformed to world
// coordinates and the result is in tvlist[] of each polygon object

for (int poly = 0; poly < rend_list->num_polys; poly++)
{
// acquire current polygon
POLYF4DV1_PTR curr_poly = rend_list->poly_ptrs[poly];

// is this polygon valid?
// transform this polygon if and only if it's not clipped, not culled,
// active, and visible, note however the concept of "backface" is 
// irrelevant in a wire frame engine though
if ((curr_poly==NULL) || !(curr_poly->state & POLY4DV1_STATE_ACTIVE) ||
     (curr_poly->state & POLY4DV1_STATE_CLIPPED ) ||
     (curr_poly->state & POLY4DV1_STATE_BACKFACE) )
       continue; // move onto next poly

// all good, let's transform 
for (int vertex = 0; vertex < 3; vertex++)
    {
    float z = curr_poly->tvlist[vertex].z;

    // transform the vertex by the view parameters in the camera
    curr_poly->tvlist[vertex].x = cam->view_dist*curr_poly->tvlist[vertex].x/z;
    curr_poly->tvlist[vertex].y = cam->view_dist*curr_poly->tvlist[vertex].y*cam->aspect_ratio/z;
    // z = z, so no change

    // not that we are NOT dividing by the homogenous w coordinate since
    // we are not using a matrix operation for this version of the function 

    } // end for vertex

} // end for poly

} // end Camera_To_Perspective_RENDERLIST4DV1

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

void Camera_To_Perspective_Screen_RENDERLIST4DV1(RENDERLIST4DV1_PTR rend_list, 
                                                 CAM4DV1_PTR cam)
{
// NOTE: this is not a matrix based function
// this function transforms the camera coordinates of an object
// into Screen scaled perspective coordinates, based on the 
// sent camera object, that is, view_dist_h and view_dist_v 
// should be set to cause the desired (viewport_width X viewport_height)
// it only works on the vertices in the tvlist[] list
// finally, the function also inverts the y axis, so the coordinates
// generated from this function ARE screen coordinates and ready for
// rendering

// transform each polygon in the render list to perspective screen 
// coordinates assumes the render list has already been transformed 
// to camera coordinates and the result is in tvlist[]
for (int poly = 0; poly < rend_list->num_polys; poly++)
{
// acquire current polygon
POLYF4DV1_PTR curr_poly = rend_list->poly_ptrs[poly];

// is this polygon valid?
// transform this polygon if and only if it's not clipped, not culled,
// active, and visible, note however the concept of "backface" is 
// irrelevant in a wire frame engine though
if ((curr_poly==NULL) || !(curr_poly->state & POLY4DV1_STATE_ACTIVE) ||
     (curr_poly->state & POLY4DV1_STATE_CLIPPED ) ||
     (curr_poly->state & POLY4DV1_STATE_BACKFACE) )
       continue; // move onto next poly

float alpha = (0.5*cam->viewport_width-0.5);
float beta  = (0.5*cam->viewport_height-0.5);

// all good, let's transform 
for (int vertex = 0; vertex < 3; vertex++)
    {
    float z = curr_poly->tvlist[vertex].z;

    // transform the vertex by the view parameters in the camera
    curr_poly->tvlist[vertex].x = cam->view_dist*curr_poly->tvlist[vertex].x/z;
    curr_poly->tvlist[vertex].y = cam->view_dist*curr_poly->tvlist[vertex].y/z;
    // z = z, so no change

    // not that we are NOT dividing by the homogenous w coordinate since
    // we are not using a matrix operation for this version of the function 

    // now the coordinates are in the range x:(-viewport_width/2 to viewport_width/2)
    // and y:(-viewport_height/2 to viewport_height/2), thus we need a translation and
    // since the y-axis is inverted, we need to invert y to complete the screen 
    // transform:
    curr_poly->tvlist[vertex].x =  curr_poly->tvlist[vertex].x + alpha; 
    curr_poly->tvlist[vertex].y = -curr_poly->tvlist[vertex].y + beta;

    } // end for vertex

} // end for poly

} // end Camera_To_Perspective_Screen_RENDERLIST4DV1

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

void Perspective_To_Screen_RENDERLIST4DV1(RENDERLIST4DV1_PTR rend_list, 
                                               CAM4DV1_PTR cam)
{
// NOTE: this is not a matrix based function
// this function transforms the perspective coordinates of the render
// list into screen coordinates, based on the sent viewport in the camera
// assuming that the viewplane coordinates were normalized
// you would use this function instead of the object based function
// if you decided earlier in the pipeline to turn each object into 
// a list of polygons and then add them to the global render list
// you would only call this function if you previously performed
// a normalized perspective transform

// transform each polygon in the render list from perspective to screen 
// coordinates assumes the render list has already been transformed 
// to normalized perspective coordinates and the result is in tvlist[]
for (int poly = 0; poly < rend_list->num_polys; poly++)
{
// acquire current polygon
POLYF4DV1_PTR curr_poly = rend_list->poly_ptrs[poly];

// is this polygon valid?
// transform this polygon if and only if it's not clipped, not culled,
// active, and visible, note however the concept of "backface" is 
// irrelevant in a wire frame engine though
if ((curr_poly==NULL) || !(curr_poly->state & POLY4DV1_STATE_ACTIVE) ||
     (curr_poly->state & POLY4DV1_STATE_CLIPPED ) ||
     (curr_poly->state & POLY4DV1_STATE_BACKFACE) )
       continue; // move onto next poly

float alpha = (0.5*cam->viewport_width-0.5);
float beta  = (0.5*cam->viewport_height-0.5);

// all good, let's transform 
for (int vertex = 0; vertex < 3; vertex++)
    {
    // the vertex is in perspective normalized coords from -1 to 1
    // on each axis, simple scale them and invert y axis and project
    // to screen

    // transform the vertex by th

⌨️ 快捷键说明

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