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

📄 t3dlib6.cpp

📁 3D游戏编程大师技巧第九章的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// T3DLIB6.CPP - low level line and triangle rendering code

// I N C L U D E S ///////////////////////////////////////////////////////////

#define DEBUG_ON

#define WIN32_LEAN_AND_MEAN  

#include <windows.h>   // include important windows stuff
#include <windowsx.h> 
#include <mmsystem.h>
#include <objbase.h>
#include <iostream.h> // include important C/C++ stuff
#include <conio.h>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <math.h>
#include <io.h>
#include <fcntl.h>
#include <direct.h>
#include <wchar.h>
#include <limits.h>
#include <float.h>
#include <search.h>

#include <ddraw.h>      // needed for defs in T3DLIB1.H 
#include "T3DLIB1.H"
#include "T3DLIB4.H"
#include "T3DLIB5.H"
#include "T3DLIB6.H"

// GLOBALS //////////////////////////////////////////////////////////////////

MATV1 materials[MAX_MATERIALS]; // materials in system
int num_materials;              // current number of materials

LIGHTV1 lights[MAX_LIGHTS];  // lights in system
int num_lights;              // current number of lights

// these look up tables are used by the 8-bit lighting engine
// the first one holds a color translation table in the form of each
// row is a color 0..255, and each row consists of 256 shades of that color
// the data in each row is the color/intensity indices and the resulting value
// is an 8-bit index into the real color lookup that should be used as the color

// the second table works by each index being a compressed 16bit RGB value
// the data indexed by that RGB value IS the index 0..255 of the real
// color lookup that matches the desired color the closest

UCHAR rgbilookup[256][256];         // intensity RGB 8-bit lookup storage
UCHAR rgblookup[65536];             // RGB 8-bit color lookup

// FUNCTIONS ////////////////////////////////////////////////////////////////

void Draw_OBJECT4DV1_Solid(OBJECT4DV1_PTR obj, 
                          UCHAR *video_buffer, int lpitch)
                     
{
// this function renders an object to the screen in solid, 
// 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

// 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 & POLY4DV1_STATE_ACTIVE) ||
         (obj->plist[poly].state & POLY4DV1_STATE_CLIPPED ) ||
         (obj->plist[poly].state & POLY4DV1_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];

    // draw the triangle
    Draw_Triangle_2D(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].color, video_buffer, lpitch);

    } // end for poly

} // end Draw_OBJECT4DV1_Solid

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

void Draw_RENDERLIST4DV1_Solid(RENDERLIST4DV1_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, but 
// later we will need to, so hidden surfaces stay hidden
// also, we leave it to the function to determine the bitdepth
// and call the correct rasterizer

// 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 & POLY4DV1_STATE_ACTIVE) ||
         (rend_list->poly_ptrs[poly]->state & POLY4DV1_STATE_CLIPPED ) ||
         (rend_list->poly_ptrs[poly]->state & POLY4DV1_STATE_BACKFACE) )
       continue; // move onto next poly

    // draw the triangle
    Draw_Triangle_2D(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]->color, video_buffer, lpitch);

    } // end for poly

} // end Draw_RENDERLIST4DV1_Solid

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

void Draw_OBJECT4DV1_Solid16(OBJECT4DV1_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

// 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 & POLY4DV1_STATE_ACTIVE) ||
         (obj->plist[poly].state & POLY4DV1_STATE_CLIPPED ) ||
         (obj->plist[poly].state & POLY4DV1_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];
    
    // draw the triangle
    Draw_Triangle_2D16(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].color, video_buffer, lpitch);

    } // end for poly

} // end Draw_OBJECT4DV1_Solid16

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

void Draw_RENDERLIST4DV1_Solid16(RENDERLIST4DV1_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, but 
// later we will need to, so hidden surfaces stay hidden
// also, we leave it to the function to determine the bitdepth
// and call the correct rasterizer

// 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 & POLY4DV1_STATE_ACTIVE) ||
         (rend_list->poly_ptrs[poly]->state & POLY4DV1_STATE_CLIPPED ) ||
         (rend_list->poly_ptrs[poly]->state & POLY4DV1_STATE_BACKFACE) )
       continue; // move onto next poly

    // draw the triangle
    Draw_Triangle_2D16(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]->color, video_buffer, lpitch);

    } // end for poly

} // end Draw_RENDERLIST4DV1_Solid16

// CLASS CPARSERV1 IMPLEMENTATION /////////////////////////////////////////

// constructor /////////////////////////////////////////////////

CPARSERV1::CPARSERV1()
{
#ifdef PARSER_DEBUG_ON
printf("\nEntering CPARSERV1() constructor.");
#endif

// reset file system
fstream = NULL;
Reset();

} // end constructor

// destructor ///////////////////////////////////////////////////

CPARSERV1::~CPARSERV1() 
{ 
#ifdef PARSER_DEBUG_ON
printf("\nEntering ~CPARSERV1() destructor.");
#endif
Reset();

} // end destructor

// reset file system ////////////////////////////////////////////
int CPARSERV1::Reset()
{
#ifdef PARSER_DEBUG_ON
printf("\nEntering Reset().");
#endif

// reset file buffer
if (fstream)
   fclose(fstream);

fstream = NULL;

// clear and reset buffer
memset(buffer, 0, sizeof(buffer));
length    = 0;
num_lines = 0;

// set comment
strcpy(comment, PARSER_DEFAULT_COMMENT);

return(1);

} // end Reset

// open file /////////////////////////////////////////////////////

int CPARSERV1::Open(char *filename)
{
#ifdef PARSER_DEBUG_ON
printf("\nEntering Open().");
#endif

// reset file system
Reset();

// opens a file
if ((fstream = fopen(filename, "r"))!=NULL) 
   {
#ifdef PARSER_DEBUG_ON
printf("\nOpening file: %s", filename);
#endif   
   return(1);
   } // end if
else
    {
#ifdef PARSER_DEBUG_ON
printf("\nCouldn't open file: %s", filename);
#endif
    return(0);
    } // end else

} // end Open

// close file ////////////////////////////////////////////////////
int CPARSERV1::Close()
{
return(Reset());
} // end Close

// get line //////////////////////////////////////////////////////

char *CPARSERV1::Getline(int mode)
{
#ifdef PARSER_DEBUG_ON
printf("\nEntering Getline().");
#endif

char *string;

// gets a single line from the stream
if (fstream)
   {
   // check translation mode
   if (mode & PARSER_STRIP_EMPTY_LINES)
       {
       // get lines until we get a real one with data on it
       while(1)
            {      
            // have we went to the end of the file without getting anything?
            if ((string = fgets(buffer,PARSER_BUFFER_SIZE, fstream))==NULL)
               break;
            
            // we have something, strip ws from it
            int slength = strlen(string);
            int sindex = 0;

            // eat up space
            while(isspace(string[sindex]))
                 sindex++;

            // is there anything left?
            if ((slength - sindex) > 0)
               {
               // copy the string into place
               memmove((void *)buffer, (void *)&string[sindex],  (slength - sindex)+1 );
               string = buffer;
               slength = strlen(string); 
                
               // strip comments also?
               if (mode & PARSER_STRIP_COMMENTS)
                   {
                   // does this begin with a comment or end with a comment?
                   char *comment_string = strstr(string, comment);
                   
                   // 3 cases, no comment, comment at beginning, comment at end
                   if (comment_string == NULL)
                      break; // line is valid exit with line

                   // compute index into string from beginning where comment begins
                   int cindex = (int)(comment_string - string);

                   // comment at beginning then continue
                   
                   if (cindex == 0)
                      continue; // this line is a comment, ignore completely, get another
                   else
                      {
                      // comment at end, strip it, insert null where it begins
                      comment_string[0] = 0;
                      break;
                      } // end else

                   } // end if 

               // exit loop, we have something :)
               break;
               } // end if

            } // end while

       } // end if strip mode
    else
       { 
       // just get the next line, don't worry about stripping anything
       string = fgets(buffer,PARSER_BUFFER_SIZE, fstream);
       } // end else 

  
   // was the line valid?
   if (string)
      {
      // increment line count
      num_lines++;

      // final stripping of whitspace
      if (mode & PARSER_STRIP_WS_ENDS)
         {
         StringLtrim(buffer);
         StringRtrim(buffer);
         } // end if         

      // compute line length
      length = strlen(buffer);

#ifdef PARSER_DEBUG_ON
printf("\nString[%d]:%s", length, string);
#endif
      // return the pointer, copy of data already in buffer
      return(string);     

⌨️ 快捷键说明

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