mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-11 17:49:53 -10:00
Made some commandline variables fit the naming standard. Changed timerbar system not to run pushes and pops if its not in use. Put in a note about not uncommenting asserts. Fixed up a lot of missing POP's on early returns? Perhaps the motivation for Assert functionality getting commented out? Fixed up some bad asserts. Changed nebula poofs to render in 2D in htl, it makes it look how it used to in non htl. (neb.cpp,1248) Before the poofs were creating a nasty stripe effect where they intersected with ships hulls. Put in a special check for the signs of that D3D init bug I need to lock down.
698 lines
18 KiB
C++
698 lines
18 KiB
C++
/*
|
|
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
|
*
|
|
* All source code herein is the property of Volition, Inc. You may not sell
|
|
* or otherwise commercially exploit the source or things you created based on the
|
|
* source.
|
|
*
|
|
*/
|
|
|
|
/*
|
|
* $Logfile: /Freespace2/code/Weapon/Trails.cpp $
|
|
* $Revision: 2.11 $
|
|
* $Date: 2003-11-19 20:37:25 $
|
|
* $Author: randomtiger $
|
|
*
|
|
* Code for missile trails
|
|
*
|
|
* $Log: not supported by cvs2svn $
|
|
* Revision 2.10 2003/11/17 04:25:58 bobboau
|
|
* made the poly list dynamicly alocated,
|
|
* started work on fixing the node model not rendering,
|
|
* but most of that got commented out so I wouldn't have to deal with it
|
|
* while mucking about with the polylist
|
|
*
|
|
* Revision 2.9 2003/11/16 04:09:20 Goober5000
|
|
* language
|
|
*
|
|
* Revision 2.8 2003/11/11 03:56:13 bobboau
|
|
* lots of bug fixing, much of it in nebula and bitmap drawing
|
|
*
|
|
* Revision 2.7 2003/11/09 06:31:40 Kazan
|
|
* a couple of htl functions being called in nonhtl (ie NULL functions) problems fixed
|
|
* conflicts in cmdline and timerbar.h log entries
|
|
* cvs stopped acting like it was on crack obviously
|
|
*
|
|
* Revision 2.6 2003/11/02 05:50:08 bobboau
|
|
* modified trails to render with tristrips now rather than with stinky old trifans,
|
|
* MUCH faster now, at least one order of magnatude.
|
|
*
|
|
* Revision 2.5 2003/10/23 18:03:25 randomtiger
|
|
* Bobs changes (take 2)
|
|
*
|
|
* Revision 2.4 2003/08/21 15:04:17 phreak
|
|
* zeroed out the specular fields since they caused some flickering
|
|
*
|
|
* Revision 2.3 2003/07/15 16:07:12 phreak
|
|
* trails now properly alphablend in ogl as it does in d3d
|
|
*
|
|
* Revision 2.2 2003/05/04 20:50:06 phreak
|
|
* bumped MAX_TRAILS to 500 because of afterburner trails
|
|
*
|
|
* Revision 2.1 2002/08/01 01:41:11 penguin
|
|
* The big include file move
|
|
*
|
|
* Revision 2.0 2002/06/03 04:02:29 penguin
|
|
* Warpcore CVS sync
|
|
*
|
|
* Revision 1.2 2002/05/04 04:52:22 mharris
|
|
* 1st draft at porting
|
|
*
|
|
* Revision 1.1 2002/05/02 18:03:13 mharris
|
|
* Initial checkin - converted filenames and includes to lower case
|
|
*
|
|
*
|
|
* 7 6/23/99 2:23p Mattk
|
|
* Fixed detail level trail rendering problem.
|
|
*
|
|
* 6 6/22/99 7:03p Dave
|
|
* New detail options screen.
|
|
*
|
|
* 5 2/23/99 8:11p Dave
|
|
* Tidied up dogfight mode. Fixed TvT ship type problems for alpha wing.
|
|
* Small pass over todolist items.
|
|
*
|
|
* 4 2/17/99 2:11p Dave
|
|
* First full run of squad war. All freespace and tracker side stuff
|
|
* works.
|
|
*
|
|
* 3 11/14/98 5:33p Dave
|
|
* Lots of nebula work. Put in ship contrails.
|
|
*
|
|
* 2 10/07/98 10:54a Dave
|
|
* Initial checkin.
|
|
*
|
|
* 1 10/07/98 10:51a Dave
|
|
*
|
|
* 9 5/13/98 3:10p John
|
|
* made detail slider for weapon rendering change the distance that lasers
|
|
* become non-textured. The lowest setting turns off missile trail
|
|
* rendering.
|
|
*
|
|
* 8 5/08/98 7:09p Dave
|
|
* Lots of UI tweaking.
|
|
*
|
|
* 7 4/10/98 5:20p John
|
|
* Changed RGB in lighting structure to be ubytes. Removed old
|
|
* not-necessary 24 bpp software stuff.
|
|
*
|
|
* 6 3/31/98 5:19p John
|
|
* Removed demo/save/restore. Made NDEBUG defined compile. Removed a
|
|
* bunch of debug stuff out of player file. Made model code be able to
|
|
* unload models and malloc out only however many models are needed.
|
|
*
|
|
*
|
|
* 5 3/23/98 5:00p John
|
|
* Improved missile trails. Made smooth alpha under hardware. Made end
|
|
* taper. Made trail touch weapon.
|
|
*
|
|
* 4 1/23/98 5:08p John
|
|
* Took L out of vertex structure used B (blue) instead. Took all small
|
|
* fireballs out of fireball types and used particles instead. Fixed some
|
|
* debris explosion things. Restructured fireball code. Restructured
|
|
* some lighting code. Made dynamic lighting on by default. Made groups
|
|
* of lasers only cast one light. Made fireballs not cast light.
|
|
*
|
|
* 3 1/15/98 11:13a John
|
|
* Added code for specifying weapon trail bitmaps in weapons.tbl
|
|
*
|
|
* 2 12/21/97 6:15p John
|
|
* Made a seperate system for missile trails
|
|
*
|
|
* 1 12/21/97 5:30p John
|
|
* Initial version
|
|
*
|
|
* $NoKeywords: $
|
|
*/
|
|
|
|
#include "globalincs/pstypes.h"
|
|
#include "freespace2/freespace.h"
|
|
#include "weapon/weapon.h"
|
|
#include "globalincs/linklist.h"
|
|
#include "render/3d.h"
|
|
#include "render/3dinternal.h"
|
|
#include "bmpman/bmpman.h"
|
|
#include "weapon/trails.h"
|
|
#include "debugconsole/timerbar.h"
|
|
#include "io/timer.h"
|
|
|
|
#define MAX_TRAILS 500
|
|
|
|
// Stuff for missile trails doesn't need to be saved or restored... or does it?
|
|
typedef struct trail {
|
|
int head, tail; // pointers into the queue for the trail points
|
|
vector pos[NUM_TRAIL_SECTIONS]; // positions of trail points
|
|
float val[NUM_TRAIL_SECTIONS]; // for each point, a value that tells how much to fade out
|
|
int object_died; // set to zero as long as object
|
|
int trail_stamp; // trail timestamp
|
|
|
|
// trail info
|
|
trail_info info; // this is passed when creating a trail
|
|
|
|
struct trail * prev;
|
|
struct trail * next;
|
|
} trail;
|
|
|
|
|
|
int Num_trails = 0;
|
|
trail Trails[MAX_TRAILS];
|
|
|
|
trail Trail_free_list;
|
|
trail Trail_used_list;
|
|
|
|
// Reset everything between levels
|
|
void trail_level_init()
|
|
{
|
|
int i;
|
|
|
|
Num_trails = 0;
|
|
list_init( &Trail_free_list );
|
|
list_init( &Trail_used_list );
|
|
|
|
// Link all object slots into the free list
|
|
for (i=0; i<MAX_TRAILS; i++) {
|
|
list_append(&Trail_free_list, &Trails[i] );
|
|
}
|
|
}
|
|
|
|
//returns the number of a free trail
|
|
//returns -1 if no free trails
|
|
int trail_create(trail_info info)
|
|
{
|
|
int trail_num;
|
|
trail *trailp;
|
|
|
|
// standalone server should never create trails
|
|
if(Game_mode & GM_STANDALONE_SERVER){
|
|
return -1;
|
|
}
|
|
|
|
if ( !Detail.weapon_extras ) {
|
|
// No trails at slot 0
|
|
return -1;
|
|
}
|
|
|
|
if (Num_trails >= MAX_TRAILS ) {
|
|
#ifndef NDEBUG
|
|
mprintf(("Trail creation failed - too many trails!\n" ));
|
|
#endif
|
|
return -1;
|
|
}
|
|
|
|
// Find next available trail
|
|
trailp = GET_FIRST(&Trail_free_list);
|
|
Assert( trailp != &Trail_free_list ); // shouldn't have the dummy element
|
|
|
|
// remove trailp from the free list
|
|
list_remove( &Trail_free_list, trailp );
|
|
|
|
// insert trailp onto the end of used list
|
|
list_append( &Trail_used_list, trailp );
|
|
|
|
// increment counter
|
|
Num_trails++;
|
|
|
|
// get objnum
|
|
trail_num = trailp-Trails;
|
|
|
|
// Init the trail data
|
|
trailp->info = info;
|
|
trailp->tail = 0;
|
|
trailp->head = 0;
|
|
trailp->object_died = 0;
|
|
trailp->trail_stamp = timestamp(trailp->info.stamp);
|
|
|
|
return trail_num;
|
|
}
|
|
|
|
// output top and bottom vectors
|
|
// fvec == forward vector (eye viewpoint basically. in world coords)
|
|
// pos == world coordinate of the point we're calculating "around"
|
|
// w == width of the diff between top and bottom around pos
|
|
void trail_calc_facing_pts( vector *top, vector *bot, vector *fvec, vector *pos, float w )
|
|
{
|
|
vector uvec, rvec;
|
|
|
|
vm_vec_sub( &rvec, &Eye_position, pos );
|
|
vm_vec_normalize( &rvec );
|
|
|
|
vm_vec_crossprod(&uvec,fvec,&rvec);
|
|
vm_vec_normalize(&uvec);
|
|
|
|
vm_vec_scale_add( top, pos, &uvec, w/2.0f );
|
|
vm_vec_scale_add( bot, pos, &uvec, -w/2.0f );
|
|
}
|
|
|
|
// trail is on ship
|
|
int trail_is_on_ship(int trail_index, ship *shipp)
|
|
{
|
|
int idx;
|
|
|
|
for(idx=0; idx<MAX_SHIP_CONTRAILS; idx++){
|
|
if(shipp->trail_num[idx] == (short)trail_index){
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
// nope
|
|
return 0;
|
|
}
|
|
|
|
extern int OGL_inited;
|
|
|
|
// Render the trail behind a missile.
|
|
// Basically a queue of points that face the viewer
|
|
extern int Cmdline_nohtl;
|
|
/*
|
|
void trail_render( trail * trailp )
|
|
{
|
|
TIMERBAR_PUSH(6);
|
|
trail_info *ti;
|
|
|
|
if ( trailp->tail == trailp->head ) return;
|
|
|
|
ti = &trailp->info;
|
|
|
|
vector topv, botv, *fvec, last_pos, tmp_fvec;
|
|
vertex last_top, last_bot, top, bot;
|
|
|
|
int sections[NUM_TRAIL_SECTIONS];
|
|
int num_sections = 0;
|
|
|
|
int n = trailp->tail;
|
|
|
|
// if this trail is on the player ship, and he's in any padlock view except rear view, don't draw
|
|
if((Player_ship != NULL) && trail_is_on_ship(trailp - Trails, Player_ship) && (Viewer_mode & (VM_PADLOCK_UP | VM_PADLOCK_LEFT | VM_PADLOCK_RIGHT)) ){
|
|
return;
|
|
}
|
|
|
|
do {
|
|
n--;
|
|
if ( n < 0 ) n = NUM_TRAIL_SECTIONS-1;
|
|
|
|
|
|
if ( trailp->val[n] > 1.0f ) {
|
|
break;
|
|
}
|
|
|
|
sections[num_sections++] = n;
|
|
|
|
} while ( n != trailp->head );
|
|
|
|
int i;
|
|
|
|
for (i=0; i<num_sections; i++ ) {
|
|
|
|
n = sections[i];
|
|
|
|
float w;
|
|
ubyte l;
|
|
|
|
w = trailp->val[n]*(ti->w_end - ti->w_start) + ti->w_start;
|
|
l = (ubyte)fl2i((trailp->val[n]*(ti->a_end - ti->a_start) + ti->a_start)*255.0f);
|
|
|
|
vector pos;
|
|
|
|
pos = trailp->pos[n];
|
|
|
|
if ( i == 0 ) {
|
|
//fvec =
|
|
//&objp->orient.fvec;
|
|
if ( num_sections > 1 ) {
|
|
|
|
vm_vec_sub(&tmp_fvec, &pos, &trailp->pos[sections[i+1]] );
|
|
vm_vec_normalize_safe(&tmp_fvec);
|
|
fvec = &tmp_fvec;
|
|
|
|
} else {
|
|
fvec = &tmp_fvec;
|
|
fvec->xyz.x = 0.0f;
|
|
fvec->xyz.y = 0.0f;
|
|
fvec->xyz.z = 1.0f;
|
|
}
|
|
} else {
|
|
vm_vec_sub(&tmp_fvec, &last_pos, &pos );
|
|
vm_vec_normalize_safe(&tmp_fvec);
|
|
fvec = &tmp_fvec;
|
|
}
|
|
|
|
trail_calc_facing_pts( &topv, &botv, fvec, &pos, w );
|
|
|
|
if(!Cmdline_nohtl){
|
|
g3_transfer_vertex( &top, &topv );
|
|
g3_transfer_vertex( &bot, &botv );
|
|
}else{
|
|
g3_rotate_vertex( &top, &topv );
|
|
g3_rotate_vertex( &bot, &botv );
|
|
}
|
|
top.a = bot.a = l;
|
|
|
|
if ( i > 0 ) {
|
|
|
|
if ( i == num_sections-1 ) {
|
|
// Last one...
|
|
vector centerv;
|
|
vm_vec_avg( ¢erv, &topv, &botv );
|
|
vertex center;
|
|
if(!Cmdline_nohtl){
|
|
g3_transfer_vertex( ¢er, ¢erv );
|
|
}else{
|
|
g3_rotate_vertex( ¢er, ¢erv );
|
|
}
|
|
center.a = l;
|
|
|
|
vertex *vlist[3];
|
|
vlist[0] = &last_top;
|
|
vlist[1] = &last_bot;
|
|
vlist[2] = ¢er;
|
|
|
|
vlist[0]->u = 0.0f; vlist[0]->v = 1.0f; vlist[0]->spec_r=vlist[0]->spec_g=vlist[0]->spec_b=0;
|
|
vlist[1]->u = 0.0f; vlist[1]->v = 0.0f; vlist[1]->spec_r=vlist[1]->spec_g=vlist[1]->spec_b=0;
|
|
vlist[2]->u = 1.0f; vlist[2]->v = 0.5f; vlist[1]->spec_r=vlist[1]->spec_g=vlist[1]->spec_b=0;
|
|
|
|
gr_set_bitmap(ti->bitmap, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, l/255.0f );
|
|
if ( D3D_enabled || OGL_inited ) {
|
|
|
|
if(Cmdline_nohtl)g3_draw_poly( 3, vlist, TMAP_FLAG_TEXTURED|TMAP_FLAG_ALPHA|TMAP_FLAG_GOURAUD );
|
|
else g3_draw_poly( 3, vlist, TMAP_FLAG_TEXTURED|TMAP_FLAG_ALPHA|TMAP_FLAG_GOURAUD | TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT );
|
|
} else {
|
|
if(Cmdline_nohtl)g3_draw_poly( 3, vlist, TMAP_FLAG_TEXTURED );
|
|
else g3_draw_poly( 3, vlist, TMAP_FLAG_TEXTURED | TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT);
|
|
}
|
|
|
|
|
|
} else {
|
|
vertex *vlist[4];
|
|
vlist[0] = &last_bot;
|
|
vlist[1] = ⊥
|
|
vlist[2] = ⊤
|
|
vlist[3] = &last_top;
|
|
|
|
vlist[0]->u = 0.0f; vlist[0]->v = 0.0f; vlist[0]->spec_r=vlist[0]->spec_g=vlist[0]->spec_b=0;
|
|
vlist[1]->u = 1.0f; vlist[1]->v = 0.0f; vlist[1]->spec_r=vlist[1]->spec_g=vlist[1]->spec_b=0;
|
|
vlist[2]->u = 1.0f; vlist[2]->v = 1.0f; vlist[2]->spec_r=vlist[2]->spec_g=vlist[2]->spec_b=0;
|
|
vlist[3]->u = 0.0f; vlist[3]->v = 1.0f; vlist[3]->spec_r=vlist[3]->spec_g=vlist[3]->spec_b=0;
|
|
|
|
gr_set_bitmap(ti->bitmap, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, l/255.0f );
|
|
if ( D3D_enabled || OGL_inited ) {
|
|
if(Cmdline_nohtl)g3_draw_poly( 4, vlist, TMAP_FLAG_TEXTURED|TMAP_FLAG_ALPHA|TMAP_FLAG_GOURAUD );
|
|
else g3_draw_poly( 4, vlist, TMAP_FLAG_TEXTURED|TMAP_FLAG_ALPHA|TMAP_FLAG_GOURAUD | TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT );
|
|
} else {
|
|
if(Cmdline_nohtl)g3_draw_poly( 4, vlist, TMAP_FLAG_TEXTURED );
|
|
else g3_draw_poly( 4, vlist, TMAP_FLAG_TEXTURED | TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT );
|
|
}
|
|
}
|
|
}
|
|
last_pos = pos;
|
|
last_top = top;
|
|
last_bot = bot;
|
|
}
|
|
TIMERBAR_POP();
|
|
}
|
|
*/
|
|
#define MAX_TRAIL_POLYS 129
|
|
void trail_render( trail * trailp )
|
|
{
|
|
TIMERBAR_PUSH(6);
|
|
// if(!Cmdline_nohtl)gr_set_lighting(false,false);//this shouldn't need to be here but it does need to be here, WHY!!!!!!!?-Bobboau
|
|
trail_info *ti;
|
|
|
|
if ( trailp->tail == trailp->head )
|
|
{
|
|
TIMERBAR_POP();
|
|
return;
|
|
}
|
|
|
|
ti = &trailp->info;
|
|
|
|
vector topv, botv, *fvec, last_pos, tmp_fvec;
|
|
vertex top, bot;
|
|
|
|
int sections[NUM_TRAIL_SECTIONS];
|
|
int num_sections = 0;
|
|
|
|
int n = trailp->tail;
|
|
|
|
// if this trail is on the player ship, and he's in any padlock view except rear view, don't draw
|
|
if((Player_ship != NULL) && trail_is_on_ship(trailp - Trails, Player_ship) && (Viewer_mode & (VM_PADLOCK_UP | VM_PADLOCK_LEFT | VM_PADLOCK_RIGHT)) ){
|
|
return;
|
|
}
|
|
|
|
do {
|
|
n--;
|
|
if ( n < 0 ) n = NUM_TRAIL_SECTIONS-1;
|
|
|
|
|
|
if ( trailp->val[n] > 1.0f ) {
|
|
break;
|
|
}
|
|
|
|
sections[num_sections++] = n;
|
|
|
|
} while ( n != trailp->head );
|
|
|
|
int i;
|
|
|
|
vertex *vlist[MAX_TRAIL_POLYS];
|
|
vertex v_list[MAX_TRAIL_POLYS];
|
|
int nv = 0;
|
|
|
|
for (i=0; i<num_sections; i++ ) {
|
|
|
|
if(nv>MAX_TRAIL_POLYS-3)Error( LOCATION, "too many verts in trail render\n" );
|
|
|
|
n = sections[i];
|
|
|
|
float w;
|
|
ubyte l;
|
|
|
|
w = trailp->val[n]*(ti->w_end - ti->w_start) + ti->w_start;
|
|
l = (ubyte)fl2i((trailp->val[n]*(ti->a_end - ti->a_start) + ti->a_start)*255.0f);
|
|
|
|
vector pos;
|
|
|
|
pos = trailp->pos[n];
|
|
|
|
if ( i == 0 ) {
|
|
//fvec =
|
|
//&objp->orient.fvec;
|
|
if ( num_sections > 1 ) {
|
|
|
|
vm_vec_sub(&tmp_fvec, &pos, &trailp->pos[sections[i+1]] );
|
|
vm_vec_normalize_safe(&tmp_fvec);
|
|
fvec = &tmp_fvec;
|
|
|
|
} else {
|
|
fvec = &tmp_fvec;
|
|
fvec->xyz.x = 0.0f;
|
|
fvec->xyz.y = 0.0f;
|
|
fvec->xyz.z = 1.0f;
|
|
}
|
|
} else {
|
|
vm_vec_sub(&tmp_fvec, &last_pos, &pos );
|
|
vm_vec_normalize_safe(&tmp_fvec);
|
|
fvec = &tmp_fvec;
|
|
}
|
|
|
|
trail_calc_facing_pts( &topv, &botv, fvec, &pos, w );
|
|
|
|
if(!Cmdline_nohtl){
|
|
g3_transfer_vertex( &top, &topv );
|
|
g3_transfer_vertex( &bot, &botv );
|
|
}else{
|
|
g3_rotate_vertex( &top, &topv );
|
|
g3_rotate_vertex( &bot, &botv );
|
|
}
|
|
top.a = bot.a = l;
|
|
|
|
if ( i > 0 ) {
|
|
|
|
if ( i == num_sections-1 ) {
|
|
// Last one...
|
|
vector centerv;
|
|
vm_vec_avg( ¢erv, &topv, &botv );
|
|
if(!Cmdline_nohtl){
|
|
g3_transfer_vertex( &v_list[nv+2], ¢erv );
|
|
}else{
|
|
g3_rotate_vertex( &v_list[nv+2], ¢erv );
|
|
}
|
|
v_list[nv].a = l;
|
|
|
|
vlist[nv] = &v_list[nv];
|
|
vlist[nv]->u = float(i); vlist[nv]->v = 1.0f;
|
|
vlist[nv]->r=vlist[nv]->g=vlist[nv]->b=l; vlist[nv]->spec_r=vlist[nv]->spec_g=vlist[nv]->spec_b=0;;
|
|
nv++;
|
|
vlist[nv] = &v_list[nv];
|
|
vlist[nv]->u = float(i); vlist[nv]->v = 0.0f;
|
|
vlist[nv]->r=vlist[nv]->g=vlist[nv]->b=l; vlist[nv]->spec_r=vlist[nv]->spec_g=vlist[nv]->spec_b=0;
|
|
nv++;
|
|
vlist[nv] = &v_list[nv];
|
|
vlist[nv]->u = float(i+1); vlist[nv]->v = 0.5f;
|
|
vlist[nv]->r=vlist[nv]->g=vlist[nv]->b=0; vlist[nv]->spec_r=vlist[nv]->spec_g=vlist[nv]->spec_b=0;
|
|
nv++;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
vlist[nv] = &v_list[nv];
|
|
vlist[nv]->u = float(i); vlist[nv]->v = 1.0f;
|
|
vlist[nv]->r=vlist[nv]->g=vlist[nv]->b=l; vlist[nv]->spec_r=vlist[nv]->spec_g=vlist[nv]->spec_b=0;
|
|
nv++;
|
|
vlist[nv] = &v_list[nv];
|
|
vlist[nv]->u = float(i); vlist[nv]->v = 0.0f;
|
|
vlist[nv]->r=vlist[nv]->g=vlist[nv]->b=l; vlist[nv]->spec_r=vlist[nv]->spec_g=vlist[nv]->spec_b=0;
|
|
nv++;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
last_pos = pos;
|
|
v_list[nv] = top;
|
|
v_list[nv+1] = bot;
|
|
}
|
|
if(!nv) {
|
|
TIMERBAR_POP();
|
|
return;
|
|
}
|
|
if(nv<3)Error( LOCATION, "too few verts in trail render\n" );
|
|
if(nv>MAX_TRAIL_POLYS-1)Error( LOCATION, "too many verts in trail render\n" );
|
|
if(nv%2 != 1)Error( LOCATION, "even number of verts verts in trail render\n" );//there should always be three virts in the last section and 2 everyware else, therefore there should always be an odd number of verts
|
|
|
|
gr_set_bitmap(ti->bitmap, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 1.0f );
|
|
if ( D3D_enabled || OGL_inited ) {
|
|
if(Cmdline_nohtl) g3_draw_poly( nv, vlist, TMAP_FLAG_TEXTURED|TMAP_FLAG_ALPHA|TMAP_FLAG_GOURAUD | TMAP_FLAG_RGB | TMAP_FLAG_TRISTRIP );
|
|
else g3_draw_poly( nv, vlist, TMAP_FLAG_TEXTURED|TMAP_FLAG_ALPHA|TMAP_FLAG_GOURAUD | TMAP_FLAG_RGB | TMAP_HTL_3D_UNLIT | TMAP_FLAG_TRISTRIP );
|
|
} else {
|
|
if(Cmdline_nohtl)g3_draw_poly( nv, vlist, TMAP_FLAG_TEXTURED | TMAP_FLAG_TRISTRIP);
|
|
else g3_draw_poly( nv, vlist, TMAP_FLAG_TEXTURED | TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT | TMAP_FLAG_TRISTRIP);
|
|
}
|
|
TIMERBAR_POP();
|
|
}
|
|
|
|
|
|
|
|
void trail_add_segment( int trail_num, vector *pos )
|
|
{
|
|
if (trail_num < 0 ) return;
|
|
if (trail_num >= MAX_TRAILS ) return;
|
|
|
|
trail *trailp = &Trails[trail_num];
|
|
|
|
int next = trailp->tail;
|
|
trailp->tail++;
|
|
if ( trailp->tail >= NUM_TRAIL_SECTIONS )
|
|
trailp->tail = 0;
|
|
|
|
if ( trailp->head == trailp->tail ) {
|
|
// wrapped!!
|
|
trailp->head++;
|
|
if ( trailp->head >= NUM_TRAIL_SECTIONS )
|
|
trailp->head = 0;
|
|
}
|
|
|
|
trailp->pos[next] = *pos;
|
|
trailp->val[next] = 0.0f;
|
|
}
|
|
|
|
void trail_set_segment( int trail_num, vector *pos )
|
|
{
|
|
if (trail_num < 0 ) return;
|
|
if (trail_num >= MAX_TRAILS ) return;
|
|
|
|
trail *trailp = &Trails[trail_num];
|
|
|
|
int next = trailp->tail-1;
|
|
if ( next < 0 ) {
|
|
next = NUM_TRAIL_SECTIONS-1;
|
|
}
|
|
|
|
trailp->pos[next] = *pos;
|
|
}
|
|
|
|
void trail_move_all(float frametime)
|
|
{
|
|
trail *trailp;
|
|
|
|
trailp=GET_FIRST(&Trail_used_list);
|
|
|
|
while ( trailp!=END_OF_LIST(&Trail_used_list) ) {
|
|
|
|
int num_alive_segments = 0;
|
|
|
|
if ( trailp->tail != trailp->head ) {
|
|
int n = trailp->tail;
|
|
float time_delta = frametime / trailp->info.max_life;
|
|
do {
|
|
n--;
|
|
if ( n < 0 ) n = NUM_TRAIL_SECTIONS-1;
|
|
|
|
trailp->val[n] += time_delta;
|
|
|
|
if ( trailp->val[n] <= 1.0f ) {
|
|
num_alive_segments++; // Record how many still alive.
|
|
}
|
|
|
|
} while ( n != trailp->head );
|
|
}
|
|
|
|
if ( trailp->object_died && (num_alive_segments < 1) ) {
|
|
// delete it from the list!
|
|
trail *next_one = GET_NEXT(trailp);
|
|
|
|
// remove objp from the used list
|
|
list_remove( &Trail_used_list, trailp);
|
|
|
|
// add objp to the end of the free
|
|
list_append( &Trail_free_list, trailp );
|
|
|
|
// decrement counter
|
|
Num_trails--;
|
|
|
|
Assert(Num_trails >= 0);
|
|
|
|
trailp = next_one;
|
|
} else {
|
|
trailp=GET_NEXT(trailp);
|
|
}
|
|
}
|
|
}
|
|
|
|
void trail_object_died( int trail_num )
|
|
{
|
|
if (trail_num < 0 ) return;
|
|
if (trail_num >= MAX_TRAILS ) return;
|
|
|
|
trail *trailp = &Trails[trail_num];
|
|
|
|
trailp->object_died++;
|
|
}
|
|
|
|
void trail_render_all()
|
|
{
|
|
trail *trailp;
|
|
|
|
if ( !Detail.weapon_extras ) {
|
|
// No trails at slot 0
|
|
return;
|
|
}
|
|
|
|
trailp=GET_FIRST(&Trail_used_list);
|
|
|
|
while ( trailp!=END_OF_LIST(&Trail_used_list) ) {
|
|
trail_render(trailp);
|
|
trailp=GET_NEXT(trailp);
|
|
}
|
|
|
|
}
|
|
int trail_stamp_elapsed(int trail_num)
|
|
{
|
|
return timestamp_elapsed(Trails[trail_num].trail_stamp);
|
|
}
|
|
|
|
void trail_set_stamp(int trail_num)
|
|
{
|
|
Trails[trail_num].trail_stamp = timestamp(Trails[trail_num].info.stamp);
|
|
}
|