//tracks.cpp //draw tire tracks on the road #include #include "textures.h" #include "fileio.h" #include "vectors.h" #include "renderframe.h" #include "gamemem.h" #include "network.h" #include "tracks.h" #include "log.h" #include "error.h" #include "gameinitexit.h" #include "environment.h" #define kMaxTrack 512 //size of track segment buffer #define kTrackShiftSize 256 //how many track segmnents to delete when buffer is full #define kTrackHeight 0.02 //how far tracks are drawn above ground (to avoid z-buffer problems) #define kMaxIntensity 0.8 #define kTrackTexScale 0.18 typedef struct{ tVector3 pos1l,pos1r,pos2l,pos2r,normal; int texture; float l1,l2; float intensity1,intensity2; } tTrackSegment; tTrackSegment gTrack[kMaxTrack];//track segment buffer int gNumTracks=0; int gTrackIndexShift=0; //Add a new segment of tire tracks, going from pos1 to pos2 //attach specifies a track segment which links to this one int TracksAdd(tVector3 pos1,tVector3 pos2,tVector3 normal,float width,int texture,float intensity,int attach) { //is there any space left in the track segment buffer? if(gNumTracks>=kMaxTrack) { //if not, delete kTrackShiftSize elements, by shifting the track segment buffer gTrackIndexShift+=kTrackShiftSize; gNumTracks-=kTrackShiftSize; MemoryMove(gTrack,gTrack+kTrackShiftSize,(kMaxTrack-kTrackShiftSize)*sizeof(tTrackSegment)); } float adjustedIntensity=intensity*kMaxIntensity; pos1.y+=kTrackHeight;//to avoid Z-Buffer Problems pos2.y+=kTrackHeight; tVector3 crossNormal=!((pos1-pos2)%normal); gTrack[gNumTracks].pos1l=pos1+crossNormal*width*0.5; gTrack[gNumTracks].pos1r=pos1-crossNormal*width*0.5; gTrack[gNumTracks].pos2l=pos2+crossNormal*width*0.5; gTrack[gNumTracks].pos2r=pos2-crossNormal*width*0.5; gTrack[gNumTracks].normal=normal; gTrack[gNumTracks].texture=texture; gTrack[gNumTracks].intensity1=adjustedIntensity; gTrack[gNumTracks].intensity2=adjustedIntensity; gTrack[gNumTracks].l1=0; gTrack[gNumTracks].l2=~(pos2-pos1); //does attach correspods to a given Track Segment in the Buffer? if(attach-gTrackIndexShift>0) { //fix the Track Segments to properly fit together. gTrack[attach-gTrackIndexShift].pos2l=gTrack[gNumTracks].pos1l; gTrack[attach-gTrackIndexShift].pos2r=gTrack[gNumTracks].pos1r; gTrack[attach-gTrackIndexShift].l2=gTrack[attach-gTrackIndexShift].l1+~(gTrack[attach-gTrackIndexShift].pos2l-gTrack[attach-gTrackIndexShift].pos1l); gTrack[attach-gTrackIndexShift].intensity2=adjustedIntensity; float lOffs=gTrack[attach-gTrackIndexShift].l2; gTrack[gNumTracks].l1+=lOffs; gTrack[gNumTracks].l2+=lOffs; } return (gNumTracks++)+gTrackIndexShift; } //clear the Track Segment Buffer void TracksClear() { gNumTracks=0; } //Render the Tracks void TracksRender(tVector3 *clipPlanes) { SetupWorldTranslation(); glPushAttrib(GL_COLOR_BUFFER_BIT+GL_CURRENT_BIT+GL_DEPTH_BUFFER_BIT+GL_LIGHTING_BIT); glDisable(GL_LIGHTING); glEnable(GL_BLEND); glDepthMask(false); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); int tex=-1; for(int i=0;iambient.x+gEnvironment->ambient.y+gEnvironment->ambient.z)*0.33; glBegin(GL_TRIANGLE_STRIP); glTexCoord2d(0,gTrack[i].l1*kTrackTexScale); glColor4f(light,light,light,gTrack[i].intensity1); glVertex3fv(&(gTrack[i].pos1r).x); glTexCoord2d(0,gTrack[i].l2*kTrackTexScale); glColor4f(light,light,light,gTrack[i].intensity2); glVertex3fv(&(gTrack[i].pos2r).x); glTexCoord2d(1,gTrack[i].l1*kTrackTexScale); glColor4f(light,light,light,gTrack[i].intensity1); glVertex3fv(&(gTrack[i].pos1l).x); glTexCoord2d(1,gTrack[i].l2*kTrackTexScale); glColor4f(light,light,light,gTrack[i].intensity2); glVertex3fv(&(gTrack[i].pos2l).x); glEnd(); #ifdef __POLYCOUNT gPolyCount+=2; #endif } glPopAttrib(); }