t3dlib7.cpp
资源名称:Source.rar [点击查看]
上传用户:husern
上传日期:2018-01-20
资源大小:42486k
文件大小:512k
源码类别:
游戏
开发平台:
Visual C++
- Write_Error("nSurface Desc = 0x%.4x, num_verts = %d, vert_indices [%d, %d, %d]",
- poly_surface_desc,
- poly_num_verts,
- obj->plist[poly].vert[0],
- obj->plist[poly].vert[1],
- obj->plist[poly].vert[2]);
- // now we that we have the vertex list and we have entered the polygon
- // vertex index data into the polygon itself, now let's analyze the surface
- // descriptor and set the fields for the polygon based on the description
- // extract out each field of data from the surface descriptor
- // first let's get the single/double sided stuff out of the way
- if ((poly_surface_desc & PLX_2SIDED_FLAG))
- {
- SET_BIT(obj->plist[poly].attr, POLY4DV2_ATTR_2SIDED);
- Write_Error("n2 sided.");
- } // end if
- else
- {
- // one sided
- Write_Error("n1 sided.");
- } // end else
- // now let's set the color type and color
- if ((poly_surface_desc & PLX_COLOR_MODE_RGB_FLAG))
- {
- // this is an RGB 4.4.4 surface
- SET_BIT(obj->plist[poly].attr,POLY4DV2_ATTR_RGB16);
- // now extract color and copy into polygon color
- // field in proper 16-bit format
- // 0x0RGB is the format, 4 bits per pixel
- int red = ((poly_surface_desc & 0x0f00) >> 8);
- int green = ((poly_surface_desc & 0x00f0) >> 4);
- int blue = (poly_surface_desc & 0x000f);
- // although the data is always in 4.4.4 format, the graphics card
- // is either 5.5.5 or 5.6.5, but our virtual color system translates
- // 8.8.8 into 5.5.5 or 5.6.5 for us, but we have to first scale all
- // these 4.4.4 values into 8.8.8
- obj->plist[poly].color = RGB16Bit(red*16, green*16, blue*16);
- Write_Error("nRGB color = [%d, %d, %d]", red, green, blue);
- } // end if
- else
- {
- // this is an 8-bit color indexed surface
- SET_BIT(obj->plist[poly].attr,POLY4DV2_ATTR_8BITCOLOR);
- // and simple extract the last 8 bits and that's the color index
- obj->plist[poly].color = (poly_surface_desc & 0x00ff);
- Write_Error("n8-bit color index = %d", obj->plist[poly].color);
- } // end else
- // handle shading mode
- int shade_mode = (poly_surface_desc & PLX_SHADE_MODE_MASK);
- // set polygon shading mode
- switch(shade_mode)
- {
- case PLX_SHADE_MODE_PURE_FLAG: {
- SET_BIT(obj->plist[poly].attr, POLY4DV2_ATTR_SHADE_MODE_PURE);
- Write_Error("nShade mode = pure");
- } break;
- case PLX_SHADE_MODE_FLAT_FLAG: {
- SET_BIT(obj->plist[poly].attr, POLY4DV2_ATTR_SHADE_MODE_FLAT);
- Write_Error("nShade mode = flat");
- } break;
- case PLX_SHADE_MODE_GOURAUD_FLAG: {
- SET_BIT(obj->plist[poly].attr, POLY4DV2_ATTR_SHADE_MODE_GOURAUD);
- // the vertices from this polygon all need normals, set that in the flags attribute
- SET_BIT(obj->vlist_local[ obj->plist[poly].vert[0] ].attr, VERTEX4DTV1_ATTR_NORMAL);
- SET_BIT(obj->vlist_local[ obj->plist[poly].vert[1] ].attr, VERTEX4DTV1_ATTR_NORMAL);
- SET_BIT(obj->vlist_local[ obj->plist[poly].vert[2] ].attr, VERTEX4DTV1_ATTR_NORMAL);
- Write_Error("nShade mode = gouraud");
- } break;
- case PLX_SHADE_MODE_PHONG_FLAG: {
- SET_BIT(obj->plist[poly].attr, POLY4DV2_ATTR_SHADE_MODE_PHONG);
- // the vertices from this polygon all need normals, set that in the flags attribute
- SET_BIT(obj->vlist_local[ obj->plist[poly].vert[0] ].attr, VERTEX4DTV1_ATTR_NORMAL);
- SET_BIT(obj->vlist_local[ obj->plist[poly].vert[1] ].attr, VERTEX4DTV1_ATTR_NORMAL);
- SET_BIT(obj->vlist_local[ obj->plist[poly].vert[2] ].attr, VERTEX4DTV1_ATTR_NORMAL);
- Write_Error("nShade mode = phong");
- } break;
- default: break;
- } // end switch
- // set the material mode to ver. 1.0 emulation
- SET_BIT(obj->plist[poly].attr, POLY4DV2_ATTR_DISABLE_MATERIAL);
- // finally set the polygon to active
- obj->plist[poly].state = POLY4DV2_STATE_ACTIVE;
- // point polygon vertex list to object's vertex list
- // note that this is redundant since the polylist is contained
- // within the object in this case and its up to the user to select
- // whether the local or transformed vertex list is used when building up
- // polygon geometry, might be a better idea to set to NULL in the context
- // of polygons that are part of an object
- obj->plist[poly].vlist = obj->vlist_local;
- // set texture coordinate list, this is needed
- obj->plist[poly].tlist = obj->tlist;
- } // end for poly
- // compute the polygon normal lengths
- Compute_OBJECT4DV2_Poly_Normals(obj);
- // compute vertex normals for any gouraud shaded polys
- Compute_OBJECT4DV2_Vertex_Normals(obj);
- // close the file
- fclose(fp);
- // return success
- return(1);
- } // end Load_OBJECT4DV2_PLG
- ////////////////////////////////////////////////////////////////
- void Reset_RENDERLIST4DV2(RENDERLIST4DV2_PTR rend_list)
- {
- // this function intializes and resets the sent render list and
- // redies it for polygons/faces to be inserted into it
- // note that the render list in this version is composed
- // of an array FACE4DV1 pointer objects, you call this
- // function each frame
- // since we are tracking the number of polys in the
- // list via num_polys we can set it to 0
- // but later we will want a more robust scheme if
- // we generalize the linked list more and disconnect
- // it from the polygon pointer list
- rend_list->num_polys = 0; // that was hard!
- } // end Reset_RENDERLIST4DV2
- ////////////////////////////////////////////////////////////////
- void Draw_RENDERLIST4DV2_Wire16(RENDERLIST4DV2_PTR rend_list,
- UCHAR *video_buffer, int lpitch)
- {
- // this function "executes" the render list or in other words
- // draws all the faces in the list in wire frame 16bit mode
- // note there is no need to sort wire frame polygons
- // at this point, all we have is a list of polygons and it's time
- // to draw them
- for (int poly=0; poly < rend_list->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 (!(rend_list->poly_ptrs[poly]->state & POLY4DV2_STATE_ACTIVE) ||
- (rend_list->poly_ptrs[poly]->state & POLY4DV2_STATE_CLIPPED ) ||
- (rend_list->poly_ptrs[poly]->state & POLY4DV2_STATE_BACKFACE) )
- continue; // move onto next poly
- // draw the triangle edge one, note that clipping was already set up
- // by 2D initialization, so line clipper will clip all polys out
- // of the 2D screen/window boundary
- Draw_Clip_Line16(rend_list->poly_ptrs[poly]->tvlist[0].x,
- rend_list->poly_ptrs[poly]->tvlist[0].y,
- rend_list->poly_ptrs[poly]->tvlist[1].x,
- rend_list->poly_ptrs[poly]->tvlist[1].y,
- rend_list->poly_ptrs[poly]->lit_color[0],
- video_buffer, lpitch);
- Draw_Clip_Line16(rend_list->poly_ptrs[poly]->tvlist[1].x,
- rend_list->poly_ptrs[poly]->tvlist[1].y,
- rend_list->poly_ptrs[poly]->tvlist[2].x,
- rend_list->poly_ptrs[poly]->tvlist[2].y,
- rend_list->poly_ptrs[poly]->lit_color[0],
- video_buffer, lpitch);
- Draw_Clip_Line16(rend_list->poly_ptrs[poly]->tvlist[2].x,
- rend_list->poly_ptrs[poly]->tvlist[2].y,
- rend_list->poly_ptrs[poly]->tvlist[0].x,
- rend_list->poly_ptrs[poly]->tvlist[0].y,
- rend_list->poly_ptrs[poly]->lit_color[0],
- video_buffer, lpitch);
- // track rendering stats
- #ifdef DEBUG_ON
- debug_polys_rendered_per_frame++;
- #endif
- } // end for poly
- } // end Draw_RENDERLIST4DV2_Wire16
- /////////////////////////////////////////////////////////////
- void Draw_RENDERLIST4DV2_Wire(RENDERLIST4DV2_PTR rend_list,
- UCHAR *video_buffer, int lpitch)
- {
- // this function "executes" the render list or in other words
- // draws all the faces in the list in wire frame 8bit mode
- // note there is no need to sort wire frame polygons
- // at this point, all we have is a list of polygons and it's time
- // to draw them
- for (int poly=0; poly < rend_list->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 (!(rend_list->poly_ptrs[poly]->state & POLY4DV2_STATE_ACTIVE) ||
- (rend_list->poly_ptrs[poly]->state & POLY4DV2_STATE_CLIPPED ) ||
- (rend_list->poly_ptrs[poly]->state & POLY4DV2_STATE_BACKFACE) )
- continue; // move onto next poly
- // draw the triangle edge one, note that clipping was already set up
- // by 2D initialization, so line clipper will clip all polys out
- // of the 2D screen/window boundary
- Draw_Clip_Line(rend_list->poly_ptrs[poly]->tvlist[0].x,
- rend_list->poly_ptrs[poly]->tvlist[0].y,
- rend_list->poly_ptrs[poly]->tvlist[1].x,
- rend_list->poly_ptrs[poly]->tvlist[1].y,
- rend_list->poly_ptrs[poly]->lit_color[0],
- video_buffer, lpitch);
- Draw_Clip_Line(rend_list->poly_ptrs[poly]->tvlist[1].x,
- rend_list->poly_ptrs[poly]->tvlist[1].y,
- rend_list->poly_ptrs[poly]->tvlist[2].x,
- rend_list->poly_ptrs[poly]->tvlist[2].y,
- rend_list->poly_ptrs[poly]->lit_color[0],
- video_buffer, lpitch);
- Draw_Clip_Line(rend_list->poly_ptrs[poly]->tvlist[2].x,
- rend_list->poly_ptrs[poly]->tvlist[2].y,
- rend_list->poly_ptrs[poly]->tvlist[0].x,
- rend_list->poly_ptrs[poly]->tvlist[0].y,
- rend_list->poly_ptrs[poly]->lit_color[0],
- video_buffer, lpitch);
- // track rendering stats
- #ifdef DEBUG_ON
- debug_polys_rendered_per_frame++;
- #endif
- } // end for poly
- } // end Draw_RENDERLIST4DV2_Wire
- ///////////////////////////////////////////////////////////////
- void Draw_RENDERLIST4DV2_Solid16(RENDERLIST4DV2_PTR rend_list,
- UCHAR *video_buffer,
- int lpitch)
- {
- // 16-bit version
- // this function "executes" the render list or in other words
- // draws all the faces in the list, the function will call the
- // proper rasterizer based on the lighting model of the polygons
- POLYF4DV2 face; // temp face used to render polygon
- // at this point, all we have is a list of polygons and it's time
- // to draw them
- for (int poly=0; poly < rend_list->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 (!(rend_list->poly_ptrs[poly]->state & POLY4DV2_STATE_ACTIVE) ||
- (rend_list->poly_ptrs[poly]->state & POLY4DV2_STATE_CLIPPED ) ||
- (rend_list->poly_ptrs[poly]->state & POLY4DV2_STATE_BACKFACE) )
- continue; // move onto next poly
- // need to test for textured first, since a textured poly can either
- // be emissive, or flat shaded, hence we need to call different
- // rasterizers
- if (rend_list->poly_ptrs[poly]->attr & POLY4DV2_ATTR_SHADE_MODE_TEXTURE)
- {
- // set the vertices
- face.tvlist[0].x = (int)rend_list->poly_ptrs[poly]->tvlist[0].x;
- face.tvlist[0].y = (int)rend_list->poly_ptrs[poly]->tvlist[0].y;
- face.tvlist[0].u0 = (int)rend_list->poly_ptrs[poly]->tvlist[0].u0;
- face.tvlist[0].v0 = (int)rend_list->poly_ptrs[poly]->tvlist[0].v0;
- face.tvlist[1].x = (int)rend_list->poly_ptrs[poly]->tvlist[1].x;
- face.tvlist[1].y = (int)rend_list->poly_ptrs[poly]->tvlist[1].y;
- face.tvlist[1].u0 = (int)rend_list->poly_ptrs[poly]->tvlist[1].u0;
- face.tvlist[1].v0 = (int)rend_list->poly_ptrs[poly]->tvlist[1].v0;
- face.tvlist[2].x = (int)rend_list->poly_ptrs[poly]->tvlist[2].x;
- face.tvlist[2].y = (int)rend_list->poly_ptrs[poly]->tvlist[2].y;
- face.tvlist[2].u0 = (int)rend_list->poly_ptrs[poly]->tvlist[2].u0;
- face.tvlist[2].v0 = (int)rend_list->poly_ptrs[poly]->tvlist[2].v0;
- // assign the texture
- face.texture = rend_list->poly_ptrs[poly]->texture;
- // is this a plain emissive texture?
- if (rend_list->poly_ptrs[poly]->attr & POLY4DV2_ATTR_SHADE_MODE_CONSTANT)
- {
- // draw the textured triangle as emissive
- Draw_Textured_Triangle16(&face, video_buffer, lpitch);
- } // end if
- else
- {
- // draw as flat shaded
- face.lit_color[0] = rend_list->poly_ptrs[poly]->lit_color[0];
- Draw_Textured_TriangleFS16(&face, video_buffer, lpitch);
- } // end else
- } // end if
- else
- if ((rend_list->poly_ptrs[poly]->attr & POLY4DV2_ATTR_SHADE_MODE_FLAT) ||
- (rend_list->poly_ptrs[poly]->attr & POLY4DV2_ATTR_SHADE_MODE_CONSTANT) )
- {
- // draw the triangle with basic flat rasterizer
- Draw_Triangle_2D2_16(rend_list->poly_ptrs[poly]->tvlist[0].x, rend_list->poly_ptrs[poly]->tvlist[0].y,
- rend_list->poly_ptrs[poly]->tvlist[1].x, rend_list->poly_ptrs[poly]->tvlist[1].y,
- rend_list->poly_ptrs[poly]->tvlist[2].x, rend_list->poly_ptrs[poly]->tvlist[2].y,
- rend_list->poly_ptrs[poly]->lit_color[0], video_buffer, lpitch);
- } // end if
- else
- if (rend_list->poly_ptrs[poly]->attr & POLY4DV2_ATTR_SHADE_MODE_GOURAUD)
- {
- // {andre take advantage of the data structures later..}
- // set the vertices
- face.tvlist[0].x = (int)rend_list->poly_ptrs[poly]->tvlist[0].x;
- face.tvlist[0].y = (int)rend_list->poly_ptrs[poly]->tvlist[0].y;
- face.lit_color[0] = rend_list->poly_ptrs[poly]->lit_color[0];
- face.tvlist[1].x = (int)rend_list->poly_ptrs[poly]->tvlist[1].x;
- face.tvlist[1].y = (int)rend_list->poly_ptrs[poly]->tvlist[1].y;
- face.lit_color[1] = rend_list->poly_ptrs[poly]->lit_color[1];
- face.tvlist[2].x = (int)rend_list->poly_ptrs[poly]->tvlist[2].x;
- face.tvlist[2].y = (int)rend_list->poly_ptrs[poly]->tvlist[2].y;
- face.lit_color[2] = rend_list->poly_ptrs[poly]->lit_color[2];
- // draw the gouraud shaded triangle
- Draw_Gouraud_Triangle16(&face, video_buffer, lpitch);
- } // end if gouraud
- } // end for poly
- } // end Draw_RENDERLIST4DV2_Solid16
- ///////////////////////////////////////////////////////////////
- void Draw_RENDERLIST4DV2_Solid(RENDERLIST4DV2_PTR rend_list,
- UCHAR *video_buffer,
- int lpitch)
- {
- // 8-bit version
- // this function "executes" the render list or in other words
- // draws all the faces in the list, the function will call the
- // proper rasterizer based on the lighting model of the polygons
- POLYF4DV2 face; // temp face used to render polygon
- // at this point, all we have is a list of polygons and it's time
- // to draw them
- for (int poly=0; poly < rend_list->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 (!(rend_list->poly_ptrs[poly]->state & POLY4DV2_STATE_ACTIVE) ||
- (rend_list->poly_ptrs[poly]->state & POLY4DV2_STATE_CLIPPED ) ||
- (rend_list->poly_ptrs[poly]->state & POLY4DV2_STATE_BACKFACE) )
- continue; // move onto next poly
- // need to test for textured first, since a textured poly can either
- // be emissive, or flat shaded, hence we need to call different
- // rasterizers
- if (rend_list->poly_ptrs[poly]->attr & POLY4DV2_ATTR_SHADE_MODE_TEXTURE)
- {
- // set the vertices
- face.tvlist[0].x = (int)rend_list->poly_ptrs[poly]->tvlist[0].x;
- face.tvlist[0].y = (int)rend_list->poly_ptrs[poly]->tvlist[0].y;
- face.tvlist[0].u0 = (int)rend_list->poly_ptrs[poly]->tvlist[0].u0;
- face.tvlist[0].v0 = (int)rend_list->poly_ptrs[poly]->tvlist[0].v0;
- face.tvlist[1].x = (int)rend_list->poly_ptrs[poly]->tvlist[1].x;
- face.tvlist[1].y = (int)rend_list->poly_ptrs[poly]->tvlist[1].y;
- face.tvlist[1].u0 = (int)rend_list->poly_ptrs[poly]->tvlist[1].u0;
- face.tvlist[1].v0 = (int)rend_list->poly_ptrs[poly]->tvlist[1].v0;
- face.tvlist[2].x = (int)rend_list->poly_ptrs[poly]->tvlist[2].x;
- face.tvlist[2].y = (int)rend_list->poly_ptrs[poly]->tvlist[2].y;
- face.tvlist[2].u0 = (int)rend_list->poly_ptrs[poly]->tvlist[2].u0;
- face.tvlist[2].v0 = (int)rend_list->poly_ptrs[poly]->tvlist[2].v0;
- // assign the texture
- face.texture = rend_list->poly_ptrs[poly]->texture;
- // is this a plain emissive texture?
- if (rend_list->poly_ptrs[poly]->attr & POLY4DV2_ATTR_SHADE_MODE_CONSTANT)
- {
- // draw the textured triangle as emissive
- Draw_Textured_Triangle(&face, video_buffer, lpitch);
- } // end if
- else
- {
- // draw as flat shaded
- face.lit_color[0] = rend_list->poly_ptrs[poly]->lit_color[0];
- Draw_Textured_TriangleFS(&face, video_buffer, lpitch);
- } // end else
- } // end if
- else
- if ((rend_list->poly_ptrs[poly]->attr & POLY4DV2_ATTR_SHADE_MODE_FLAT) ||
- (rend_list->poly_ptrs[poly]->attr & POLY4DV2_ATTR_SHADE_MODE_CONSTANT) )
- {
- // draw the triangle with basic flat rasterizer
- Draw_Triangle_2D2(rend_list->poly_ptrs[poly]->tvlist[0].x, rend_list->poly_ptrs[poly]->tvlist[0].y,
- rend_list->poly_ptrs[poly]->tvlist[1].x, rend_list->poly_ptrs[poly]->tvlist[1].y,
- rend_list->poly_ptrs[poly]->tvlist[2].x, rend_list->poly_ptrs[poly]->tvlist[2].y,
- rend_list->poly_ptrs[poly]->lit_color[0], video_buffer, lpitch);
- } // end if
- else
- if (rend_list->poly_ptrs[poly]->attr & POLY4DV2_ATTR_SHADE_MODE_GOURAUD)
- {
- // {andre take advantage of the data structures later..}
- // set the vertices
- face.tvlist[0].x = (int)rend_list->poly_ptrs[poly]->tvlist[0].x;
- face.tvlist[0].y = (int)rend_list->poly_ptrs[poly]->tvlist[0].y;
- face.lit_color[0] = rend_list->poly_ptrs[poly]->lit_color[0];
- face.tvlist[1].x = (int)rend_list->poly_ptrs[poly]->tvlist[1].x;
- face.tvlist[1].y = (int)rend_list->poly_ptrs[poly]->tvlist[1].y;
- face.lit_color[1] = rend_list->poly_ptrs[poly]->lit_color[1];
- face.tvlist[2].x = (int)rend_list->poly_ptrs[poly]->tvlist[2].x;
- face.tvlist[2].y = (int)rend_list->poly_ptrs[poly]->tvlist[2].y;
- face.lit_color[2] = rend_list->poly_ptrs[poly]->lit_color[2];
- // draw the gouraud shaded triangle
- Draw_Gouraud_Triangle(&face, video_buffer, lpitch);
- } // end if gouraud
- } // end for poly
- } // end Draw_RENDERLIST4DV2_Solid
- /////////////////////////////////////////////////////////////////
- void Draw_OBJECT4DV2_Solid(OBJECT4DV2_PTR obj,
- UCHAR *video_buffer, int lpitch)
- {
- // this function renders an object to the screen in
- // 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
- POLYF4DV2 face; // temp face used to render polygon
- // at this point, all we have is a list of polygons and it's time
- // to draw them
- 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];
- // need to test for textured first, since a textured poly can either
- // be emissive, or flat shaded, hence we need to call different
- // rasterizers
- if (obj->plist[poly].attr & POLY4DV2_ATTR_SHADE_MODE_TEXTURE)
- {
- // set the vertices
- face.tvlist[0].x = (int)obj->vlist_trans[ vindex_0].x;
- face.tvlist[0].y = (int)obj->vlist_trans[ vindex_0].y;
- face.tvlist[0].u0 = (int)obj->vlist_trans[ vindex_0].u0;
- face.tvlist[0].v0 = (int)obj->vlist_trans[ vindex_0].v0;
- face.tvlist[1].x = (int)obj->vlist_trans[ vindex_1].x;
- face.tvlist[1].y = (int)obj->vlist_trans[ vindex_1].y;
- face.tvlist[1].u0 = (int)obj->vlist_trans[ vindex_1].u0;
- face.tvlist[1].v0 = (int)obj->vlist_trans[ vindex_1].v0;
- face.tvlist[2].x = (int)obj->vlist_trans[ vindex_2].x;
- face.tvlist[2].y = (int)obj->vlist_trans[ vindex_2].y;
- face.tvlist[2].u0 = (int)obj->vlist_trans[ vindex_2].u0;
- face.tvlist[2].v0 = (int)obj->vlist_trans[ vindex_2].v0;
- // assign the texture
- face.texture = obj->plist[poly].texture;
- // is this a plain emissive texture?
- if (obj->plist[poly].attr & POLY4DV2_ATTR_SHADE_MODE_CONSTANT)
- {
- // draw the textured triangle as emissive
- Draw_Textured_Triangle(&face, video_buffer, lpitch);
- } // end if
- else
- {
- // draw as flat shaded
- face.lit_color[0] = obj->plist[poly].lit_color[0];
- Draw_Textured_TriangleFS(&face, video_buffer, lpitch);
- } // end else
- } // end if
- else
- if ((obj->plist[poly].attr & POLY4DV2_ATTR_SHADE_MODE_FLAT) ||
- (obj->plist[poly].attr & POLY4DV2_ATTR_SHADE_MODE_CONSTANT) )
- {
- // draw the triangle with basic flat rasterizer
- Draw_Triangle_2D2(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->vlist_trans[ vindex_2].x, obj->vlist_trans[ vindex_2].y,
- obj->plist[poly].lit_color[0], video_buffer, lpitch);
- } // end if
- else
- if (obj->plist[poly].attr & POLY4DV2_ATTR_SHADE_MODE_GOURAUD)
- {
- // {andre take advantage of the data structures later..}
- // set the vertices
- face.tvlist[0].x = (int)obj->vlist_trans[ vindex_0].x;
- face.tvlist[0].y = (int)obj->vlist_trans[ vindex_0].y;
- face.lit_color[0] = obj->plist[poly].lit_color[0];
- face.tvlist[1].x = (int)obj->vlist_trans[ vindex_1].x;
- face.tvlist[1].y = (int)obj->vlist_trans[ vindex_1].y;
- face.lit_color[1] = obj->plist[poly].lit_color[1];
- face.tvlist[2].x = (int)obj->vlist_trans[ vindex_2].x;
- face.tvlist[2].y = (int)obj->vlist_trans[ vindex_2].y;
- face.lit_color[2] = obj->plist[poly].lit_color[2];
- // draw the gouraud shaded triangle
- Draw_Gouraud_Triangle(&face, video_buffer, lpitch);
- } // end if gouraud
- } // end for poly
- } // end Draw_OBJECT4DV2_Solid
- ///////////////////////////////////////////////////////////////
- void Draw_OBJECT4DV2_Solid16(OBJECT4DV2_PTR obj,
- UCHAR *video_buffer, int lpitch)
- {
- // this function renders an object to the screen in
- // 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
- POLYF4DV2 face; // temp face used to render polygon
- // at this point, all we have is a list of polygons and it's time
- // to draw them
- 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];
- // need to test for textured first, since a textured poly can either
- // be emissive, or flat shaded, hence we need to call different
- // rasterizers
- if (obj->plist[poly].attr & POLY4DV2_ATTR_SHADE_MODE_TEXTURE)
- {
- // set the vertices
- face.tvlist[0].x = (int)obj->vlist_trans[ vindex_0].x;
- face.tvlist[0].y = (int)obj->vlist_trans[ vindex_0].y;
- face.tvlist[0].u0 = (int)obj->vlist_trans[ vindex_0].u0;
- face.tvlist[0].v0 = (int)obj->vlist_trans[ vindex_0].v0;
- face.tvlist[1].x = (int)obj->vlist_trans[ vindex_1].x;
- face.tvlist[1].y = (int)obj->vlist_trans[ vindex_1].y;
- face.tvlist[1].u0 = (int)obj->vlist_trans[ vindex_1].u0;
- face.tvlist[1].v0 = (int)obj->vlist_trans[ vindex_1].v0;
- face.tvlist[2].x = (int)obj->vlist_trans[ vindex_2].x;
- face.tvlist[2].y = (int)obj->vlist_trans[ vindex_2].y;
- face.tvlist[2].u0 = (int)obj->vlist_trans[ vindex_2].u0;
- face.tvlist[2].v0 = (int)obj->vlist_trans[ vindex_2].v0;
- // assign the texture
- face.texture = obj->plist[poly].texture;
- // is this a plain emissive texture?
- if (obj->plist[poly].attr & POLY4DV2_ATTR_SHADE_MODE_CONSTANT)
- {
- // draw the textured triangle as emissive
- Draw_Textured_Triangle16(&face, video_buffer, lpitch);
- } // end if
- else
- {
- // draw as flat shaded
- face.lit_color[0] = obj->plist[poly].lit_color[0];
- Draw_Textured_TriangleFS16(&face, video_buffer, lpitch);
- } // end else
- } // end if
- else
- if ((obj->plist[poly].attr & POLY4DV2_ATTR_SHADE_MODE_FLAT) ||
- (obj->plist[poly].attr & POLY4DV2_ATTR_SHADE_MODE_CONSTANT) )
- {
- // draw the triangle with basic flat rasterizer
- Draw_Triangle_2D2_16(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->vlist_trans[ vindex_2].x, obj->vlist_trans[ vindex_2].y,
- obj->plist[poly].lit_color[0], video_buffer, lpitch);
- } // end if
- else
- if (obj->plist[poly].attr & POLY4DV2_ATTR_SHADE_MODE_GOURAUD)
- {
- // {andre take advantage of the data structures later..}
- // set the vertices
- face.tvlist[0].x = (int)obj->vlist_trans[ vindex_0].x;
- face.tvlist[0].y = (int)obj->vlist_trans[ vindex_0].y;
- face.lit_color[0] = obj->plist[poly].lit_color[0];
- face.tvlist[1].x = (int)obj->vlist_trans[ vindex_1].x;
- face.tvlist[1].y = (int)obj->vlist_trans[ vindex_1].y;
- face.lit_color[1] = obj->plist[poly].lit_color[1];
- face.tvlist[2].x = (int)obj->vlist_trans[ vindex_2].x;
- face.tvlist[2].y = (int)obj->vlist_trans[ vindex_2].y;
- face.lit_color[2] = obj->plist[poly].lit_color[2];
- // draw the gouraud shaded triangle
- Draw_Gouraud_Triangle16(&face, video_buffer, lpitch);
- } // end if gouraud
- } // end for poly
- } // end Draw_OBJECT4DV2_Solid16
- /////////////////////////////////////////////////////////////
- void Draw_Textured_Triangle(POLYF4DV2_PTR face, // ptr to face
- UCHAR *dest_buffer, // pointer to video buffer
- int mem_pitch) // bytes per line, 320, 640 etc.
- {
- // this function draws a textured triangle in 8-bit mode
- int v0=0,
- v1=1,
- v2=2,
- temp=0,
- tri_type = TRI_TYPE_NONE,
- irestart = INTERP_LHS;
- int dx,dy,dyl,dyr, // general deltas
- u,v,
- du,dv,
- xi,yi, // the current interpolated x,y
- ui,vi, // the current interpolated u,v
- index_x,index_y, // looping vars
- x,y, // hold general x,y
- xstart,
- xend,
- ystart,
- yrestart,
- yend,
- xl,
- dxdyl,
- xr,
- dxdyr,
- dudyl,
- ul,
- dvdyl,
- vl,
- dudyr,
- ur,
- dvdyr,
- vr;
- int x0,y0,tu0,tv0, // cached vertices
- x1,y1,tu1,tv1,
- x2,y2,tu2,tv2;
- UCHAR *screen_ptr = NULL,
- *screen_line = NULL,
- *textmap = NULL;
- #ifdef DEBUG_ON
- // track rendering stats
- debug_polys_rendered_per_frame++;
- #endif
- // extract texture map
- textmap = face->texture->buffer;
- // extract base 2 of texture width
- int texture_shift2 = logbase2ofx[face->texture->width];
- // first trivial clipping rejection tests
- if (((face->tvlist[0].y < min_clip_y) &&
- (face->tvlist[1].y < min_clip_y) &&
- (face->tvlist[2].y < min_clip_y)) ||
- ((face->tvlist[0].y > max_clip_y) &&
- (face->tvlist[1].y > max_clip_y) &&
- (face->tvlist[2].y > max_clip_y)) ||
- ((face->tvlist[0].x < min_clip_x) &&
- (face->tvlist[1].x < min_clip_x) &&
- (face->tvlist[2].x < min_clip_x)) ||
- ((face->tvlist[0].x > max_clip_x) &&
- (face->tvlist[1].x > max_clip_x) &&
- (face->tvlist[2].x > max_clip_x)))
- return;
- // degenerate triangle
- if ( ((face->tvlist[0].x==face->tvlist[1].x) && (face->tvlist[1].x==face->tvlist[2].x)) ||
- ((face->tvlist[0].y==face->tvlist[1].y) && (face->tvlist[1].y==face->tvlist[2].y)))
- return;
- // sort vertices
- if (face->tvlist[v1].y < face->tvlist[v0].y)
- {SWAP(v0,v1,temp);}
- if (face->tvlist[v2].y < face->tvlist[v0].y)
- {SWAP(v0,v2,temp);}
- if (face->tvlist[v2].y < face->tvlist[v1].y)
- {SWAP(v1,v2,temp);}
- // now test for trivial flat sided cases
- if (face->tvlist[v0].y==face->tvlist[v1].y)
- {
- // set triangle type
- tri_type = TRI_TYPE_FLAT_TOP;
- // sort vertices left to right
- if (face->tvlist[v1].x < face->tvlist[v0].x)
- {SWAP(v0,v1,temp);}
- } // end if
- else
- // now test for trivial flat sided cases
- if (face->tvlist[v1].y==face->tvlist[v2].y)
- {
- // set triangle type
- tri_type = TRI_TYPE_FLAT_BOTTOM;
- // sort vertices left to right
- if (face->tvlist[v2].x < face->tvlist[v1].x)
- {SWAP(v1,v2,temp);}
- } // end if
- else
- {
- // must be a general triangle
- tri_type = TRI_TYPE_GENERAL;
- } // end else
- // extract vertices for processing, now that we have order
- x0 = (int)(face->tvlist[v0].x+0.5);
- y0 = (int)(face->tvlist[v0].y+0.5);
- tu0 = (int)(face->tvlist[v0].u0);
- tv0 = (int)(face->tvlist[v0].v0);
- x1 = (int)(face->tvlist[v1].x+0.5);
- y1 = (int)(face->tvlist[v1].y+0.5);
- tu1 = (int)(face->tvlist[v1].u0);
- tv1 = (int)(face->tvlist[v1].v0);
- x2 = (int)(face->tvlist[v2].x+0.5);
- y2 = (int)(face->tvlist[v2].y+0.5);
- tu2 = (int)(face->tvlist[v2].u0);
- tv2 = (int)(face->tvlist[v2].v0);
- // set interpolation restart value
- yrestart = y1;
- // what kind of triangle
- if (tri_type & TRI_TYPE_FLAT_MASK)
- {
- if (tri_type == TRI_TYPE_FLAT_TOP)
- {
- // compute all deltas
- dy = (y2 - y0);
- dxdyl = ((x2 - x0) << FIXP16_SHIFT)/dy;
- dudyl = ((tu2 - tu0) << FIXP16_SHIFT)/dy;
- dvdyl = ((tv2 - tv0) << FIXP16_SHIFT)/dy;
- dxdyr = ((x2 - x1) << FIXP16_SHIFT)/dy;
- dudyr = ((tu2 - tu1) << FIXP16_SHIFT)/dy;
- dvdyr = ((tv2 - tv1) << FIXP16_SHIFT)/dy;
- // test for y clipping
- if (y0 < min_clip_y)
- {
- // compute overclip
- dy = (min_clip_y - y0);
- // computer new LHS starting values
- xl = dxdyl*dy + (x0 << FIXP16_SHIFT);
- ul = dudyl*dy + (tu0 << FIXP16_SHIFT);
- vl = dvdyl*dy + (tv0 << FIXP16_SHIFT);
- // compute new RHS starting values
- xr = dxdyr*dy + (x1 << FIXP16_SHIFT);
- ur = dudyr*dy + (tu1 << FIXP16_SHIFT);
- vr = dvdyr*dy + (tv1 << FIXP16_SHIFT);
- // compute new starting y
- ystart = min_clip_y;
- } // end if
- else
- {
- // no clipping
- // set starting values
- xl = (x0 << FIXP16_SHIFT);
- xr = (x1 << FIXP16_SHIFT);
- ul = (tu0 << FIXP16_SHIFT);
- vl = (tv0 << FIXP16_SHIFT);
- ur = (tu1 << FIXP16_SHIFT);
- vr = (tv1 << FIXP16_SHIFT);
- // set starting y
- ystart = y0;
- } // end else
- } // end if flat top
- else
- {
- // must be flat bottom
- // compute all deltas
- dy = (y1 - y0);
- dxdyl = ((x1 - x0) << FIXP16_SHIFT)/dy;
- dudyl = ((tu1 - tu0) << FIXP16_SHIFT)/dy;
- dvdyl = ((tv1 - tv0) << FIXP16_SHIFT)/dy;
- dxdyr = ((x2 - x0) << FIXP16_SHIFT)/dy;
- dudyr = ((tu2 - tu0) << FIXP16_SHIFT)/dy;
- dvdyr = ((tv2 - tv0) << FIXP16_SHIFT)/dy;
- // test for y clipping
- if (y0 < min_clip_y)
- {
- // compute overclip
- dy = (min_clip_y - y0);
- // computer new LHS starting values
- xl = dxdyl*dy + (x0 << FIXP16_SHIFT);
- ul = dudyl*dy + (tu0 << FIXP16_SHIFT);
- vl = dvdyl*dy + (tv0 << FIXP16_SHIFT);
- // compute new RHS starting values
- xr = dxdyr*dy + (x0 << FIXP16_SHIFT);
- ur = dudyr*dy + (tu0 << FIXP16_SHIFT);
- vr = dvdyr*dy + (tv0 << FIXP16_SHIFT);
- // compute new starting y
- ystart = min_clip_y;
- } // end if
- else
- {
- // no clipping
- // set starting values
- xl = (x0 << FIXP16_SHIFT);
- xr = (x0 << FIXP16_SHIFT);
- ul = (tu0 << FIXP16_SHIFT);
- vl = (tv0 << FIXP16_SHIFT);
- ur = (tu0 << FIXP16_SHIFT);
- vr = (tv0 << FIXP16_SHIFT);
- // set starting y
- ystart = y0;
- } // end else
- } // end else flat bottom
- // test for bottom clip, always
- if ((yend = y2) > max_clip_y)
- yend = max_clip_y;
- // test for horizontal clipping
- if ((x0 < min_clip_x) || (x0 > max_clip_x) ||
- (x1 < min_clip_x) || (x1 > max_clip_x) ||
- (x2 < min_clip_x) || (x2 > max_clip_x))
- {
- // clip version
- // point screen ptr to starting line
- screen_ptr = dest_buffer + (ystart * mem_pitch);
- for (yi = ystart; yi<=yend; yi++)
- {
- // compute span endpoints
- xstart = ((xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
- xend = ((xr + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
- // compute starting points for u,v interpolants
- ui = ul + FIXP16_ROUND_UP;
- vi = vl + FIXP16_ROUND_UP;
- // compute u,v interpolants
- if ((dx = (xend - xstart))>0)
- {
- du = (ur - ul)/dx;
- dv = (vr - vl)/dx;
- } // end if
- else
- {
- du = (ur - ul);
- dv = (vr - vl);
- } // end else
- ///////////////////////////////////////////////////////////////////////
- // test for x clipping, LHS
- if (xstart < min_clip_x)
- {
- // compute x overlap
- dx = min_clip_x - xstart;
- // slide interpolants over
- ui+=dx*du;
- vi+=dx*dv;
- // reset vars
- xstart = min_clip_x;
- } // end if
- // test for x clipping RHS
- if (xend > max_clip_x)
- xend = max_clip_x;
- ///////////////////////////////////////////////////////////////////////
- // draw span
- for (xi=xstart; xi<=xend; xi++)
- {
- // write textel
- screen_ptr[xi] = textmap[(ui >> FIXP16_SHIFT) + ((vi >> FIXP16_SHIFT) << texture_shift2)];
- // interpolate u,v
- ui+=du;
- vi+=dv;
- } // end for xi
- // interpolate u,v,x along right and left edge
- xl+=dxdyl;
- ul+=dudyl;
- vl+=dvdyl;
- xr+=dxdyr;
- ur+=dudyr;
- vr+=dvdyr;
- // advance screen ptr
- screen_ptr+=mem_pitch;
- } // end for y
- } // end if clip
- else
- {
- // non-clip version
- // point screen ptr to starting line
- screen_ptr = dest_buffer + (ystart * mem_pitch);
- for (yi = ystart; yi<=yend; yi++)
- {
- // compute span endpoints
- xstart = ((xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
- xend = ((xr + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
- // compute starting points for u,v interpolants
- ui = ul + FIXP16_ROUND_UP;
- vi = vl + FIXP16_ROUND_UP;
- // compute u,v interpolants
- if ((dx = (xend - xstart))>0)
- {
- du = (ur - ul)/dx;
- dv = (vr - vl)/dx;
- } // end if
- else
- {
- du = (ur - ul);
- dv = (vr - vl);
- } // end else
- // draw span
- for (xi=xstart; xi<=xend; xi++)
- {
- // write textel
- screen_ptr[xi] = textmap[(ui >> FIXP16_SHIFT) + ((vi >> FIXP16_SHIFT) << texture_shift2)];
- // interpolate u,v
- ui+=du;
- vi+=dv;
- } // end for xi
- // interpolate u,v,x along right and left edge
- xl+=dxdyl;
- ul+=dudyl;
- vl+=dvdyl;
- xr+=dxdyr;
- ur+=dudyr;
- vr+=dvdyr;
- // advance screen ptr
- screen_ptr+=mem_pitch;
- } // end for y
- } // end if non-clipped
- } // end if
- else
- if (tri_type==TRI_TYPE_GENERAL)
- {
- // first test for bottom clip, always
- if ((yend = y2) > max_clip_y)
- yend = max_clip_y;
- // pre-test y clipping status
- if (y1 < min_clip_y)
- {
- // compute all deltas
- // LHS
- dyl = (y2 - y1);
- dxdyl = ((x2 - x1) << FIXP16_SHIFT)/dyl;
- dudyl = ((tu2 - tu1) << FIXP16_SHIFT)/dyl;
- dvdyl = ((tv2 - tv1) << FIXP16_SHIFT)/dyl;
- // RHS
- dyr = (y2 - y0);
- dxdyr = ((x2 - x0) << FIXP16_SHIFT)/dyr;
- dudyr = ((tu2 - tu0) << FIXP16_SHIFT)/dyr;
- dvdyr = ((tv2 - tv0) << FIXP16_SHIFT)/dyr;
- // compute overclip
- dyr = (min_clip_y - y0);
- dyl = (min_clip_y - y1);
- // computer new LHS starting values
- xl = dxdyl*dyl + (x1 << FIXP16_SHIFT);
- ul = dudyl*dyl + (tu1 << FIXP16_SHIFT);
- vl = dvdyl*dyl + (tv1 << FIXP16_SHIFT);
- // compute new RHS starting values
- xr = dxdyr*dyr + (x0 << FIXP16_SHIFT);
- ur = dudyr*dyr + (tu0 << FIXP16_SHIFT);
- vr = dvdyr*dyr + (tv0 << FIXP16_SHIFT);
- // compute new starting y
- ystart = min_clip_y;
- // test if we need swap to keep rendering left to right
- if (dxdyr > dxdyl)
- {
- SWAP(dxdyl,dxdyr,temp);
- SWAP(dudyl,dudyr,temp);
- SWAP(dvdyl,dvdyr,temp);
- SWAP(xl,xr,temp);
- SWAP(ul,ur,temp);
- SWAP(vl,vr,temp);
- SWAP(x1,x2,temp);
- SWAP(y1,y2,temp);
- SWAP(tu1,tu2,temp);
- SWAP(tv1,tv2,temp);
- // set interpolation restart
- irestart = INTERP_RHS;
- } // end if
- } // end if
- else
- if (y0 < min_clip_y)
- {
- // compute all deltas
- // LHS
- dyl = (y1 - y0);
- dxdyl = ((x1 - x0) << FIXP16_SHIFT)/dyl;
- dudyl = ((tu1 - tu0) << FIXP16_SHIFT)/dyl;
- dvdyl = ((tv1 - tv0) << FIXP16_SHIFT)/dyl;
- // RHS
- dyr = (y2 - y0);
- dxdyr = ((x2 - x0) << FIXP16_SHIFT)/dyr;
- dudyr = ((tu2 - tu0) << FIXP16_SHIFT)/dyr;
- dvdyr = ((tv2 - tv0) << FIXP16_SHIFT)/dyr;
- // compute overclip
- dy = (min_clip_y - y0);
- // computer new LHS starting values
- xl = dxdyl*dy + (x0 << FIXP16_SHIFT);
- ul = dudyl*dy + (tu0 << FIXP16_SHIFT);
- vl = dvdyl*dy + (tv0 << FIXP16_SHIFT);
- // compute new RHS starting values
- xr = dxdyr*dy + (x0 << FIXP16_SHIFT);
- ur = dudyr*dy + (tu0 << FIXP16_SHIFT);
- vr = dvdyr*dy + (tv0 << FIXP16_SHIFT);
- // compute new starting y
- ystart = min_clip_y;
- // test if we need swap to keep rendering left to right
- if (dxdyr < dxdyl)
- {
- SWAP(dxdyl,dxdyr,temp);
- SWAP(dudyl,dudyr,temp);
- SWAP(dvdyl,dvdyr,temp);
- SWAP(xl,xr,temp);
- SWAP(ul,ur,temp);
- SWAP(vl,vr,temp);
- SWAP(x1,x2,temp);
- SWAP(y1,y2,temp);
- SWAP(tu1,tu2,temp);
- SWAP(tv1,tv2,temp);
- // set interpolation restart
- irestart = INTERP_RHS;
- } // end if
- } // end if
- else
- {
- // no initial y clipping
- // compute all deltas
- // LHS
- dyl = (y1 - y0);
- dxdyl = ((x1 - x0) << FIXP16_SHIFT)/dyl;
- dudyl = ((tu1 - tu0) << FIXP16_SHIFT)/dyl;
- dvdyl = ((tv1 - tv0) << FIXP16_SHIFT)/dyl;
- // RHS
- dyr = (y2 - y0);
- dxdyr = ((x2 - x0) << FIXP16_SHIFT)/dyr;
- dudyr = ((tu2 - tu0) << FIXP16_SHIFT)/dyr;
- dvdyr = ((tv2 - tv0) << FIXP16_SHIFT)/dyr;
- // no clipping y
- // set starting values
- xl = (x0 << FIXP16_SHIFT);
- xr = (x0 << FIXP16_SHIFT);
- ul = (tu0 << FIXP16_SHIFT);
- vl = (tv0 << FIXP16_SHIFT);
- ur = (tu0 << FIXP16_SHIFT);
- vr = (tv0 << FIXP16_SHIFT);
- // set starting y
- ystart = y0;
- // test if we need swap to keep rendering left to right
- if (dxdyr < dxdyl)
- {
- SWAP(dxdyl,dxdyr,temp);
- SWAP(dudyl,dudyr,temp);
- SWAP(dvdyl,dvdyr,temp);
- SWAP(xl,xr,temp);
- SWAP(ul,ur,temp);
- SWAP(vl,vr,temp);
- SWAP(x1,x2,temp);
- SWAP(y1,y2,temp);
- SWAP(tu1,tu2,temp);
- SWAP(tv1,tv2,temp);
- // set interpolation restart
- irestart = INTERP_RHS;
- } // end if
- } // end else
- // test for horizontal clipping
- if ((x0 < min_clip_x) || (x0 > max_clip_x) ||
- (x1 < min_clip_x) || (x1 > max_clip_x) ||
- (x2 < min_clip_x) || (x2 > max_clip_x))
- {
- // clip version
- // x clipping
- // point screen ptr to starting line
- screen_ptr = dest_buffer + (ystart * mem_pitch);
- for (yi = ystart; yi<=yend; yi++)
- {
- // compute span endpoints
- xstart = ((xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
- xend = ((xr + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
- // compute starting points for u,v interpolants
- ui = ul + FIXP16_ROUND_UP;
- vi = vl + FIXP16_ROUND_UP;
- // compute u,v interpolants
- if ((dx = (xend - xstart))>0)
- {
- du = (ur - ul)/dx;
- dv = (vr - vl)/dx;
- } // end if
- else
- {
- du = (ur - ul);
- dv = (vr - vl);
- } // end else
- ///////////////////////////////////////////////////////////////////////
- // test for x clipping, LHS
- if (xstart < min_clip_x)
- {
- // compute x overlap
- dx = min_clip_x - xstart;
- // slide interpolants over
- ui+=dx*du;
- vi+=dx*dv;
- // set x to left clip edge
- xstart = min_clip_x;
- } // end if
- // test for x clipping RHS
- if (xend > max_clip_x)
- xend = max_clip_x;
- ///////////////////////////////////////////////////////////////////////
- // draw span
- for (xi=xstart; xi<=xend; xi++)
- {
- // write textel
- screen_ptr[xi] = textmap[(ui >> FIXP16_SHIFT) + ((vi >> FIXP16_SHIFT) << texture_shift2)];
- // interpolate u,v
- ui+=du;
- vi+=dv;
- } // end for xi
- // interpolate u,v,x along right and left edge
- xl+=dxdyl;
- ul+=dudyl;
- vl+=dvdyl;
- xr+=dxdyr;
- ur+=dudyr;
- vr+=dvdyr;
- // advance screen ptr
- screen_ptr+=mem_pitch;
- // test for yi hitting second region, if so change interpolant
- if (yi==yrestart)
- {
- // test interpolation side change flag
- if (irestart == INTERP_LHS)
- {
- // LHS
- dyl = (y2 - y1);
- dxdyl = ((x2 - x1) << FIXP16_SHIFT)/dyl;
- dudyl = ((tu2 - tu1) << FIXP16_SHIFT)/dyl;
- dvdyl = ((tv2 - tv1) << FIXP16_SHIFT)/dyl;
- // set starting values
- xl = (x1 << FIXP16_SHIFT);
- ul = (tu1 << FIXP16_SHIFT);
- vl = (tv1 << FIXP16_SHIFT);
- // interpolate down on LHS to even up
- xl+=dxdyl;
- ul+=dudyl;
- vl+=dvdyl;
- } // end if
- else
- {
- // RHS
- dyr = (y1 - y2);
- dxdyr = ((x1 - x2) << FIXP16_SHIFT)/dyr;
- dudyr = ((tu1 - tu2) << FIXP16_SHIFT)/dyr;
- dvdyr = ((tv1 - tv2) << FIXP16_SHIFT)/dyr;
- // set starting values
- xr = (x2 << FIXP16_SHIFT);
- ur = (tu2 << FIXP16_SHIFT);
- vr = (tv2 << FIXP16_SHIFT);
- // interpolate down on RHS to even up
- xr+=dxdyr;
- ur+=dudyr;
- vr+=dvdyr;
- } // end else
- } // end if
- } // end for y
- } // end if
- else
- {
- // no x clipping
- // point screen ptr to starting line
- screen_ptr = dest_buffer + (ystart * mem_pitch);
- for (yi = ystart; yi<=yend; yi++)
- {
- // compute span endpoints
- xstart = ((xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
- xend = ((xr + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
- // compute starting points for u,v interpolants
- ui = ul + FIXP16_ROUND_UP;
- vi = vl + FIXP16_ROUND_UP;
- // compute u,v interpolants
- if ((dx = (xend - xstart))>0)
- {
- du = (ur - ul)/dx;
- dv = (vr - vl)/dx;
- } // end if
- else
- {
- du = (ur - ul);
- dv = (vr - vl);
- } // end else
- // draw span
- for (xi=xstart; xi<=xend; xi++)
- {
- // write textel
- screen_ptr[xi] = textmap[(ui >> FIXP16_SHIFT) + ((vi >> FIXP16_SHIFT) << texture_shift2)];
- // interpolate u,v
- ui+=du;
- vi+=dv;
- } // end for xi
- // interpolate u,v,x along right and left edge
- xl+=dxdyl;
- ul+=dudyl;
- vl+=dvdyl;
- xr+=dxdyr;
- ur+=dudyr;
- vr+=dvdyr;
- // advance screen ptr
- screen_ptr+=mem_pitch;
- // test for yi hitting second region, if so change interpolant
- if (yi==yrestart)
- {
- // test interpolation side change flag
- if (irestart == INTERP_LHS)
- {
- // LHS
- dyl = (y2 - y1);
- dxdyl = ((x2 - x1) << FIXP16_SHIFT)/dyl;
- dudyl = ((tu2 - tu1) << FIXP16_SHIFT)/dyl;
- dvdyl = ((tv2 - tv1) << FIXP16_SHIFT)/dyl;
- // set starting values
- xl = (x1 << FIXP16_SHIFT);
- ul = (tu1 << FIXP16_SHIFT);
- vl = (tv1 << FIXP16_SHIFT);
- // interpolate down on LHS to even up
- xl+=dxdyl;
- ul+=dudyl;
- vl+=dvdyl;
- } // end if
- else
- {
- // RHS
- dyr = (y1 - y2);
- dxdyr = ((x1 - x2) << FIXP16_SHIFT)/dyr;
- dudyr = ((tu1 - tu2) << FIXP16_SHIFT)/dyr;
- dvdyr = ((tv1 - tv2) << FIXP16_SHIFT)/dyr;
- // set starting values
- xr = (x2 << FIXP16_SHIFT);
- ur = (tu2 << FIXP16_SHIFT);
- vr = (tv2 << FIXP16_SHIFT);
- // interpolate down on RHS to even up
- xr+=dxdyr;
- ur+=dudyr;
- vr+=dvdyr;
- } // end else
- } // end if
- } // end for y
- } // end else
- } // end if
- } // end Draw_Textured_Triangle
- //////////////////////////////////////////////////////////////////////
- void Draw_Textured_TriangleFS(POLYF4DV2_PTR face, // ptr to face
- UCHAR *dest_buffer, // pointer to video buffer
- int mem_pitch) // bytes per line, 320, 640 etc.
- {
- // this function draws a textured triangle in 8-bit mode
- int v0=0,
- v1=1,
- v2=2,
- temp=0,
- tri_type = TRI_TYPE_NONE,
- irestart = INTERP_LHS;
- int dx,dy,dyl,dyr, // general deltas
- u,v,
- du,dv,
- xi,yi, // the current interpolated x,y
- ui,vi, // the current interpolated u,v
- index_x,index_y, // looping vars
- x,y, // hold general x,y
- xstart,
- xend,
- ystart,
- yrestart,
- yend,
- xl,
- dxdyl,
- xr,
- dxdyr,
- dudyl,
- ul,
- dvdyl,
- vl,
- dudyr,
- ur,
- dvdyr,
- vr;
- int x0,y0,tu0,tv0, // cached vertices
- x1,y1,tu1,tv1,
- x2,y2,tu2,tv2;
- int r_base, g_base, b_base, base_rgb444, textel; // used for color modulation algorithm to light texture
- UCHAR *screen_ptr = NULL,
- *screen_line = NULL,
- *textmap = NULL,
- *lightrow444_8 = NULL;
- #ifdef DEBUG_ON
- // track rendering stats
- debug_polys_rendered_per_frame++;
- #endif
- // extract texture map
- textmap = face->texture->buffer;
- // extract base 2 of texture width
- int texture_shift2 = logbase2ofx[face->texture->width];
- // first trivial clipping rejection tests
- if (((face->tvlist[0].y < min_clip_y) &&
- (face->tvlist[1].y < min_clip_y) &&
- (face->tvlist[2].y < min_clip_y)) ||
- ((face->tvlist[0].y > max_clip_y) &&
- (face->tvlist[1].y > max_clip_y) &&
- (face->tvlist[2].y > max_clip_y)) ||
- ((face->tvlist[0].x < min_clip_x) &&
- (face->tvlist[1].x < min_clip_x) &&
- (face->tvlist[2].x < min_clip_x)) ||
- ((face->tvlist[0].x > max_clip_x) &&
- (face->tvlist[1].x > max_clip_x) &&
- (face->tvlist[2].x > max_clip_x)))
- return;
- // degenerate triangle
- if ( ((face->tvlist[0].x==face->tvlist[1].x) && (face->tvlist[1].x==face->tvlist[2].x)) ||
- ((face->tvlist[0].y==face->tvlist[1].y) && (face->tvlist[1].y==face->tvlist[2].y)))
- return;
- // sort vertices
- if (face->tvlist[v1].y < face->tvlist[v0].y)
- {SWAP(v0,v1,temp);}
- if (face->tvlist[v2].y < face->tvlist[v0].y)
- {SWAP(v0,v2,temp);}
- if (face->tvlist[v2].y < face->tvlist[v1].y)
- {SWAP(v1,v2,temp);}
- // now test for trivial flat sided cases
- if (face->tvlist[v0].y==face->tvlist[v1].y)
- {
- // set triangle type
- tri_type = TRI_TYPE_FLAT_TOP;
- // sort vertices left to right
- if (face->tvlist[v1].x < face->tvlist[v0].x)
- {SWAP(v0,v1,temp);}
- } // end if
- else
- // now test for trivial flat sided cases
- if (face->tvlist[v1].y==face->tvlist[v2].y)
- {
- // set triangle type
- tri_type = TRI_TYPE_FLAT_BOTTOM;
- // sort vertices left to right
- if (face->tvlist[v2].x < face->tvlist[v1].x)
- {SWAP(v1,v2,temp);}
- } // end if
- else
- {
- // must be a general triangle
- tri_type = TRI_TYPE_GENERAL;
- } // end else
- // extract base color of lit poly, so we can modulate texture a bit
- // for lighting
- r_base = palette[face->lit_color[0]].peRed;
- g_base = palette[face->lit_color[0]].peGreen;
- b_base = palette[face->lit_color[0]].peBlue;
- // build 4.4.4 intensity for color modulation
- base_rgb444 = ( (b_base >> 4) + ((g_base >> 4) << 4) + ((r_base >> 4) << 8) );
- // now find row in light table we will need for the r,g,b values on this polygon
- lightrow444_8 = rgblightlookup[base_rgb444];
- // extract vertices for processing, now that we have order
- x0 = (int)(face->tvlist[v0].x+0.5);
- y0 = (int)(face->tvlist[v0].y+0.5);
- tu0 = (int)(face->tvlist[v0].u0);
- tv0 = (int)(face->tvlist[v0].v0);
- x1 = (int)(face->tvlist[v1].x+0.5);
- y1 = (int)(face->tvlist[v1].y+0.5);
- tu1 = (int)(face->tvlist[v1].u0);
- tv1 = (int)(face->tvlist[v1].v0);
- x2 = (int)(face->tvlist[v2].x+0.5);
- y2 = (int)(face->tvlist[v2].y+0.5);
- tu2 = (int)(face->tvlist[v2].u0);
- tv2 = (int)(face->tvlist[v2].v0);
- // set interpolation restart value
- yrestart = y1;
- // what kind of triangle
- if (tri_type & TRI_TYPE_FLAT_MASK)
- {
- if (tri_type == TRI_TYPE_FLAT_TOP)
- {
- // compute all deltas
- dy = (y2 - y0);
- dxdyl = ((x2 - x0) << FIXP16_SHIFT)/dy;
- dudyl = ((tu2 - tu0) << FIXP16_SHIFT)/dy;
- dvdyl = ((tv2 - tv0) << FIXP16_SHIFT)/dy;
- dxdyr = ((x2 - x1) << FIXP16_SHIFT)/dy;
- dudyr = ((tu2 - tu1) << FIXP16_SHIFT)/dy;
- dvdyr = ((tv2 - tv1) << FIXP16_SHIFT)/dy;
- // test for y clipping
- if (y0 < min_clip_y)
- {
- // compute overclip
- dy = (min_clip_y - y0);
- // computer new LHS starting values
- xl = dxdyl*dy + (x0 << FIXP16_SHIFT);
- ul = dudyl*dy + (tu0 << FIXP16_SHIFT);
- vl = dvdyl*dy + (tv0 << FIXP16_SHIFT);
- // compute new RHS starting values
- xr = dxdyr*dy + (x1 << FIXP16_SHIFT);
- ur = dudyr*dy + (tu1 << FIXP16_SHIFT);
- vr = dvdyr*dy + (tv1 << FIXP16_SHIFT);
- // compute new starting y
- ystart = min_clip_y;
- } // end if
- else
- {
- // no clipping
- // set starting values
- xl = (x0 << FIXP16_SHIFT);
- xr = (x1 << FIXP16_SHIFT);
- ul = (tu0 << FIXP16_SHIFT);
- vl = (tv0 << FIXP16_SHIFT);
- ur = (tu1 << FIXP16_SHIFT);
- vr = (tv1 << FIXP16_SHIFT);
- // set starting y
- ystart = y0;
- } // end else
- } // end if flat top
- else
- {
- // must be flat bottom
- // compute all deltas
- dy = (y1 - y0);
- dxdyl = ((x1 - x0) << FIXP16_SHIFT)/dy;
- dudyl = ((tu1 - tu0) << FIXP16_SHIFT)/dy;
- dvdyl = ((tv1 - tv0) << FIXP16_SHIFT)/dy;
- dxdyr = ((x2 - x0) << FIXP16_SHIFT)/dy;
- dudyr = ((tu2 - tu0) << FIXP16_SHIFT)/dy;
- dvdyr = ((tv2 - tv0) << FIXP16_SHIFT)/dy;
- // test for y clipping
- if (y0 < min_clip_y)
- {
- // compute overclip
- dy = (min_clip_y - y0);
- // computer new LHS starting values
- xl = dxdyl*dy + (x0 << FIXP16_SHIFT);
- ul = dudyl*dy + (tu0 << FIXP16_SHIFT);
- vl = dvdyl*dy + (tv0 << FIXP16_SHIFT);
- // compute new RHS starting values
- xr = dxdyr*dy + (x0 << FIXP16_SHIFT);
- ur = dudyr*dy + (tu0 << FIXP16_SHIFT);
- vr = dvdyr*dy + (tv0 << FIXP16_SHIFT);
- // compute new starting y
- ystart = min_clip_y;
- } // end if
- else
- {
- // no clipping
- // set starting values
- xl = (x0 << FIXP16_SHIFT);
- xr = (x0 << FIXP16_SHIFT);
- ul = (tu0 << FIXP16_SHIFT);
- vl = (tv0 << FIXP16_SHIFT);
- ur = (tu0 << FIXP16_SHIFT);
- vr = (tv0 << FIXP16_SHIFT);
- // set starting y
- ystart = y0;
- } // end else
- } // end else flat bottom
- // test for bottom clip, always
- if ((yend = y2) > max_clip_y)
- yend = max_clip_y;
- // test for horizontal clipping
- if ((x0 < min_clip_x) || (x0 > max_clip_x) ||
- (x1 < min_clip_x) || (x1 > max_clip_x) ||
- (x2 < min_clip_x) || (x2 > max_clip_x))
- {
- // clip version
- // point screen ptr to starting line
- screen_ptr = dest_buffer + (ystart * mem_pitch);
- for (yi = ystart; yi<=yend; yi++)
- {
- // compute span endpoints
- xstart = ((xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
- xend = ((xr + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
- // compute starting points for u,v interpolants
- ui = ul + FIXP16_ROUND_UP;
- vi = vl + FIXP16_ROUND_UP;
- // compute u,v interpolants
- if ((dx = (xend - xstart))>0)
- {
- du = (ur - ul)/dx;
- dv = (vr - vl)/dx;
- } // end if
- else
- {
- du = (ur - ul);
- dv = (vr - vl);
- } // end else
- ///////////////////////////////////////////////////////////////////////
- // test for x clipping, LHS
- if (xstart < min_clip_x)
- {
- // compute x overlap
- dx = min_clip_x - xstart;
- // slide interpolants over
- ui+=dx*du;
- vi+=dx*dv;
- // reset vars
- xstart = min_clip_x;
- } // end if
- // test for x clipping RHS
- if (xend > max_clip_x)
- xend = max_clip_x;
- ///////////////////////////////////////////////////////////////////////
- // draw span
- for (xi=xstart; xi<=xend; xi++)
- {
- // write textel
- // get textel
- textel = textmap[(ui >> FIXP16_SHIFT) + ((vi >> FIXP16_SHIFT) << texture_shift2)];
- // modulate with base color via light table and write textel
- screen_ptr[xi] = lightrow444_8[textel];
- // interpolate u,v
- ui+=du;
- vi+=dv;
- } // end for xi
- // interpolate u,v,x along right and left edge
- xl+=dxdyl;
- ul+=dudyl;
- vl+=dvdyl;
- xr+=dxdyr;
- ur+=dudyr;
- vr+=dvdyr;
- // advance screen ptr
- screen_ptr+=mem_pitch;
- } // end for y
- } // end if clip
- else
- {
- // non-clip version
- // point screen ptr to starting line
- screen_ptr = dest_buffer + (ystart * mem_pitch);
- for (yi = ystart; yi<=yend; yi++)
- {
- // compute span endpoints
- xstart = ((xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
- xend = ((xr + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
- // compute starting points for u,v interpolants
- ui = ul + FIXP16_ROUND_UP;
- vi = vl + FIXP16_ROUND_UP;
- // compute u,v interpolants
- if ((dx = (xend - xstart))>0)
- {
- du = (ur - ul)/dx;
- dv = (vr - vl)/dx;
- } // end if
- else
- {
- du = (ur - ul);
- dv = (vr - vl);
- } // end else
- // draw span
- for (xi=xstart; xi<=xend; xi++)
- {
- // write textel
- // get textel
- textel = textmap[(ui >> FIXP16_SHIFT) + ((vi >> FIXP16_SHIFT) << texture_shift2)];
- // modulate with base color via light table and write textel
- screen_ptr[xi] = lightrow444_8[textel];
- // interpolate u,v
- ui+=du;
- vi+=dv;
- } // end for xi
- // interpolate u,v,x along right and left edge
- xl+=dxdyl;
- ul+=dudyl;
- vl+=dvdyl;
- xr+=dxdyr;
- ur+=dudyr;
- vr+=dvdyr;
- // advance screen ptr
- screen_ptr+=mem_pitch;
- } // end for y
- } // end if non-clipped
- } // end if
- else
- if (tri_type==TRI_TYPE_GENERAL)
- {
- // first test for bottom clip, always
- if ((yend = y2) > max_clip_y)
- yend = max_clip_y;
- // pre-test y clipping status
- if (y1 < min_clip_y)
- {
- // compute all deltas
- // LHS
- dyl = (y2 - y1);
- dxdyl = ((x2 - x1) << FIXP16_SHIFT)/dyl;
- dudyl = ((tu2 - tu1) << FIXP16_SHIFT)/dyl;
- dvdyl = ((tv2 - tv1) << FIXP16_SHIFT)/dyl;
- // RHS
- dyr = (y2 - y0);
- dxdyr = ((x2 - x0) << FIXP16_SHIFT)/dyr;
- dudyr = ((tu2 - tu0) << FIXP16_SHIFT)/dyr;
- dvdyr = ((tv2 - tv0) << FIXP16_SHIFT)/dyr;
- // compute overclip
- dyr = (min_clip_y - y0);
- dyl = (min_clip_y - y1);
- // computer new LHS starting values
- xl = dxdyl*dyl + (x1 << FIXP16_SHIFT);
- ul = dudyl*dyl + (tu1 << FIXP16_SHIFT);
- vl = dvdyl*dyl + (tv1 << FIXP16_SHIFT);
- // compute new RHS starting values
- xr = dxdyr*dyr + (x0 << FIXP16_SHIFT);
- ur = dudyr*dyr + (tu0 << FIXP16_SHIFT);
- vr = dvdyr*dyr + (tv0 << FIXP16_SHIFT);
- // compute new starting y
- ystart = min_clip_y;
- // test if we need swap to keep rendering left to right
- if (dxdyr > dxdyl)
- {
- SWAP(dxdyl,dxdyr,temp);
- SWAP(dudyl,dudyr,temp);
- SWAP(dvdyl,dvdyr,temp);
- SWAP(xl,xr,temp);
- SWAP(ul,ur,temp);
- SWAP(vl,vr,temp);
- SWAP(x1,x2,temp);
- SWAP(y1,y2,temp);
- SWAP(tu1,tu2,temp);
- SWAP(tv1,tv2,temp);
- // set interpolation restart
- irestart = INTERP_RHS;
- } // end if
- } // end if
- else
- if (y0 < min_clip_y)
- {
- // compute all deltas
- // LHS
- dyl = (y1 - y0);
- dxdyl = ((x1 - x0) << FIXP16_SHIFT)/dyl;
- dudyl = ((tu1 - tu0) << FIXP16_SHIFT)/dyl;
- dvdyl = ((tv1 - tv0) << FIXP16_SHIFT)/dyl;
- // RHS
- dyr = (y2 - y0);
- dxdyr = ((x2 - x0) << FIXP16_SHIFT)/dyr;
- dudyr = ((tu2 - tu0) << FIXP16_SHIFT)/dyr;
- dvdyr = ((tv2 - tv0) << FIXP16_SHIFT)/dyr;
- // compute overclip
- dy = (min_clip_y - y0);
- // computer new LHS starting values
- xl = dxdyl*dy + (x0 << FIXP16_SHIFT);
- ul = dudyl*dy + (tu0 << FIXP16_SHIFT);
- vl = dvdyl*dy + (tv0 << FIXP16_SHIFT);
- // compute new RHS starting values
- xr = dxdyr*dy + (x0 << FIXP16_SHIFT);
- ur = dudyr*dy + (tu0 << FIXP16_SHIFT);
- vr = dvdyr*dy + (tv0 << FIXP16_SHIFT);
- // compute new starting y
- ystart = min_clip_y;
- // test if we need swap to keep rendering left to right
- if (dxdyr < dxdyl)
- {
- SWAP(dxdyl,dxdyr,temp);
- SWAP(dudyl,dudyr,temp);
- SWAP(dvdyl,dvdyr,temp);
- SWAP(xl,xr,temp);
- SWAP(ul,ur,temp);
- SWAP(vl,vr,temp);
- SWAP(x1,x2,temp);
- SWAP(y1,y2,temp);
- SWAP(tu1,tu2,temp);
- SWAP(tv1,tv2,temp);
- // set interpolation restart
- irestart = INTERP_RHS;
- } // end if
- } // end if
- else
- {
- // no initial y clipping
- // compute all deltas
- // LHS
- dyl = (y1 - y0);
- dxdyl = ((x1 - x0) << FIXP16_SHIFT)/dyl;
- dudyl = ((tu1 - tu0) << FIXP16_SHIFT)/dyl;
- dvdyl = ((tv1 - tv0) << FIXP16_SHIFT)/dyl;
- // RHS
- dyr = (y2 - y0);
- dxdyr = ((x2 - x0) << FIXP16_SHIFT)/dyr;
- dudyr = ((tu2 - tu0) << FIXP16_SHIFT)/dyr;
- dvdyr = ((tv2 - tv0) << FIXP16_SHIFT)/dyr;
- // no clipping y
- // set starting values
- xl = (x0 << FIXP16_SHIFT);
- xr = (x0 << FIXP16_SHIFT);
- ul = (tu0 << FIXP16_SHIFT);
- vl = (tv0 << FIXP16_SHIFT);
- ur = (tu0 << FIXP16_SHIFT);
- vr = (tv0 << FIXP16_SHIFT);
- // set starting y
- ystart = y0;
- // test if we need swap to keep rendering left to right
- if (dxdyr < dxdyl)
- {
- SWAP(dxdyl,dxdyr,temp);
- SWAP(dudyl,dudyr,temp);
- SWAP(dvdyl,dvdyr,temp);
- SWAP(xl,xr,temp);
- SWAP(ul,ur,temp);
- SWAP(vl,vr,temp);
- SWAP(x1,x2,temp);
- SWAP(y1,y2,temp);
- SWAP(tu1,tu2,temp);
- SWAP(tv1,tv2,temp);
- // set interpolation restart
- irestart = INTERP_RHS;
- } // end if
- } // end else
- // test for horizontal clipping
- if ((x0 < min_clip_x) || (x0 > max_clip_x) ||
- (x1 < min_clip_x) || (x1 > max_clip_x) ||
- (x2 < min_clip_x) || (x2 > max_clip_x))
- {
- // clip version
- // x clipping
- // point screen ptr to starting line
- screen_ptr = dest_buffer + (ystart * mem_pitch);
- for (yi = ystart; yi<=yend; yi++)
- {
- // compute span endpoints
- xstart = ((xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
- xend = ((xr + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
- // compute starting points for u,v interpolants
- ui = ul + FIXP16_ROUND_UP;
- vi = vl + FIXP16_ROUND_UP;
- // compute u,v interpolants
- if ((dx = (xend - xstart))>0)
- {
- du = (ur - ul)/dx;
- dv = (vr - vl)/dx;
- } // end if
- else
- {
- du = (ur - ul);
- dv = (vr - vl);
- } // end else
- ///////////////////////////////////////////////////////////////////////
- // test for x clipping, LHS
- if (xstart < min_clip_x)
- {
- // compute x overlap
- dx = min_clip_x - xstart;
- // slide interpolants over
- ui+=dx*du;
- vi+=dx*dv;
- // set x to left clip edge
- xstart = min_clip_x;
- } // end if
- // test for x clipping RHS
- if (xend > max_clip_x)
- xend = max_clip_x;
- ///////////////////////////////////////////////////////////////////////
- // draw span
- for (xi=xstart; xi<=xend; xi++)
- {
- // write textel
- // get textel
- textel = textmap[(ui >> FIXP16_SHIFT) + ((vi >> FIXP16_SHIFT) << texture_shift2)];
- // modulate with base color via light table and write textel
- screen_ptr[xi] = lightrow444_8[textel];
- // interpolate u,v
- ui+=du;
- vi+=dv;
- } // end for xi
- // interpolate u,v,x along right and left edge
- xl+=dxdyl;
- ul+=dudyl;
- vl+=dvdyl;
- xr+=dxdyr;
- ur+=dudyr;
- vr+=dvdyr;
- // advance screen ptr
- screen_ptr+=mem_pitch;
- // test for yi hitting second region, if so change interpolant
- if (yi==yrestart)
- {
- // test interpolation side change flag
- if (irestart == INTERP_LHS)
- {
- // LHS
- dyl = (y2 - y1);
- dxdyl = ((x2 - x1) << FIXP16_SHIFT)/dyl;
- dudyl = ((tu2 - tu1) << FIXP16_SHIFT)/dyl;
- dvdyl = ((tv2 - tv1) << FIXP16_SHIFT)/dyl;
- // set starting values
- xl = (x1 << FIXP16_SHIFT);
- ul = (tu1 << FIXP16_SHIFT);
- vl = (tv1 << FIXP16_SHIFT);
- // interpolate down on LHS to even up
- xl+=dxdyl;
- ul+=dudyl;
- vl+=dvdyl;
- } // end if
- else
- {
- // RHS
- dyr = (y1 - y2);
- dxdyr = ((x1 - x2) << FIXP16_SHIFT)/dyr;
- dudyr = ((tu1 - tu2) << FIXP16_SHIFT)/dyr;
- dvdyr = ((tv1 - tv2) << FIXP16_SHIFT)/dyr;
- // set starting values
- xr = (x2 << FIXP16_SHIFT);
- ur = (tu2 << FIXP16_SHIFT);
- vr = (tv2 << FIXP16_SHIFT);
- // interpolate down on RHS to even up
- xr+=dxdyr;
- ur+=dudyr;
- vr+=dvdyr;
- } // end else
- } // end if
- } // end for y
- } // end if
- else
- {
- // no x clipping
- // point screen ptr to starting line
- screen_ptr = dest_buffer + (ystart * mem_pitch);
- for (yi = ystart; yi<=yend; yi++)
- {
- // compute span endpoints
- xstart = ((xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
- xend = ((xr + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
- // compute starting points for u,v interpolants
- ui = ul + FIXP16_ROUND_UP;
- vi = vl + FIXP16_ROUND_UP;
- // compute u,v interpolants
- if ((dx = (xend - xstart))>0)
- {
- du = (ur - ul)/dx;
- dv = (vr - vl)/dx;
- } // end if
- else
- {
- du = (ur - ul);
- dv = (vr - vl);
- } // end else
- // draw span
- for (xi=xstart; xi<=xend; xi++)
- {
- // write textel
- // get textel
- textel = textmap[(ui >> FIXP16_SHIFT) + ((vi >> FIXP16_SHIFT) << texture_shift2)];
- // modulate with base color via light table and write textel
- screen_ptr[xi] = lightrow444_8[textel];
- // interpolate u,v
- ui+=du;
- vi+=dv;
- } // end for xi
- // interpolate u,v,x along right and left edge
- xl+=dxdyl;
- ul+=dudyl;
- vl+=dvdyl;
- xr+=dxdyr;
- ur+=dudyr;
- vr+=dvdyr;
- // advance screen ptr
- screen_ptr+=mem_pitch;
- // test for yi hitting second region, if so change interpolant
- if (yi==yrestart)
- {
- // test interpolation side change flag
- if (irestart == INTERP_LHS)
- {
- // LHS
- dyl = (y2 - y1);
- dxdyl = ((x2 - x1) << FIXP16_SHIFT)/dyl;
- dudyl = ((tu2 - tu1) << FIXP16_SHIFT)/dyl;
- dvdyl = ((tv2 - tv1) << FIXP16_SHIFT)/dyl;
- // set starting values
- xl = (x1 << FIXP16_SHIFT);
- ul = (tu1 << FIXP16_SHIFT);
- vl = (tv1 << FIXP16_SHIFT);
- // interpolate down on LHS to even up
- xl+=dxdyl;
- ul+=dudyl;
- vl+=dvdyl;
- } // end if
- else
- {
- // RHS
- dyr = (y1 - y2);
- dxdyr = ((x1 - x2) << FIXP16_SHIFT)/dyr;
- dudyr = ((tu1 - tu2) << FIXP16_SHIFT)/dyr;
- dvdyr = ((tv1 - tv2) << FIXP16_SHIFT)/dyr;
- // set starting values
- xr = (x2 << FIXP16_SHIFT);
- ur = (tu2 << FIXP16_SHIFT);
- vr = (tv2 << FIXP16_SHIFT);
- // interpolate down on RHS to even up
- xr+=dxdyr;
- ur+=dudyr;
- vr+=dvdyr;
- } // end else
- } // end if
- } // end for y
- } // end else
- } // end if
- } // end Draw_Textured_TriangleFS
- /////////////////////////////////////////////////////////////
- void Draw_Textured_Triangle16(POLYF4DV2_PTR face, // ptr to face
- UCHAR *_dest_buffer, // pointer to video buffer
- int mem_pitch) // bytes per line, 320, 640 etc.
- {
- // this function draws a textured triangle in 16-bit mode
- int v0=0,
- v1=1,
- v2=2,
- temp=0,
- tri_type = TRI_TYPE_NONE,
- irestart = INTERP_LHS;
- int dx,dy,dyl,dyr, // general deltas
- u,v,
- du,dv,
- xi,yi, // the current interpolated x,y
- ui,vi, // the current interpolated u,v
- index_x,index_y, // looping vars
- x,y, // hold general x,y
- xstart,
- xend,
- ystart,
- yrestart,
- yend,
- xl,
- dxdyl,
- xr,
- dxdyr,
- dudyl,
- ul,
- dvdyl,
- vl,
- dudyr,
- ur,
- dvdyr,
- vr;
- int x0,y0,tu0,tv0, // cached vertices
- x1,y1,tu1,tv1,
- x2,y2,tu2,tv2;
- USHORT *screen_ptr = NULL,
- *screen_line = NULL,
- *textmap = NULL,
- *dest_buffer = (USHORT *)_dest_buffer;
- #ifdef DEBUG_ON
- // track rendering stats
- debug_polys_rendered_per_frame++;
- #endif
- // extract texture map
- textmap = (USHORT *)face->texture->buffer;
- // extract base 2 of texture width
- int texture_shift2 = logbase2ofx[face->texture->width];
- // adjust memory pitch to words, divide by 2
- mem_pitch >>=1;
- // first trivial clipping rejection tests
- if (((face->tvlist[0].y < min_clip_y) &&
- (face->tvlist[1].y < min_clip_y) &&
- (face->tvlist[2].y < min_clip_y)) ||
- ((face->tvlist[0].y > max_clip_y) &&
- (face->tvlist[1].y > max_clip_y) &&
- (face->tvlist[2].y > max_clip_y)) ||
- ((face->tvlist[0].x < min_clip_x) &&
- (face->tvlist[1].x < min_clip_x) &&
- (face->tvlist[2].x < min_clip_x)) ||
- ((face->tvlist[0].x > max_clip_x) &&
- (face->tvlist[1].x > max_clip_x) &&
- (face->tvlist[2].x > max_clip_x)))
- return;
- // degenerate triangle
- if ( ((face->tvlist[0].x==face->tvlist[1].x) && (face->tvlist[1].x==face->tvlist[2].x)) ||
- ((face->tvlist[0].y==face->tvlist[1].y) && (face->tvlist[1].y==face->tvlist[2].y)))
- return;
- // sort vertices
- if (face->tvlist[v1].y < face->tvlist[v0].y)
- {SWAP(v0,v1,temp);}
- if (face->tvlist[v2].y < face->tvlist[v0].y)
- {SWAP(v0,v2,temp);}
- if (face->tvlist[v2].y < face->tvlist[v1].y)
- {SWAP(v1,v2,temp);}
- // now test for trivial flat sided cases
- if (face->tvlist[v0].y==face->tvlist[v1].y)
- {
- // set triangle type
- tri_type = TRI_TYPE_FLAT_TOP;
- // sort vertices left to right
- if (face->tvlist[v1].x < face->tvlist[v0].x)
- {SWAP(v0,v1,temp);}
- } // end if
- else
- // now test for trivial flat sided cases
- if (face->tvlist[v1].y==face->tvlist[v2].y)
- {
- // set triangle type
- tri_type = TRI_TYPE_FLAT_BOTTOM;
- // sort vertices left to right
- if (face->tvlist[v2].x < face->tvlist[v1].x)
- {SWAP(v1,v2,temp);}
- } // end if
- else
- {
- // must be a general triangle
- tri_type = TRI_TYPE_GENERAL;
- } // end else
- // extract vertices for processing, now that we have order
- x0 = (int)(face->tvlist[v0].x+0.5);
- y0 = (int)(face->tvlist[v0].y+0.5);
- tu0 = (int)(face->tvlist[v0].u0);
- tv0 = (int)(face->tvlist[v0].v0);
- x1 = (int)(face->tvlist[v1].x+0.5);
- y1 = (int)(face->tvlist[v1].y+0.5);
- tu1 = (int)(face->tvlist[v1].u0);
- tv1 = (int)(face->tvlist[v1].v0);
- x2 = (int)(face->tvlist[v2].x+0.5);
- y2 = (int)(face->tvlist[v2].y+0.5);
- tu2 = (int)(face->tvlist[v2].u0);
- tv2 = (int)(face->tvlist[v2].v0);
- // set interpolation restart value
- yrestart = y1;
- // what kind of triangle
- if (tri_type & TRI_TYPE_FLAT_MASK)
- {
- if (tri_type == TRI_TYPE_FLAT_TOP)
- {
- // compute all deltas
- dy = (y2 - y0);
- dxdyl = ((x2 - x0) << FIXP16_SHIFT)/dy;
- dudyl = ((tu2 - tu0) << FIXP16_SHIFT)/dy;
- dvdyl = ((tv2 - tv0) << FIXP16_SHIFT)/dy;
- dxdyr = ((x2 - x1) << FIXP16_SHIFT)/dy;
- dudyr = ((tu2 - tu1) << FIXP16_SHIFT)/dy;
- dvdyr = ((tv2 - tv1) << FIXP16_SHIFT)/dy;
- // test for y clipping
- if (y0 < min_clip_y)
- {
- // compute overclip
- dy = (min_clip_y - y0);
- // computer new LHS starting values
- xl = dxdyl*dy + (x0 << FIXP16_SHIFT);
- ul = dudyl*dy + (tu0 << FIXP16_SHIFT);
- vl = dvdyl*dy + (tv0 << FIXP16_SHIFT);
- // compute new RHS starting values
- xr = dxdyr*dy + (x1 << FIXP16_SHIFT);
- ur = dudyr*dy + (tu1 << FIXP16_SHIFT);
- vr = dvdyr*dy + (tv1 << FIXP16_SHIFT);
- // compute new starting y
- ystart = min_clip_y;
- } // end if
- else
- {
- // no clipping
- // set starting values
- xl = (x0 << FIXP16_SHIFT);
- xr = (x1 << FIXP16_SHIFT);
- ul = (tu0 << FIXP16_SHIFT);
- vl = (tv0 << FIXP16_SHIFT);
- ur = (tu1 << FIXP16_SHIFT);
- vr = (tv1 << FIXP16_SHIFT);
- // set starting y
- ystart = y0;
- } // end else
- } // end if flat top
- else
- {
- // must be flat bottom
- // compute all deltas
- dy = (y1 - y0);
- dxdyl = ((x1 - x0) << FIXP16_SHIFT)/dy;
- dudyl = ((tu1 - tu0) << FIXP16_SHIFT)/dy;
- dvdyl = ((tv1 - tv0) << FIXP16_SHIFT)/dy;
- dxdyr = ((x2 - x0) << FIXP16_SHIFT)/dy;
- dudyr = ((tu2 - tu0) << FIXP16_SHIFT)/dy;
- dvdyr = ((tv2 - tv0) << FIXP16_SHIFT)/dy;
- // test for y clipping
- if (y0 < min_clip_y)
- {
- // compute overclip
- dy = (min_clip_y - y0);
- // computer new LHS starting values
- xl = dxdyl*dy + (x0 << FIXP16_SHIFT);
- ul = dudyl*dy + (tu0 << FIXP16_SHIFT);
- vl = dvdyl*dy + (tv0 << FIXP16_SHIFT);
- // compute new RHS starting values
- xr = dxdyr*dy + (x0 << FIXP16_SHIFT);
- ur = dudyr*dy + (tu0 << FIXP16_SHIFT);
- vr = dvdyr*dy + (tv0 << FIXP16_SHIFT);
- // compute new starting y
- ystart = min_clip_y;
- } // end if
- else
- {
- // no clipping
- // set starting values
- xl = (x0 << FIXP16_SHIFT);
- xr = (x0 << FIXP16_SHIFT);
- ul = (tu0 << FIXP16_SHIFT);
- vl = (tv0 << FIXP16_SHIFT);
- ur = (tu0 << FIXP16_SHIFT);
- vr = (tv0 << FIXP16_SHIFT);
- // set starting y
- ystart = y0;
- } // end else
- } // end else flat bottom
- // test for bottom clip, always
- if ((yend = y2) > max_clip_y)
- yend = max_clip_y;
- // test for horizontal clipping
- if ((x0 < min_clip_x) || (x0 > max_clip_x) ||
- (x1 < min_clip_x) || (x1 > max_clip_x) ||
- (x2 < min_clip_x) || (x2 > max_clip_x))
- {
- // clip version
- // point screen ptr to starting line
- screen_ptr = dest_buffer + (ystart * mem_pitch);
- for (yi = ystart; yi<=yend; yi++)
- {
- // compute span endpoints
- xstart = ((xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
- xend = ((xr + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
- // compute starting points for u,v interpolants
- ui = ul + FIXP16_ROUND_UP;
- vi = vl + FIXP16_ROUND_UP;
- // compute u,v interpolants
- if ((dx = (xend - xstart))>0)
- {
- du = (ur - ul)/dx;
- dv = (vr - vl)/dx;
- } // end if
- else
- {
- du = (ur - ul);
- dv = (vr - vl);
- } // end else
- ///////////////////////////////////////////////////////////////////////
- // test for x clipping, LHS
- if (xstart < min_clip_x)
- {
- // compute x overlap
- dx = min_clip_x - xstart;
- // slide interpolants over
- ui+=dx*du;
- vi+=dx*dv;
- // reset vars
- xstart = min_clip_x;
- } // end if
- // test for x clipping RHS
- if (xend > max_clip_x)
- xend = max_clip_x;
- ///////////////////////////////////////////////////////////////////////
- // draw span
- for (xi=xstart; xi<=xend; xi++)
- {
- // write textel
- screen_ptr[xi] = textmap[(ui >> FIXP16_SHIFT) + ((vi >> FIXP16_SHIFT) << texture_shift2)];
- // interpolate u,v
- ui+=du;
- vi+=dv;
- } // end for xi
- // interpolate u,v,x along right and left edge
- xl+=dxdyl;
- ul+=dudyl;
- vl+=dvdyl;
- xr+=dxdyr;
- ur+=dudyr;
- vr+=dvdyr;
- // advance screen ptr
- screen_ptr+=mem_pitch;
- } // end for y
- } // end if clip
- else
- {
- // non-clip version
- // point screen ptr to starting line
- screen_ptr = dest_buffer + (ystart * mem_pitch);
- for (yi = ystart; yi<=yend; yi++)
- {
- // compute span endpoints
- xstart = ((xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
- xend = ((xr + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
- // compute starting points for u,v interpolants
- ui = ul + FIXP16_ROUND_UP;
- vi = vl + FIXP16_ROUND_UP;
- // compute u,v interpolants
- if ((dx = (xend - xstart))>0)
- {
- du = (ur - ul)/dx;
- dv = (vr - vl)/dx;
- } // end if
- else
- {
- du = (ur - ul);
- dv = (vr - vl);
- } // end else
- // draw span
- for (xi=xstart; xi<=xend; xi++)
- {
- // write textel
- screen_ptr[xi] = textmap[(ui >> FIXP16_SHIFT) + ((vi >> FIXP16_SHIFT) << texture_shift2)];
- // interpolate u,v
- ui+=du;
- vi+=dv;
- } // end for xi
- // interpolate u,v,x along right and left edge
- xl+=dxdyl;
- ul+=dudyl;
- vl+=dvdyl;
- xr+=dxdyr;
- ur+=dudyr;
- vr+=dvdyr;
- // advance screen ptr
- screen_ptr+=mem_pitch;
- } // end for y
- } // end if non-clipped
- } // end if
- else
- if (tri_type==TRI_TYPE_GENERAL)
- {
- // first test for bottom clip, always
- if ((yend = y2) > max_clip_y)
- yend = max_clip_y;
- // pre-test y clipping status
- if (y1 < min_clip_y)
- {
- // compute all deltas
- // LHS
- dyl = (y2 - y1);
- dxdyl = ((x2 - x1) << FIXP16_SHIFT)/dyl;
- dudyl = ((tu2 - tu1) << FIXP16_SHIFT)/dyl;
- dvdyl = ((tv2 - tv1) << FIXP16_SHIFT)/dyl;
- // RHS
- dyr = (y2 - y0);
- dxdyr = ((x2 - x0) << FIXP16_SHIFT)/dyr;
- dudyr = ((tu2 - tu0) << FIXP16_SHIFT)/dyr;
- dvdyr = ((tv2 - tv0) << FIXP16_SHIFT)/dyr;
- // compute overclip
- dyr = (min_clip_y - y0);
- dyl = (min_clip_y - y1);
- // computer new LHS starting values
- xl = dxdyl*dyl + (x1 << FIXP16_SHIFT);
- ul = dudyl*dyl + (tu1 << FIXP16_SHIFT);
- vl = dvdyl*dyl + (tv1 << FIXP16_SHIFT);
- // compute new RHS starting values
- xr = dxdyr*dyr + (x0 << FIXP16_SHIFT);
- ur = dudyr*dyr + (tu0 << FIXP16_SHIFT);
- vr = dvdyr*dyr + (tv0 << FIXP16_SHIFT);
- // compute new starting y
- ystart = min_clip_y;
- // test if we need swap to keep rendering left to right
- if (dxdyr > dxdyl)
- {
- SWAP(dxdyl,dxdyr,temp);
- SWAP(dudyl,dudyr,temp);
- SWAP(dvdyl,dvdyr,temp);
- SWAP(xl,xr,temp);
- SWAP(ul,ur,temp);
- SWAP(vl,vr,temp);
- SWAP(x1,x2,temp);
- SWAP(y1,y2,temp);
- SWAP(tu1,tu2,temp);
- SWAP(tv1,tv2,temp);
- // set interpolation restart
- irestart = INTERP_RHS;
- } // end if
- } // end if
- else
- if (y0 < min_clip_y)
- {
- // compute all deltas
- // LHS
- dyl = (y1 - y0);
- dxdyl = ((x1 - x0) << FIXP16_SHIFT)/dyl;
- dudyl = ((tu1 - tu0) << FIXP16_SHIFT)/dyl;
- dvdyl = ((tv1 - tv0) << FIXP16_SHIFT)/dyl;
- // RHS
- dyr = (y2 - y0);
- dxdyr = ((x2 - x0) << FIXP16_SHIFT)/dyr;
- dudyr = ((tu2 - tu0) << FIXP16_SHIFT)/dyr;
- dvdyr = ((tv2 - tv0) << FIXP16_SHIFT)/dyr;
- // compute overclip
- dy = (min_clip_y - y0);
- // computer new LHS starting values
- xl = dxdyl*dy + (x0 << FIXP16_SHIFT);
- ul = dudyl*dy + (tu0 << FIXP16_SHIFT);
- vl = dvdyl*dy + (tv0 << FIXP16_SHIFT);
- // compute new RHS starting values
- xr = dxdyr*dy + (x0 << FIXP16_SHIFT);
- ur = dudyr*dy + (tu0 << FIXP16_SHIFT);
- vr = dvdyr*dy + (tv0 << FIXP16_SHIFT);
- // compute new starting y
- ystart = min_clip_y;
- // test if we need swap to keep rendering left to right
- if (dxdyr < dxdyl)
- {
- SWAP(dxdyl,dxdyr,temp);
- SWAP(dudyl,dudyr,temp);
- SWAP(dvdyl,dvdyr,temp);
- SWAP(xl,xr,temp);
- SWAP(ul,ur,temp);
- SWAP(vl,vr,temp);
- SWAP(x1,x2,temp);
- SWAP(y1,y2,temp);
- SWAP(tu1,tu2,temp);
- SWAP(tv1,tv2,temp);
- // set interpolation restart
- irestart = INTERP_RHS;
- } // end if
- } // end if
- else
- {
- // no initial y clipping
- // compute all deltas
- // LHS
- dyl = (y1 - y0);
- dxdyl = ((x1 - x0) << FIXP16_SHIFT)/dyl;
- dudyl = ((tu1 - tu0) << FIXP16_SHIFT)/dyl;
- dvdyl = ((tv1 - tv0) << FIXP16_SHIFT)/dyl;
- // RHS
- dyr = (y2 - y0);
- dxdyr = ((x2 - x0) << FIXP16_SHIFT)/dyr;
- dudyr = ((tu2 - tu0) << FIXP16_SHIFT)/dyr;
- dvdyr = ((tv2 - tv0) << FIXP16_SHIFT)/dyr;
- // no clipping y
- // set starting values
- xl = (x0 << FIXP16_SHIFT);
- xr = (x0 << FIXP16_SHIFT);
- ul = (tu0 << FIXP16_SHIFT);
- vl = (tv0 << FIXP16_SHIFT);
- ur = (tu0 << FIXP16_SHIFT);
- vr = (tv0 << FIXP16_SHIFT);
- // set starting y
- ystart = y0;
- // test if we need swap to keep rendering left to right
- if (dxdyr < dxdyl)
- {
- SWAP(dxdyl,dxdyr,temp);
- SWAP(dudyl,dudyr,temp);
- SWAP(dvdyl,dvdyr,temp);
- SWAP(xl,xr,temp);
- SWAP(ul,ur,temp);
- SWAP(vl,vr,temp);
- SWAP(x1,x2,temp);
- SWAP(y1,y2,temp);
- SWAP(tu1,tu2,temp);
- SWAP(tv1,tv2,temp);
- // set interpolation restart
- irestart = INTERP_RHS;
- } // end if
- } // end else
- // test for horizontal clipping
- if ((x0 < min_clip_x) || (x0 > max_clip_x) ||
- (x1 < min_clip_x) || (x1 > max_clip_x) ||
- (x2 < min_clip_x) || (x2 > max_clip_x))
- {
- // clip version
- // x clipping
- // point screen ptr to starting line
- screen_ptr = dest_buffer + (ystart * mem_pitch);
- for (yi = ystart; yi<=yend; yi++)
- {
- // compute span endpoints
- xstart = ((xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
- xend = ((xr + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
- // compute starting points for u,v interpolants
- ui = ul + FIXP16_ROUND_UP;
- vi = vl + FIXP16_ROUND_UP;
- // compute u,v interpolants
- if ((dx = (xend - xstart))>0)
- {
- du = (ur - ul)/dx;
- dv = (vr - vl)/dx;
- } // end if
- else
- {
- du = (ur - ul);
- dv = (vr - vl);
- } // end else
- ///////////////////////////////////////////////////////////////////////
- // test for x clipping, LHS
- if (xstart < min_clip_x)
- {
- // compute x overlap
- dx = min_clip_x - xstart;
- // slide interpolants over
- ui+=dx*du;
- vi+=dx*dv;
- // set x to left clip edge
- xstart = min_clip_x;
- } // end if
- // test for x clipping RHS
- if (xend > max_clip_x)
- xend = max_clip_x;
- ///////////////////////////////////////////////////////////////////////
- // draw span
- for (xi=xstart; xi<=xend; xi++)
- {
- // write textel
- screen_ptr[xi] = textmap[(ui >> FIXP16_SHIFT) + ((vi >> FIXP16_SHIFT) << texture_shift2)];
- // interpolate u,v
- ui+=du;
- vi+=dv;
- } // end for xi
- // interpolate u,v,x along right and left edge
- xl+=dxdyl;
- ul+=dudyl;
- vl+=dvdyl;
- xr+=dxdyr;
- ur+=dudyr;
- vr+=dvdyr;
- // advance screen ptr
- screen_ptr+=mem_pitch;
- // test for yi hitting second region, if so change interpolant
- if (yi==yrestart)
- {
- // test interpolation side change flag
- if (irestart == INTERP_LHS)
- {
- // LHS
- dyl = (y2 - y1);
- dxdyl = ((x2 - x1) << FIXP16_SHIFT)/dyl;
- dudyl = ((tu2 - tu1) << FIXP16_SHIFT)/dyl;
- dvdyl = ((tv2 - tv1) << FIXP16_SHIFT)/dyl;
- // set starting values
- xl = (x1 << FIXP16_SHIFT);
- ul = (tu1 << FIXP16_SHIFT);
- vl = (tv1 << FIXP16_SHIFT);
- // interpolate down on LHS to even up
- xl+=dxdyl;
- ul+=dudyl;
- vl+=dvdyl;
- } // end if
- else
- {
- // RHS
- dyr = (y1 - y2);
- dxdyr = ((x1 - x2) << FIXP16_SHIFT)/dyr;
- dudyr = ((tu1 - tu2) << FIXP16_SHIFT)/dyr;
- dvdyr = ((tv1 - tv2) << FIXP16_SHIFT)/dyr;
- // set starting values
- xr = (x2 << FIXP16_SHIFT);
- ur = (tu2 << FIXP16_SHIFT);
- vr = (tv2 << FIXP16_SHIFT);
- // interpolate down on RHS to even up
- xr+=dxdyr;
- ur+=dudyr;
- vr+=dvdyr;
- } // end else
- } // end if
- } // end for y
- } // end if
- else
- {
- // no x clipping
- // point screen ptr to starting line
- screen_ptr = dest_buffer + (ystart * mem_pitch);
- for (yi = ystart; yi<=yend; yi++)
- {
- // compute span endpoints
- xstart = ((xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
- xend = ((xr + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
- // compute starting points for u,v interpolants
- ui = ul + FIXP16_ROUND_UP;
- vi = vl + FIXP16_ROUND_UP;
- // compute u,v interpolants
- if ((dx = (xend - xstart))>0)
- {
- du = (ur - ul)/dx;
- dv = (vr - vl)/dx;
- } // end if
- else
- {
- du = (ur - ul);
- dv = (vr - vl);
- } // end else
- // draw span
- for (xi=xstart; xi<=xend; xi++)
- {
- // write textel
- screen_ptr[xi] = textmap[(ui >> FIXP16_SHIFT) + ((vi >> FIXP16_SHIFT) << texture_shift2)];
- // interpolate u,v
- ui+=du;
- vi+=dv;
- } // end for xi
- // interpolate u,v,x along right and left edge
- xl+=dxdyl;
- ul+=dudyl;
- vl+=dvdyl;
- xr+=dxdyr;
- ur+=dudyr;
- vr+=dvdyr;
- // advance screen ptr
- screen_ptr+=mem_pitch;
- // test for yi hitting second region, if so change interpolant
- if (yi==yrestart)
- {
- // test interpolation side change flag
- if (irestart == INTERP_LHS)
- {
- // LHS
- dyl = (y2 - y1);
- dxdyl = ((x2 - x1) << FIXP16_SHIFT)/dyl;
- dudyl = ((tu2 - tu1) << FIXP16_SHIFT)/dyl;
- dvdyl = ((tv2 - tv1) << FIXP16_SHIFT)/dyl;
- // set starting values
- xl = (x1 << FIXP16_SHIFT);
- ul = (tu1 << FIXP16_SHIFT);
- vl = (tv1 << FIXP16_SHIFT);
- // interpolate down on LHS to even up
- xl+=dxdyl;
- ul+=dudyl;
- vl+=dvdyl;
- } // end if
- else
- {
- // RHS
- dyr = (y1 - y2);
- dxdyr = ((x1 - x2) << FIXP16_SHIFT)/dyr;
- dudyr = ((tu1 - tu2) << FIXP16_SHIFT)/dyr;
- dvdyr = ((tv1 - tv2) << FIXP16_SHIFT)/dyr;
- // set starting values
- xr = (x2 << FIXP16_SHIFT);
- ur = (tu2 << FIXP16_SHIFT);
- vr = (tv2 << FIXP16_SHIFT);
- // interpolate down on RHS to even up
- xr+=dxdyr;
- ur+=dudyr;
- vr+=dvdyr;
- } // end else
- } // end if
- } // end for y
- } // end else
- } // end if
- } // end Draw_Textured_Triangle16
- ///////////////////////////////////////////////////////////////////////////////
- void Draw_Textured_TriangleFS16(POLYF4DV2_PTR face, // ptr to face
- UCHAR *_dest_buffer, // pointer to video buffer
- int mem_pitch) // bytes per line, 320, 640 etc.
- {
- // this function draws a textured triangle in 16-bit mode with flat shading
- int v0=0,
- v1=1,
- v2=2,
- temp=0,
- tri_type = TRI_TYPE_NONE,
- irestart = INTERP_LHS;
- int dx,dy,dyl,dyr, // general deltas
- u,v,
- du,dv,
- xi,yi, // the current interpolated x,y
- ui,vi, // the current interpolated u,v
- index_x,index_y, // looping vars
- x,y, // hold general x,y
- xstart,
- xend,
- ystart,
- yrestart,
- yend,
- xl,
- dxdyl,
- xr,
- dxdyr,
- dudyl,
- ul,
- dvdyl,
- vl,
- dudyr,
- ur,
- dvdyr,
- vr;
- USHORT r_base, g_base, b_base,
- r_textel, g_textel, b_textel, textel;
- int x0,y0,tu0,tv0, // cached vertices
- x1,y1,tu1,tv1,
- x2,y2,tu2,tv2;
- USHORT *screen_ptr = NULL,
- *screen_line = NULL,
- *textmap = NULL,
- *dest_buffer = (USHORT *)_dest_buffer;
- #ifdef DEBUG_ON
- // track rendering stats
- debug_polys_rendered_per_frame++;
- #endif
- // extract texture map
- textmap = (USHORT *)face->texture->buffer;
- // extract base 2 of texture width
- int texture_shift2 = logbase2ofx[face->texture->width];
- // adjust memory pitch to words, divide by 2
- mem_pitch >>=1;
- // first trivial clipping rejection tests
- if (((face->tvlist[0].y < min_clip_y) &&
- (face->tvlist[1].y < min_clip_y) &&
- (face->tvlist[2].y < min_clip_y)) ||
- ((face->tvlist[0].y > max_clip_y) &&
- (face->tvlist[1].y > max_clip_y) &&
- (face->tvlist[2].y > max_clip_y)) ||
- ((face->tvlist[0].x < min_clip_x) &&
- (face->tvlist[1].x < min_clip_x) &&
- (face->tvlist[2].x < min_clip_x)) ||
- ((face->tvlist[0].x > max_clip_x) &&
- (face->tvlist[1].x > max_clip_x) &&
- (face->tvlist[2].x > max_clip_x)))
- return;
- // degenerate triangle
- if ( ((face->tvlist[0].x==face->tvlist[1].x) && (face->tvlist[1].x==face->tvlist[2].x)) ||
- ((face->tvlist[0].y==face->tvlist[1].y) && (face->tvlist[1].y==face->tvlist[2].y)))
- return;
- // sort vertices
- if (face->tvlist[v1].y < face->tvlist[v0].y)
- {SWAP(v0,v1,temp);}
- if (face->tvlist[v2].y < face->tvlist[v0].y)
- {SWAP(v0,v2,temp);}
- if (face->tvlist[v2].y < face->tvlist[v1].y)
- {SWAP(v1,v2,temp);}
- // now test for trivial flat sided cases
- if (face->tvlist[v0].y==face->tvlist[v1].y)
- {
- // set triangle type
- tri_type = TRI_TYPE_FLAT_TOP;
- // sort vertices left to right
- if (face->tvlist[v1].x < face->tvlist[v0].x)
- {SWAP(v0,v1,temp);}
- } // end if
- else
- // now test for trivial flat sided cases
- if (face->tvlist[v1].y==face->tvlist[v2].y)
- {
- // set triangle type
- tri_type = TRI_TYPE_FLAT_BOTTOM;
- // sort vertices left to right
- if (face->tvlist[v2].x < face->tvlist[v1].x)
- {SWAP(v1,v2,temp);}
- } // end if
- else
- {
- // must be a general triangle
- tri_type = TRI_TYPE_GENERAL;
- } // end else
- // extract base color of lit poly, so we can modulate texture a bit
- // for lighting
- _RGB565FROM16BIT(face->lit_color[0], &r_base, &g_base, &b_base);
- // extract vertices for processing, now that we have order
- x0 = (int)(face->tvlist[v0].x+0.5);
- y0 = (int)(face->tvlist[v0].y+0.5);
- tu0 = (int)(face->tvlist[v0].u0);
- tv0 = (int)(face->tvlist[v0].v0);
- x1 = (int)(face->tvlist[v1].x+0.5);
- y1 = (int)(face->tvlist[v1].y+0.5);
- tu1 = (int)(face->tvlist[v1].u0);
- tv1 = (int)(face->tvlist[v1].v0);
- x2 = (int)(face->tvlist[v2].x+0.5);
- y2 = (int)(face->tvlist[v2].y+0.5);
- tu2 = (int)(face->tvlist[v2].u0);
- tv2 = (int)(face->tvlist[v2].v0);
- // set interpolation restart value
- yrestart = y1;
- // what kind of triangle
- if (tri_type & TRI_TYPE_FLAT_MASK)
- {
- if (tri_type == TRI_TYPE_FLAT_TOP)
- {
- // compute all deltas
- dy = (y2 - y0);
- dxdyl = ((x2 - x0) << FIXP16_SHIFT)/dy;
- dudyl = ((tu2 - tu0) << FIXP16_SHIFT)/dy;
- dvdyl = ((tv2 - tv0) << FIXP16_SHIFT)/dy;
- dxdyr = ((x2 - x1) << FIXP16_SHIFT)/dy;
- dudyr = ((tu2 - tu1) << FIXP16_SHIFT)/dy;
- dvdyr = ((tv2 - tv1) << FIXP16_SHIFT)/dy;
- // test for y clipping
- if (y0 < min_clip_y)
- {
- // compute overclip
- dy = (min_clip_y - y0);
- // computer new LHS starting values
- xl = dxdyl*dy + (x0 << FIXP16_SHIFT);
- ul = dudyl*dy + (tu0 << FIXP16_SHIFT);
- vl = dvdyl*dy + (tv0 << FIXP16_SHIFT);
- // compute new RHS starting values
- xr = dxdyr*dy + (x1 << FIXP16_SHIFT);
- ur = dudyr*dy + (tu1 << FIXP16_SHIFT);
- vr = dvdyr*dy + (tv1 << FIXP16_SHIFT);
- // compute new starting y
- ystart = min_clip_y;
- } // end if
- else
- {
- // no clipping
- // set starting values
- xl = (x0 << FIXP16_SHIFT);
- xr = (x1 << FIXP16_SHIFT);
- ul = (tu0 << FIXP16_SHIFT);
- vl = (tv0 << FIXP16_SHIFT);
- ur = (tu1 << FIXP16_SHIFT);
- vr = (tv1 << FIXP16_SHIFT);
- // set starting y
- ystart = y0;
- } // end else
- } // end if flat top
- else
- {
- // must be flat bottom
- // compute all deltas
- dy = (y1 - y0);
- dxdyl = ((x1 - x0) << FIXP16_SHIFT)/dy;
- dudyl = ((tu1 - tu0) << FIXP16_SHIFT)/dy;
- dvdyl = ((tv1 - tv0) << FIXP16_SHIFT)/dy;
- dxdyr = ((x2 - x0) << FIXP16_SHIFT)/dy;
- dudyr = ((tu2 - tu0) << FIXP16_SHIFT)/dy;
- dvdyr = ((tv2 - tv0) << FIXP16_SHIFT)/dy;
- // test for y clipping
- if (y0 < min_clip_y)
- {
- // compute overclip
- dy = (min_clip_y - y0);
- // computer new LHS starting values
- xl = dxdyl*dy + (x0 << FIXP16_SHIFT);
- ul = dudyl*dy + (tu0 << FIXP16_SHIFT);
- vl = dvdyl*dy + (tv0 << FIXP16_SHIFT);
- // compute new RHS starting values
- xr = dxdyr*dy + (x0 << FIXP16_SHIFT);
- ur = dudyr*dy + (tu0 << FIXP16_SHIFT);
- vr = dvdyr*dy + (tv0 << FIXP16_SHIFT);
- // compute new starting y
- ystart = min_clip_y;
- } // end if
- else
- {
- // no clipping
- // set starting values
- xl = (x0 << FIXP16_SHIFT);
- xr = (x0 << FIXP16_SHIFT);
- ul = (tu0 << FIXP16_SHIFT);
- vl = (tv0 << FIXP16_SHIFT);
- ur = (tu0 << FIXP16_SHIFT);
- vr = (tv0 << FIXP16_SHIFT);
- // set starting y
- ystart = y0;
- } // end else
- } // end else flat bottom
- // test for bottom clip, always
- if ((yend = y2) > max_clip_y)
- yend = max_clip_y;
- // test for horizontal clipping
- if ((x0 < min_clip_x) || (x0 > max_clip_x) ||
- (x1 < min_clip_x) || (x1 > max_clip_x) ||
- (x2 < min_clip_x) || (x2 > max_clip_x))
- {
- // clip version
- // point screen ptr to starting line
- screen_ptr = dest_buffer + (ystart * mem_pitch);
- for (yi = ystart; yi<=yend; yi++)
- {
- // compute span endpoints
- xstart = ((xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
- xend = ((xr + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
- // compute starting points for u,v interpolants
- ui = ul + FIXP16_ROUND_UP;
- vi = vl + FIXP16_ROUND_UP;
- // compute u,v interpolants
- if ((dx = (xend - xstart))>0)
- {
- du = (ur - ul)/dx;
- dv = (vr - vl)/dx;
- } // end if
- else
- {
- du = (ur - ul);
- dv = (vr - vl);
- } // end else
- ///////////////////////////////////////////////////////////////////////
- // test for x clipping, LHS
- if (xstart < min_clip_x)
- {
- // compute x overlap
- dx = min_clip_x - xstart;
- // slide interpolants over
- ui+=dx*du;
- vi+=dx*dv;
- // reset vars
- xstart = min_clip_x;
- } // end if
- // test for x clipping RHS
- if (xend > max_clip_x)
- xend = max_clip_x;
- ///////////////////////////////////////////////////////////////////////
- // draw span
- for (xi=xstart; xi<=xend; xi++)
- {
- // write textel
- // get textel first
- textel = textmap[(ui >> FIXP16_SHIFT) + ((vi >> FIXP16_SHIFT) << texture_shift2)];
- // extract rgb components
- r_textel = ((textel >> 11) );
- g_textel = ((textel >> 5) & 0x3f);
- b_textel = (textel & 0x1f);
- // modulate textel with lit background color
- r_textel*=r_base;
- g_textel*=g_base;
- b_textel*=b_base;
- // finally write pixel, note that we did the math such that the results are r*32, g*64, b*32
- // hence we need to divide the results by 32,64,32 respetively, BUT since we need to shift
- // the results to fit into the destination 5.6.5 word, we can take advantage of the shifts
- // and they all cancel out for the most part, but we will need logical anding, we will do
- // it later when we optimize more...
- screen_ptr[xi] = ((b_textel >> 5) + ((g_textel >> 6) << 5) + ((r_textel >> 5) << 11));
- // interpolate u,v
- ui+=du;
- vi+=dv;
- } // end for xi
- // interpolate u,v,x along right and left edge
- xl+=dxdyl;
- ul+=dudyl;
- vl+=dvdyl;
- xr+=dxdyr;
- ur+=dudyr;
- vr+=dvdyr;
- // advance screen ptr
- screen_ptr+=mem_pitch;
- } // end for y
- } // end if clip
- else
- {
- // non-clip version
- // point screen ptr to starting line
- screen_ptr = dest_buffer + (ystart * mem_pitch);
- for (yi = ystart; yi<=yend; yi++)
- {
- // compute span endpoints
- xstart = ((xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
- xend = ((xr + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
- // compute starting points for u,v interpolants
- ui = ul + FIXP16_ROUND_UP;
- vi = vl + FIXP16_ROUND_UP;
- // compute u,v interpolants
- if ((dx = (xend - xstart))>0)
- {
- du = (ur - ul)/dx;
- dv = (vr - vl)/dx;
- } // end if
- else
- {
- du = (ur - ul);
- dv = (vr - vl);
- } // end else
- // draw span
- for (xi=xstart; xi<=xend; xi++)
- {
- // write textel
- // get textel first
- textel = textmap[(ui >> FIXP16_SHIFT) + ((vi >> FIXP16_SHIFT) << texture_shift2)];
- // extract rgb components
- r_textel = ((textel >> 11) );
- g_textel = ((textel >> 5) & 0x3f);
- b_textel = (textel & 0x1f);
- // modulate textel with lit background color
- r_textel*=r_base;
- g_textel*=g_base;
- b_textel*=b_base;
- // finally write pixel, note that we did the math such that the results are r*32, g*64, b*32
- // hence we need to divide the results by 32,64,32 respetively, BUT since we need to shift
- // the results to fit into the destination 5.6.5 word, we can take advantage of the shifts
- // and they all cancel out for the most part, but we will need logical anding, we will do
- // it later when we optimize more...
- screen_ptr[xi] = ((b_textel >> 5) + ((g_textel >> 6) << 5) + ((r_textel >> 5) << 11));
- // interpolate u,v
- ui+=du;
- vi+=dv;
- } // end for xi
- // interpolate u,v,x along right and left edge
- xl+=dxdyl;
- ul+=dudyl;
- vl+=dvdyl;
- xr+=dxdyr;
- ur+=dudyr;
- vr+=dvdyr;
- // advance screen ptr
- screen_ptr+=mem_pitch;
- } // end for y
- } // end if non-clipped
- } // end if
- else
- if (tri_type==TRI_TYPE_GENERAL)
- {
- // first test for bottom clip, always
- if ((yend = y2) > max_clip_y)
- yend = max_clip_y;
- // pre-test y clipping status
- if (y1 < min_clip_y)
- {
- // compute all deltas
- // LHS
- dyl = (y2 - y1);
- dxdyl = ((x2 - x1) << FIXP16_SHIFT)/dyl;
- dudyl = ((tu2 - tu1) << FIXP16_SHIFT)/dyl;
- dvdyl = ((tv2 - tv1) << FIXP16_SHIFT)/dyl;
- // RHS
- dyr = (y2 - y0);
- dxdyr = ((x2 - x0) << FIXP16_SHIFT)/dyr;
- dudyr = ((tu2 - tu0) << FIXP16_SHIFT)/dyr;
- dvdyr = ((tv2 - tv0) << FIXP16_SHIFT)/dyr;
- // compute overclip
- dyr = (min_clip_y - y0);
- dyl = (min_clip_y - y1);
- // computer new LHS starting values
- xl = dxdyl*dyl + (x1 << FIXP16_SHIFT);
- ul = dudyl*dyl + (tu1 << FIXP16_SHIFT);
- vl = dvdyl*dyl + (tv1 << FIXP16_SHIFT);
- // compute new RHS starting values
- xr = dxdyr*dyr + (x0 << FIXP16_SHIFT);
- ur = dudyr*dyr + (tu0 << FIXP16_SHIFT);
- vr = dvdyr*dyr + (tv0 << FIXP16_SHIFT);
- // compute new starting y
- ystart = min_clip_y;
- // test if we need swap to keep rendering left to right
- if (dxdyr > dxdyl)
- {
- SWAP(dxdyl,dxdyr,temp);
- SWAP(dudyl,dudyr,temp);
- SWAP(dvdyl,dvdyr,temp);
- SWAP(xl,xr,temp);
- SWAP(ul,ur,temp);
- SWAP(vl,vr,temp);
- SWAP(x1,x2,temp);
- SWAP(y1,y2,temp);
- SWAP(tu1,tu2,temp);
- SWAP(tv1,tv2,temp);
- // set interpolation restart
- irestart = INTERP_RHS;
- } // end if
- } // end if
- else
- if (y0 < min_clip_y)
- {
- // compute all deltas
- // LHS
- dyl = (y1 - y0);
- dxdyl = ((x1 - x0) << FIXP16_SHIFT)/dyl;
- dudyl = ((tu1 - tu0) << FIXP16_SHIFT)/dyl;
- dvdyl = ((tv1 - tv0) << FIXP16_SHIFT)/dyl;
- // RHS
- dyr = (y2 - y0);
- dxdyr = ((x2 - x0) << FIXP16_SHIFT)/dyr;
- dudyr = ((tu2 - tu0) << FIXP16_SHIFT)/dyr;
- dvdyr = ((tv2 - tv0) << FIXP16_SHIFT)/dyr;
- // compute overclip
- dy = (min_clip_y - y0);
- // computer new LHS starting values
- xl = dxdyl*dy + (x0 << FIXP16_SHIFT);
- ul = dudyl*dy + (tu0 << FIXP16_SHIFT);
- vl = dvdyl*dy + (tv0 << FIXP16_SHIFT);
- // compute new RHS starting values
- xr = dxdyr*dy + (x0 << FIXP16_SHIFT);
- ur = dudyr*dy + (tu0 << FIXP16_SHIFT);
- vr = dvdyr*dy + (tv0 << FIXP16_SHIFT);
- // compute new starting y
- ystart = min_clip_y;
- // test if we need swap to keep rendering left to right
- if (dxdyr < dxdyl)
- {
- SWAP(dxdyl,dxdyr,temp);
- SWAP(dudyl,dudyr,temp);
- SWAP(dvdyl,dvdyr,temp);
- SWAP(xl,xr,temp);
- SWAP(ul,ur,temp);
- SWAP(vl,vr,temp);
- SWAP(x1,x2,temp);
- SWAP(y1,y2,temp);
- SWAP(tu1,tu2,temp);
- SWAP(tv1,tv2,temp);
- // set interpolation restart
- irestart = INTERP_RHS;
- } // end if
- } // end if
- else
- {
- // no initial y clipping
- // compute all deltas
- // LHS
- dyl = (y1 - y0);
- dxdyl = ((x1 - x0) << FIXP16_SHIFT)/dyl;
- dudyl = ((tu1 - tu0) << FIXP16_SHIFT)/dyl;
- dvdyl = ((tv1 - tv0) << FIXP16_SHIFT)/dyl;
- // RHS
- dyr = (y2 - y0);
- dxdyr = ((x2 - x0) << FIXP16_SHIFT)/dyr;
- dudyr = ((tu2 - tu0) << FIXP16_SHIFT)/dyr;
- dvdyr = ((tv2 - tv0) << FIXP16_SHIFT)/dyr;
- // no clipping y
- // set starting values
- xl = (x0 << FIXP16_SHIFT);
- xr = (x0 << FIXP16_SHIFT);
- ul = (tu0 << FIXP16_SHIFT);
- vl = (tv0 << FIXP16_SHIFT);
- ur = (tu0 << FIXP16_SHIFT);
- vr = (tv0 << FIXP16_SHIFT);