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

📄 t3dlib7.cpp

📁 3D游戏编程大师技巧第九章的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
rend_list->poly_data[rend_list->num_polys].color   = poly->color;
rend_list->poly_data[rend_list->num_polys].nlength = poly->nlength;
rend_list->poly_data[rend_list->num_polys].texture = poly->texture;

// poly could be lit, so copy these too...
rend_list->poly_data[rend_list->num_polys].lit_color[0] = poly->lit_color[0];
rend_list->poly_data[rend_list->num_polys].lit_color[1] = poly->lit_color[1];
rend_list->poly_data[rend_list->num_polys].lit_color[2] = poly->lit_color[2];

// now copy vertices, be careful! later put a loop, but for now
// know there are 3 vertices always!
VERTEX4DTV1_COPY(&rend_list->poly_data[rend_list->num_polys].tvlist[0],
              &poly->vlist[poly->vert[0]]);

VERTEX4DTV1_COPY(&rend_list->poly_data[rend_list->num_polys].tvlist[1],
              &poly->vlist[poly->vert[1]]);

VERTEX4DTV1_COPY(&rend_list->poly_data[rend_list->num_polys].tvlist[2],
              &poly->vlist[poly->vert[2]]);

// and copy into local vertices too
VERTEX4DTV1_COPY(&rend_list->poly_data[rend_list->num_polys].vlist[0],
              &poly->vlist[poly->vert[0]]);

VERTEX4DTV1_COPY(&rend_list->poly_data[rend_list->num_polys].vlist[1],
              &poly->vlist[poly->vert[1]]);

VERTEX4DTV1_COPY(&rend_list->poly_data[rend_list->num_polys].vlist[2],
              &poly->vlist[poly->vert[2]]);

// finally the texture coordinates, this has to be performed manually
// since at this point in the pipeline the vertices do NOT have texture
// coordinate, the polygons DO, however, now, there are 3 vertices for 
// EVERY polygon, rather than vertex sharing, so we can copy the texture
// coordinates out of the indexed arrays into the VERTEX4DTV1 structures
rend_list->poly_data[rend_list->num_polys].tvlist[0].t = poly->tlist[ poly->text[0] ];
rend_list->poly_data[rend_list->num_polys].tvlist[1].t = poly->tlist[ poly->text[1] ];
rend_list->poly_data[rend_list->num_polys].tvlist[2].t = poly->tlist[ poly->text[2] ];

rend_list->poly_data[rend_list->num_polys].vlist[0].t = poly->tlist[ poly->text[0] ];
rend_list->poly_data[rend_list->num_polys].vlist[1].t = poly->tlist[ poly->text[1] ];
rend_list->poly_data[rend_list->num_polys].vlist[2].t = poly->tlist[ poly->text[2] ];

// now the polygon is loaded into the next free array position, but
// we need to fix up the links

// test if this is the first entry
if (rend_list->num_polys == 0)
   {
   // set pointers to null, could loop them around though to self
   rend_list->poly_data[0].next = NULL;
   rend_list->poly_data[0].prev = NULL;
   } // end if
else
   {
   // first set this node to point to previous node and next node (null)
   rend_list->poly_data[rend_list->num_polys].next = NULL;
   rend_list->poly_data[rend_list->num_polys].prev = 
         &rend_list->poly_data[rend_list->num_polys-1];

   // now set previous node to point to this node
   rend_list->poly_data[rend_list->num_polys-1].next = 
          &rend_list->poly_data[rend_list->num_polys];
   } // end else

// increment number of polys in list
rend_list->num_polys++;

// return successful insertion
return(1);

} // end Insert_POLY4DV2_RENDERLIST4DV2

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

int Insert_POLYF4DV2_RENDERLIST4DV2(RENDERLIST4DV2_PTR rend_list, 
                                     POLYF4DV2_PTR poly)
{
// inserts the sent polyface POLYF4DV1 into the render list

// step 0: are we full?
if (rend_list->num_polys >= RENDERLIST4DV2_MAX_POLYS)
   return(0);

// step 1: copy polygon into next opening in polygon render list

// point pointer to polygon structure
rend_list->poly_ptrs[rend_list->num_polys] = &rend_list->poly_data[rend_list->num_polys];

// copy face right into array, thats it!
memcpy((void *)&rend_list->poly_data[rend_list->num_polys],(void *)poly, sizeof(POLYF4DV2));

// now the polygon is loaded into the next free array position, but
// we need to fix up the links
// test if this is the first entry
if (rend_list->num_polys == 0)
   {
   // set pointers to null, could loop them around though to self
   rend_list->poly_data[0].next = NULL;
   rend_list->poly_data[0].prev = NULL;
   } // end if
else
   {
   // first set this node to point to previous node and next node (null)
   rend_list->poly_data[rend_list->num_polys].next = NULL;
   rend_list->poly_data[rend_list->num_polys].prev = 
         &rend_list->poly_data[rend_list->num_polys-1];

   // now set previous node to point to this node
   rend_list->poly_data[rend_list->num_polys-1].next = 
          &rend_list->poly_data[rend_list->num_polys];
   } // end else

// increment number of polys in list
rend_list->num_polys++;

// return successful insertion
return(1);

} // end Insert_POLYF4DV2_RENDERLIST4DV2

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

int Insert_OBJECT4DV2_RENDERLIST4DV2(RENDERLIST4DV2_PTR rend_list, 
                                      OBJECT4DV2_PTR obj,
                                      int insert_local=0)
                                      
{
// { andre work in progress, rewrite with materials...}

// converts the entire object into a face list and then inserts
// the visible, active, non-clipped, non-culled polygons into
// the render list, also note the flag insert_local control 
// whether or not the vlist_local or vlist_trans vertex list
// is used, thus you can insert an object "raw" totally untranformed
// if you set insert_local to 1, default is 0, that is you would
// only insert an object after at least the local to world transform
// the last parameter is used to control if their has been
// a lighting step that has generated a light value stored
// in the upper 16-bits of color, if lighting_on = 1 then
// this value is used to overwrite the base color of the 
// polygon when its sent to the rendering list

unsigned int base_color; // save base color of polygon

// is this objective inactive or culled or invisible?
if (!(obj->state & OBJECT4DV2_STATE_ACTIVE) ||
     (obj->state & OBJECT4DV2_STATE_CULLED) ||
     !(obj->state & OBJECT4DV2_STATE_VISIBLE))
   return(0); 

// the object is valid, let's rip it apart polygon by polygon
for (int poly = 0; poly < obj->num_polys; poly++)
    {
    // acquire polygon
    POLY4DV2_PTR curr_poly = &obj->plist[poly];

    // first is this polygon even visible?
    if (!(curr_poly->state & POLY4DV2_STATE_ACTIVE) ||
         (curr_poly->state & POLY4DV2_STATE_CLIPPED ) ||
         (curr_poly->state & POLY4DV2_STATE_BACKFACE) )
    continue; // move onto next poly

    // override vertex list polygon refers to
    // the case that you want the local coords used
    // first save old pointer
    VERTEX4DTV1_PTR vlist_old = curr_poly->vlist;

    if (insert_local)
       curr_poly->vlist = obj->vlist_local;
    else
       curr_poly->vlist = obj->vlist_trans;

    // now insert this polygon
    if (!Insert_POLY4DV2_RENDERLIST4DV2(rend_list, curr_poly))
       {
       // fix vertex list pointer
       curr_poly->vlist = vlist_old;
              
       // the whole object didn't fit!
       return(0);
       } // end if

    // fix vertex list pointer
    curr_poly->vlist = vlist_old;

    } // end for

// return success
return(1);

} // end Insert_OBJECT4DV2_RENDERLIST4DV2

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

void Reset_OBJECT4DV2(OBJECT4DV2_PTR obj)
{
// this function resets the sent object and redies it for 
// transformations, basically just resets the culled, clipped and
// backface flags, but here's where you would add stuff
// to ready any object for the pipeline
// the object is valid, let's rip it apart polygon by polygon
// note: works on the entire object, all frames

// reset object's culled flag
RESET_BIT(obj->state, OBJECT4DV2_STATE_CULLED);

// now the clipped and backface flags for the polygons 
for (int poly = 0; poly < obj->num_polys; poly++)
    {
    // acquire polygon
    POLY4DV2_PTR curr_poly = &obj->plist[poly];
    
    // first is this polygon even visible?
    if (!(curr_poly->state & POLY4DV2_STATE_ACTIVE))
       continue; // move onto next poly

    // reset clipped and backface flags
    RESET_BIT(curr_poly->state, POLY4DV2_STATE_CLIPPED);
    RESET_BIT(curr_poly->state, POLY4DV2_STATE_BACKFACE);
    RESET_BIT(curr_poly->state, POLY4DV2_STATE_LIT);

    } // end for poly

} // end Reset_OBJECT4DV2

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

void Draw_OBJECT4DV2_Wire(OBJECT4DV2_PTR obj, 
                          UCHAR *video_buffer, int lpitch)
                     
{
// this function renders an object to the screen in wireframe, 
// 8 bit mode, it has no regard at all about hidden surface removal, 
// etc. the function only exists as an easy way to render an object 
// without converting it into polygons, the function assumes all 
// coordinates are screen coordinates, but will perform 2D clipping
// note: only operates on the current frame

// iterate thru the poly list of the object and simply draw
// each polygon
for (int poly=0; poly < obj->num_polys; poly++)
    {
    // render this polygon if and only if it's not clipped, not culled,
    // active, and visible, note however the concecpt of "backface" is 
    // irrelevant in a wire frame engine though
    if (!(obj->plist[poly].state & POLY4DV2_STATE_ACTIVE) ||
         (obj->plist[poly].state & POLY4DV2_STATE_CLIPPED ) ||
         (obj->plist[poly].state & POLY4DV2_STATE_BACKFACE) )
       continue; // move onto next poly
    
    // extract vertex indices into master list, rember the polygons are 
    // NOT self contained, but based on the vertex list stored in the object
    // itself
    int vindex_0 = obj->plist[poly].vert[0];
    int vindex_1 = obj->plist[poly].vert[1];
    int vindex_2 = obj->plist[poly].vert[2];
    
    // {andre need material stuff here!!!! }
    // draw the lines now
    Draw_Clip_Line(obj->vlist_trans[ vindex_0 ].x, obj->vlist_trans[ vindex_0 ].y, 
                obj->vlist_trans[ vindex_1 ].x, obj->vlist_trans[ vindex_1 ].y, 
                obj->plist[poly].lit_color[0],
                video_buffer, lpitch);

    Draw_Clip_Line(obj->vlist_trans[ vindex_1 ].x, obj->vlist_trans[ vindex_1 ].y, 
                obj->vlist_trans[ vindex_2 ].x, obj->vlist_trans[ vindex_2 ].y, 
                obj->plist[poly].lit_color[0],
                video_buffer, lpitch);

    Draw_Clip_Line(obj->vlist_trans[ vindex_2 ].x, obj->vlist_trans[ vindex_2 ].y, 
                obj->vlist_trans[ vindex_0 ].x, obj->vlist_trans[ vindex_0 ].y, 
                obj->plist[poly].lit_color[0],
                video_buffer, lpitch);

// track rendering stats
#ifdef DEBUG_ON
debug_polys_rendered_per_frame++;
#endif

    } // end for poly

} // end Draw_OBJECT4DV2_Wire

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

void Draw_OBJECT4DV2_Wire16(OBJECT4DV2_PTR obj, 
                            UCHAR *video_buffer, int lpitch)
                     
{
// this function renders an object to the screen in wireframe, 
// 16 bit mode, it has no regard at all about hidden surface removal, 
// etc. the function only exists as an easy way to render an object 
// without converting it into polygons, the function assumes all 
// coordinates are screen coordinates, but will perform 2D clipping
// note: only operates on the current frame

// iterate thru the poly list of the object and simply draw
// each polygon
for (int poly=0; poly < obj->num_polys; poly++)
    {
    // render this polygon if and only if it's not clipped, not culled,
    // active, and visible, note however the concecpt of "backface" is 
    // irrelevant in a wire frame engine though
    if (!(obj->plist[poly].state & POLY4DV2_STATE_ACTIVE) ||
         (obj->plist[poly].state & POLY4DV2_STATE_CLIPPED ) ||
         (obj->plist[poly].state & POLY4DV2_STATE_BACKFACE) )
       continue; // move onto next poly
    
    // extract vertex indices into master list, rember the polygons are 
    // NOT self contained, but based on the vertex list stored in the object
    // itself
    int vindex_0 = obj->plist[poly].vert[0];
    int vindex_1 = obj->plist[poly].vert[1];
    int vindex_2 = obj->plist[poly].vert[2];
    
    // {andre need material stuff here!!!! }

    // draw the lines now
    Draw_Clip_Line16(obj->vlist_trans[ vindex_0 ].x, obj->vlist_trans[ vindex_0 ].y, 
                obj->vlist_trans[ vindex_1 ].x, obj->vlist_trans[ vindex_1 ].y, 
                obj->plist[poly].lit_color[0],
                video_buffer, lpitch);

    Draw_Clip_Line16(obj->vlist_trans[ vindex_1 ].x, obj->vlist_trans[ vindex_1 ].y, 
                obj->vlist_trans[ vindex_2 ].x, obj->vlist_trans[ vindex_2 ].y, 
                obj->plist[poly].lit_color[0],
                video_buffer, lpitch);

    Draw_Clip_Line16(obj->vlist_trans[ vindex_2 ].x, obj->vlist_trans[ vindex_2 ].y, 
                obj->vlist_trans[ vindex_0 ].x, obj->vlist_trans[ vindex_0 ].y, 
                obj->plist[poly].lit_color[0],
                video_buffer, lpitch);

// track rendering stats
#ifdef DEBUG_ON
debug_polys_rendered_per_frame++;
#endif

    } // end for poly

} // end Draw_OBJECT4DV2_Wire16

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

⌨️ 快捷键说明

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