📄 t3dlib6.cpp
字号:
// 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 + -