Exemplo n.º 1
0
void trail_render( trail * trailp )
{
	int sections[NUM_TRAIL_SECTIONS];
	int num_sections = 0;
	int i;
	vec3d topv, botv, *fvec, last_pos, tmp_fvec;
	vertex  top, bot;
	int nv = 0;
	float w;
	ubyte l;
	vec3d centerv;

	if (trailp->tail == trailp->head)
		return;

	// 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, Player_ship) &&
		(Viewer_mode & (VM_PADLOCK_UP | VM_PADLOCK_LEFT | VM_PADLOCK_RIGHT)) )
	{
		return;
	}

	trail_info *ti	= &trailp->info;

	int n = trailp->tail;

	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 );

	if (num_sections <= 0)
		return;

	Assertion(ti->texture.bitmap_id != -1, "Weapon trail %s could not be loaded", ti->texture.filename); // We can leave this as an assert, but tell them how to fix it. --Chief

	memset( &top, 0, sizeof(vertex) );
	memset( &bot, 0, sizeof(vertex) );

	// it's a tristrip, so allocate for 2+1
	allocate_trail_verts((num_sections * 2) + 1);

	float w_size = (ti->w_end - ti->w_start);
	float a_size = (ti->a_end - ti->a_start);
	int num_faded_sections = ti->n_fade_out_sections;

	for (i = 0; i < num_sections; i++) {
		n = sections[i];
		float init_fade_out = 1.0f;

		if ((num_faded_sections > 0) && (i < num_faded_sections)) {
			init_fade_out = ((float) i) / (float) num_faded_sections;
		}

		w = trailp->val[n] * w_size + ti->w_start;
		if (init_fade_out != 1.0f) {
			l = (ubyte)fl2i((trailp->val[n] * a_size + ti->a_start) * 255.0f * init_fade_out * init_fade_out);
		} else {
			l = (ubyte)fl2i((trailp->val[n] * a_size + ti->a_start) * 255.0f);
		}

		if ( i == 0 )	{
			if ( num_sections > 1 )	{
				vm_vec_sub(&tmp_fvec, &trailp->pos[n], &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, &trailp->pos[n] );
			vm_vec_normalize_safe(&tmp_fvec);
			fvec = &tmp_fvec;
		}

		trail_calc_facing_pts( &topv, &botv, fvec, &trailp->pos[n], 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) {
			float U = i2fl(i);

			if (i == num_sections-1) {
				// Last one...
				vm_vec_avg( &centerv, &topv, &botv );

				if ( !Cmdline_nohtl )
					g3_transfer_vertex( &Trail_v_list[nv+2], &centerv );
				else
					g3_rotate_vertex( &Trail_v_list[nv+2], &centerv );

				Trail_v_list[nv].a = l;	

				Trail_v_list[nv].texture_position.u = U;
				Trail_v_list[nv].texture_position.v = 1.0f; 
				Trail_v_list[nv].r = Trail_v_list[nv].g = Trail_v_list[nv].b = l;
				nv++;

				Trail_v_list[nv].texture_position.u = U;
				Trail_v_list[nv].texture_position.v = 0.0f; 
				Trail_v_list[nv].r = Trail_v_list[nv].g = Trail_v_list[nv].b = l;
				nv++;

				Trail_v_list[nv].texture_position.u = U + 1.0f;
				Trail_v_list[nv].texture_position.v = 0.5f;
				Trail_v_list[nv].r = Trail_v_list[nv].g = Trail_v_list[nv].b = 0;
				nv++;
			} else {
				Trail_v_list[nv].texture_position.u = U;
				Trail_v_list[nv].texture_position.v = 1.0f; 
				Trail_v_list[nv].r = Trail_v_list[nv].g = Trail_v_list[nv].b = l;
				nv++;

				Trail_v_list[nv].texture_position.u = U;
				Trail_v_list[nv].texture_position.v = 0.0f; 
				Trail_v_list[nv].r = Trail_v_list[nv].g = Trail_v_list[nv].b = l;
				nv++;
			}
		}

		last_pos = trailp->pos[n];
		Trail_v_list[nv] = top;
		Trail_v_list[nv+1] = bot;
	}

	if ( !nv )
		return;

	if (nv < 3)
		Error( LOCATION, "too few verts in trail render\n" );

	// there should always be three verts in the last section and 2 everyware else, therefore there should always be an odd number of verts
	if ( (nv % 2) != 1 )
		Warning( LOCATION, "even number of verts in trail render\n" );

	profile_begin("Trail Draw");
	gr_set_bitmap( ti->texture.bitmap_id, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 1.0f );
	gr_render(nv, Trail_v_list, TMAP_FLAG_TEXTURED | TMAP_FLAG_ALPHA | TMAP_FLAG_GOURAUD | TMAP_FLAG_RGB | TMAP_HTL_3D_UNLIT | TMAP_FLAG_TRISTRIP);
	profile_end("Trail Draw");
}
Exemplo n.º 2
0
void particle_render_all()
{
	ubyte flags;
	float pct_complete;
	float alpha;
	vertex pos;
	vec3d ts, te, temp;
	int rotate = 1;
	int framenum, cur_frame;
	bool render_batch = false;
	int tmap_flags = TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT | TMAP_FLAG_SOFT_QUAD;

	if ( !Particles_enabled )
		return;

	MONITOR_INC( NumParticlesRend, Num_particles );	

	if ( Particles.empty() )
		return;

	for (SCP_vector<particle*>::iterator p = Particles.begin(); p != Particles.end(); ++p) {
		particle* part = *p;
		// skip back-facing particles (ripped from fullneb code)
		// Wanderer - add support for attached particles
		vec3d p_pos;
		if (part->attached_objnum >= 0) {
			vm_vec_unrotate(&p_pos, &part->pos, &Objects[part->attached_objnum].orient);
			vm_vec_add2(&p_pos, &Objects[part->attached_objnum].pos);
		} else {
			p_pos = part->pos;
		}

		if ( vm_vec_dot_to_point(&Eye_matrix.vec.fvec, &Eye_position, &p_pos) <= 0.0f ) {
			continue;
		}

		// calculate the alpha to draw at
		alpha = get_current_alpha(&p_pos);

		// if it's transparent then just skip it
		if (alpha <= 0.0f) {
			continue;
		}

		// make sure "rotate" is enabled for this particle
		rotate = 1;

		// if this is a tracer style particle, calculate tracer vectors
		if (part->tracer_length > 0.0f) {			
			ts = p_pos;
			temp = part->velocity;
			vm_vec_normalize_quick(&temp);
			vm_vec_scale_add(&te, &ts, &temp, part->tracer_length);

			// don't bother rotating
			rotate = 0;
		}

		// rotate the vertex
		if (rotate) {
			flags = g3_rotate_vertex( &pos, &p_pos );

			if ( flags ) {
				continue;
			}

			if (!Cmdline_nohtl)
				g3_transfer_vertex(&pos, &p_pos);
		}

		// pct complete for the particle
		pct_complete = part->age / part->max_life;

		// figure out which frame we should be using
		if (part->nframes > 1) {
			framenum = fl2i(pct_complete * part->nframes + 0.5);
			CLAMP(framenum, 0, part->nframes-1);

			cur_frame = part->reverse ? (part->nframes - framenum - 1) : framenum;
		} else {
			cur_frame = 0;
		}

		if (part->type == PARTICLE_DEBUG) {
			gr_set_color( 255, 0, 0 );
			g3_draw_sphere_ez( &p_pos, part->radius );
		} else {
			framenum = part->optional_data;

			Assert( cur_frame < part->nframes );

			// if this is a tracer style particle
			if (part->tracer_length > 0.0f) {
				batch_add_laser( framenum + cur_frame, &ts, part->radius, &te, part->radius );
			}
			// draw as a regular bitmap
			else {
				batch_add_bitmap( framenum + cur_frame, tmap_flags, &pos, part->particle_index % 8, part->radius, alpha );
			}

			render_batch = true;
		}
	}

	profile_begin("Batch Render");
	if (render_batch) {
		batch_render_all(Particle_buffer_object);
	}
	profile_end("Batch Render");
}