Redline/source/tracks.cpp

138 lines
4.3 KiB
C++
Raw Normal View History

//tracks.cpp
//draw tire tracks on the road
#include <OpenGL/gl.h>
#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;i<gNumTracks;i++)
//is the segment visible?
if(!ClipPointDistanced(clipPlanes,&gTrack[i].pos1r,gTrack[i].l2-gTrack[i].l1))
{
if(gTrack[i].texture!=tex)
{
tex=gTrack[i].texture;
int texLoaded=gFileTable[tex].parsed;
TexturesSelectTex(tex);
//if the texture has just been loaded, fade the alpha values of the mipmap level textures
//this way we avoid moire effects for tire tracks further in the background.
if(!texLoaded)
TexturesAlphaFadeMipMaps();
}
//draw track segment.
//glNormal3fv(&(gTrack[i].normal).x);
float light=(gEnvironment->ambient.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();
}