コード例 #1
0
/*
===============
CG_ApplyJitters
===============
*/
static void CG_ApplyJitters( trailBeam_t *tb )
{
	trailBeamNode_t *i = nullptr;
	int             j;
	baseTrailBeam_t *btb;
	trailSystem_t   *ts;
	trailBeamNode_t *start;
	trailBeamNode_t *end;

	if ( !tb || !tb->nodes )
	{
		return;
	}

	btb = tb->class_;
	ts = tb->parent;

	for ( j = 0; j < btb->numJitters; j++ )
	{
		if ( tb->nextJitterTimes[ j ] <= cg.time )
		{
			for ( i = tb->nodes; i; i = i->next )
			{
				i->jitters[ j ][ 0 ] = ( crandom() * btb->jitters[ j ].magnitude );
				i->jitters[ j ][ 1 ] = ( crandom() * btb->jitters[ j ].magnitude );
			}

			tb->nextJitterTimes[ j ] = cg.time + btb->jitters[ j ].period;
		}
	}

	start = tb->nodes;
	end = CG_FindLastBeamNode( tb );

	if ( !btb->jitterAttachments )
	{
		if ( CG_Attached( &ts->frontAttachment ) && start->next )
		{
			start = start->next;
		}

		if ( CG_Attached( &ts->backAttachment ) && end->prev )
		{
			end = end->prev;
		}
	}

	for ( i = start; i; i = i->next )
	{
		vec3_t          forward, right, up;
		trailBeamNode_t *prev;
		trailBeamNode_t *next;
		float           upJitter = 0.0f, rightJitter = 0.0f;

		prev = i->prev;
		next = i->next;

		if ( prev && next )
		{
			//this node has two neighbours
			GetPerpendicularViewVector( cg.refdef.vieworg, next->position, prev->position, up );
			VectorSubtract( next->position, prev->position, forward );
		}
		else if ( !prev && next )
		{
			//this is the front
			GetPerpendicularViewVector( cg.refdef.vieworg, next->position, i->position, up );
			VectorSubtract( next->position, i->position, forward );
		}
		else if ( prev && !next )
		{
			//this is the back
			GetPerpendicularViewVector( cg.refdef.vieworg, i->position, prev->position, up );
			VectorSubtract( i->position, prev->position, forward );
		}

		VectorNormalize( forward );
		CrossProduct( forward, up, right );
		VectorNormalize( right );

		for ( j = 0; j < btb->numJitters; j++ )
		{
			upJitter += i->jitters[ j ][ 0 ];
			rightJitter += i->jitters[ j ][ 1 ];
		}

		VectorMA( i->position, upJitter, up, i->position );
		VectorMA( i->position, rightJitter, right, i->position );

		if ( i == end )
		{
			break;
		}
	}
}
コード例 #2
0
ファイル: cg_trails.c プロジェクト: Diskutant/RTCW-SP
void CG_AddTrailToScene(trailJunc_t *trail, int iteration, int numJuncs)
{
#define MAX_TRAIL_VERTS     2048
	polyVert_t verts[MAX_TRAIL_VERTS];
	polyVert_t outVerts[MAX_TRAIL_VERTS * 3];
	int k, i, n, l, numOutVerts;
	polyVert_t mid;
	float mod[4];
	float sInc = 0.0f, s = 0.0f;   // TTimo: init
	trailJunc_t *j, *jNext;
	vec3_t fwd, up, p, v;
	(void)fwd; // Ignore compiler warning -- Justasic
	// clipping vars
#define TRAIL_FADE_CLOSE_DIST   64.0
#define TRAIL_FADE_FAR_SCALE    4.0
	vec3_t viewProj;
	float viewDist, fadeAlpha;

	// add spark shader at head position
	if(trail->flags & TJFL_SPARKHEADFLARE)
	{
		j = trail;
		VectorCopy(j->pos, p);
		VectorMA(p, -j->width * 2, vup, p);
		VectorMA(p, -j->width * 2, vright, p);
		VectorCopy(p, verts[0].xyz);
		verts[0].st[0] = 0;
		verts[0].st[1] = 0;
		verts[0].modulate[0] = 255;
		verts[0].modulate[1] = 255;
		verts[0].modulate[2] = 255;
		verts[0].modulate[3] = (unsigned char)(j->alpha * 255.0);

		VectorCopy(j->pos, p);
		VectorMA(p, -j->width * 2, vup, p);
		VectorMA(p, j->width * 2, vright, p);
		VectorCopy(p, verts[1].xyz);
		verts[1].st[0] = 0;
		verts[1].st[1] = 1;
		verts[1].modulate[0] = 255;
		verts[1].modulate[1] = 255;
		verts[1].modulate[2] = 255;
		verts[1].modulate[3] = (unsigned char)(j->alpha * 255.0);

		VectorCopy(j->pos, p);
		VectorMA(p, j->width * 2, vup, p);
		VectorMA(p, j->width * 2, vright, p);
		VectorCopy(p, verts[2].xyz);
		verts[2].st[0] = 1;
		verts[2].st[1] = 1;
		verts[2].modulate[0] = 255;
		verts[2].modulate[1] = 255;
		verts[2].modulate[2] = 255;
		verts[2].modulate[3] = (unsigned char)(j->alpha * 255.0);

		VectorCopy(j->pos, p);
		VectorMA(p,  j->width * 2, vup, p);
		VectorMA(p, -j->width * 2, vright, p);
		VectorCopy(p, verts[3].xyz);
		verts[3].st[0] = 1;
		verts[3].st[1] = 0;
		verts[3].modulate[0] = 255;
		verts[3].modulate[1] = 255;
		verts[3].modulate[2] = 255;
		verts[3].modulate[3] = (unsigned char)(j->alpha * 255.0);

		trap_R_AddPolyToScene(cgs.media.sparkFlareShader, 4, verts);
	}

//	if (trail->flags & TJFL_CROSSOVER && iteration < 1) {
//		iteration = 1;
//	}

	if(!numJuncs)
	{
		// first count the number of juncs in the trail
		j = trail;
		numJuncs = 0;
		sInc = 0;

		while(j)
		{
			numJuncs++;

			// check for a dead next junc
			if(!j->inuse && j->nextJunc && !j->nextJunc->inuse)
			{
				CG_KillTrail(j);
			}
			else if(j->nextJunc && j->nextJunc->freed)
			{
				// not sure how this can happen, but it does, and causes infinite loops
				j->nextJunc = NULL;
			}

			if(j->nextJunc)
			{
				sInc += VectorDistance(j->nextJunc->pos, j->pos);
			}

			j = j->nextJunc;
		}
	}

	if(numJuncs < 2)
	{
		return;
	}

	if(trail->sType == STYPE_STRETCH)
	{
		//sInc = ((1.0 - 0.1) / (float)(numJuncs)); // hack, the end of funnel shows a bit of the start (looping)
		s = 0.05;
		//s = 0.05;
	}
	else if(trail->sType == STYPE_REPEAT)
	{
		s = trail->sTex;
	}

	// now traverse the list
	j = trail;
	jNext = j->nextJunc;
	i = 0;

	while(jNext)
	{

		// first get the directional vectors to the next junc
		VectorSubtract(jNext->pos, j->pos, fwd);
		GetPerpendicularViewVector(cg.refdef.vieworg, j->pos, jNext->pos, up);

		// if it's a crossover, draw it twice
		if(j->flags & TJFL_CROSSOVER)
		{
			if(iteration > 0)
			{
				ProjectPointOntoVector(cg.refdef.vieworg, j->pos, jNext->pos, viewProj);
				VectorSubtract(cg.refdef.vieworg, viewProj, v);
				VectorNormalize(v);

				if(iteration == 1)
				{
					VectorMA(up, 0.3, v, up);
				}
				else
				{
					VectorMA(up, -0.3, v, up);
				}

				VectorNormalize(up);
			}
		}
		// do fading when moving towards the projection point onto the trail segment vector
		else if(!(j->flags & TJFL_NOCULL) && (j->widthEnd > 4 || jNext->widthEnd > 4))
		{
			ProjectPointOntoVector(cg.refdef.vieworg, j->pos, jNext->pos, viewProj);
			viewDist = Distance(viewProj, cg.refdef.vieworg);

			if(viewDist < (TRAIL_FADE_CLOSE_DIST * TRAIL_FADE_FAR_SCALE))
			{
				if(viewDist < TRAIL_FADE_CLOSE_DIST)
				{
					fadeAlpha = 0.0;
				}
				else
				{
					fadeAlpha = (viewDist - TRAIL_FADE_CLOSE_DIST) / (TRAIL_FADE_CLOSE_DIST * TRAIL_FADE_FAR_SCALE);
				}

				if(fadeAlpha < j->alpha)
				{
					j->alpha = fadeAlpha;
				}

				if(fadeAlpha < jNext->alpha)
				{
					jNext->alpha = fadeAlpha;
				}
			}
		}

		// now output the QUAD for this segment

		// 1 ----
		VectorMA(j->pos, 0.5 * j->width, up, p);
		VectorCopy(p, verts[i].xyz);
		verts[i].st[0] = s;
		verts[i].st[1] = 1.0;

		for(k = 0; k < 3; k++)
			verts[i].modulate[k] = (unsigned char)(j->color[k] * 255.0);

		verts[i].modulate[3] = (unsigned char)(j->alpha * 255.0);

		// blend this with the previous junc
		if(j != trail)
		{
			VectorAdd(verts[i].xyz, verts[i - 1].xyz, verts[i].xyz);
			VectorScale(verts[i].xyz, 0.5, verts[i].xyz);
			VectorCopy(verts[i].xyz, verts[i - 1].xyz);
		}
		else if(j->flags & TJFL_FADEIN)
		{
			verts[i].modulate[3] = 0;   // fade in
		}

		i++;

		// 2 ----
		VectorMA(p, -1 * j->width, up, p);
		VectorCopy(p, verts[i].xyz);
		verts[i].st[0] = s;
		verts[i].st[1] = 0.0;

		for(k = 0; k < 3; k++)
			verts[i].modulate[k] = (unsigned char)(j->color[k] * 255.0);

		verts[i].modulate[3] = (unsigned char)(j->alpha * 255.0);

		// blend this with the previous junc
		if(j != trail)
		{
			VectorAdd(verts[i].xyz, verts[i - 3].xyz, verts[i].xyz);
			VectorScale(verts[i].xyz, 0.5, verts[i].xyz);
			VectorCopy(verts[i].xyz, verts[i - 3].xyz);
		}
		else if(j->flags & TJFL_FADEIN)
		{
			verts[i].modulate[3] = 0;   // fade in
		}

		i++;

		if(trail->sType == STYPE_REPEAT)
		{
			s = jNext->sTex;
		}
		else
		{
			//s += sInc;
			s += VectorDistance(j->pos, jNext->pos) / sInc;

			if(s > 1.0)
			{
				s = 1.0;
			}
		}

		// 3 ----
		VectorMA(jNext->pos, -0.5 * jNext->width, up, p);
		VectorCopy(p, verts[i].xyz);
		verts[i].st[0] = s;
		verts[i].st[1] = 0.0;

		for(k = 0; k < 3; k++)
			verts[i].modulate[k] = (unsigned char)(jNext->color[k] * 255.0);

		verts[i].modulate[3] = (unsigned char)(jNext->alpha * 255.0);
		i++;

		// 4 ----
		VectorMA(p, jNext->width, up, p);
		VectorCopy(p, verts[i].xyz);
		verts[i].st[0] = s;
		verts[i].st[1] = 1.0;

		for(k = 0; k < 3; k++)
			verts[i].modulate[k] = (unsigned char)(jNext->color[k] * 255.0);

		verts[i].modulate[3] = (unsigned char)(jNext->alpha * 255.0);
		i++;

		if(i + 4 > MAX_TRAIL_VERTS)
		{
			break;
		}

		j = jNext;
		jNext = j->nextJunc;
	}

	if(trail->flags & TJFL_FIXDISTORT)
	{
		// build the list of outVerts, by dividing up the QUAD's into 4 Tri's each, so as to allow
		//  any shaped (convex) Quad without bilinear distortion
		for(k = 0, numOutVerts = 0; k < i; k += 4)
		{
			VectorCopy(verts[k].xyz, mid.xyz);
			mid.st[0] = verts[k].st[0];
			mid.st[1] = verts[k].st[1];

			for(l = 0; l < 4; l++)
			{
				mod[l] = (float)verts[k].modulate[l];
			}

			for(n = 1; n < 4; n++)
			{
				VectorAdd(verts[k + n].xyz, mid.xyz, mid.xyz);
				mid.st[0] += verts[k + n].st[0];
				mid.st[1] += verts[k + n].st[1];

				for(l = 0; l < 4; l++)
				{
					mod[l] += (float)verts[k + n].modulate[l];
				}
			}

			VectorScale(mid.xyz, 0.25, mid.xyz);
			mid.st[0] *= 0.25;
			mid.st[1] *= 0.25;

			for(l = 0; l < 4; l++)
			{
				mid.modulate[l] = (unsigned char)(mod[l] / 4.0);
			}

			// now output the tri's
			for(n = 0; n < 4; n++)
			{
				outVerts[numOutVerts++] = verts[k + n];
				outVerts[numOutVerts++] = mid;

				if(n < 3)
				{
					outVerts[numOutVerts++] = verts[k + n + 1];
				}
				else
				{
					outVerts[numOutVerts++] = verts[k];
				}
			}

		}

		if(!(trail->flags & TJFL_NOPOLYMERGE))
		{
			trap_R_AddPolysToScene(trail->shader, 3, &outVerts[0], numOutVerts / 3);
		}
		else
		{
			int k;

			for(k = 0; k < numOutVerts / 3; k++)
			{
				trap_R_AddPolyToScene(trail->shader, 3, &outVerts[k * 3]);
			}
		}
	}
	else
	{
		// send the polygons
		// FIXME: is it possible to send a GL_STRIP here? We are actually sending 2x the verts we really need to
		if(!(trail->flags & TJFL_NOPOLYMERGE))
		{
			trap_R_AddPolysToScene(trail->shader, 4, &verts[0], i / 4);
		}
		else
		{
			int k;

			for(k = 0; k < i / 4; k++)
			{
				trap_R_AddPolyToScene(trail->shader, 4, &verts[k * 4]);
			}
		}
	}

	// do we need to make another pass?
	if(trail->flags & TJFL_CROSSOVER)
	{
		if(iteration < 2)
		{
			CG_AddTrailToScene(trail, iteration + 1, numJuncs);
		}
	}

}
コード例 #3
0
/*
===============
CG_RenderBeam

Renders a beam
===============
*/
static void CG_RenderBeam( trailBeam_t *tb )
{
	trailBeamNode_t   *i = nullptr;
	trailBeamNode_t   *prev = nullptr;
	trailBeamNode_t   *next = nullptr;
	vec3_t            up;
	polyVert_t        verts[( MAX_TRAIL_BEAM_NODES - 1 ) * 4 ];
	int               numVerts = 0;
	baseTrailBeam_t   *btb;
	trailSystem_t     *ts;
	baseTrailSystem_t *bts;

	if ( !tb || !tb->nodes )
	{
		return;
	}

	btb = tb->class_;
	ts = tb->parent;
	bts = ts->class_;

	if ( bts->thirdPersonOnly &&
	     ( CG_AttachmentCentNum( &ts->frontAttachment ) == cg.snap->ps.clientNum ||
	       CG_AttachmentCentNum( &ts->backAttachment ) == cg.snap->ps.clientNum ) &&
	     !cg.renderingThirdPerson )
	{
		return;
	}

	CG_CalculateBeamNodeProperties( tb );

	i = tb->nodes;

	do
	{
		prev = i->prev;
		next = i->next;

		if ( prev && next )
		{
			//this node has two neighbours
			GetPerpendicularViewVector( cg.refdef.vieworg, next->position, prev->position, up );
		}
		else if ( !prev && next )
		{
			//this is the front
			GetPerpendicularViewVector( cg.refdef.vieworg, next->position, i->position, up );
		}
		else if ( prev && !next )
		{
			//this is the back
			GetPerpendicularViewVector( cg.refdef.vieworg, i->position, prev->position, up );
		}
		else
		{
			break;
		}

		if ( prev )
		{
			VectorMA( i->position, i->halfWidth, up, verts[ numVerts ].xyz );
			verts[ numVerts ].st[ 0 ] = i->textureCoord;
			verts[ numVerts ].st[ 1 ] = 1.0f;

			if ( btb->realLight )
			{
				CG_LightVertex( verts[ numVerts ].xyz, i->alpha, verts[ numVerts ].modulate );
			}
			else
			{
				VectorCopy( i->color, verts[ numVerts ].modulate );
				verts[ numVerts ].modulate[ 3 ] = i->alpha;
			}

			numVerts++;

			VectorMA( i->position, -i->halfWidth, up, verts[ numVerts ].xyz );
			verts[ numVerts ].st[ 0 ] = i->textureCoord;
			verts[ numVerts ].st[ 1 ] = 0.0f;

			if ( btb->realLight )
			{
				CG_LightVertex( verts[ numVerts ].xyz, i->alpha, verts[ numVerts ].modulate );
			}
			else
			{
				VectorCopy( i->color, verts[ numVerts ].modulate );
				verts[ numVerts ].modulate[ 3 ] = i->alpha;
			}

			numVerts++;
		}

		if ( next )
		{
			VectorMA( i->position, -i->halfWidth, up, verts[ numVerts ].xyz );
			verts[ numVerts ].st[ 0 ] = i->textureCoord;
			verts[ numVerts ].st[ 1 ] = 0.0f;

			if ( btb->realLight )
			{
				CG_LightVertex( verts[ numVerts ].xyz, i->alpha, verts[ numVerts ].modulate );
			}
			else
			{
				VectorCopy( i->color, verts[ numVerts ].modulate );
				verts[ numVerts ].modulate[ 3 ] = i->alpha;
			}

			numVerts++;

			VectorMA( i->position, i->halfWidth, up, verts[ numVerts ].xyz );
			verts[ numVerts ].st[ 0 ] = i->textureCoord;
			verts[ numVerts ].st[ 1 ] = 1.0f;

			if ( btb->realLight )
			{
				CG_LightVertex( verts[ numVerts ].xyz, i->alpha, verts[ numVerts ].modulate );
			}
			else
			{
				VectorCopy( i->color, verts[ numVerts ].modulate );
				verts[ numVerts ].modulate[ 3 ] = i->alpha;
			}

			numVerts++;
		}

		if( btb->dynamicLight ) {
			trap_R_AddLightToScene( i->position,
						btb->dLightRadius,
						3,
						( float ) btb->dLightColor[ 0 ] / ( float ) 0xFF,
						( float ) btb->dLightColor[ 1 ] / ( float ) 0xFF,
						( float ) btb->dLightColor[ 2 ] / ( float ) 0xFF, 0, 0 );
		}

		i = i->next;
	}
	while ( i );

	trap_R_AddPolysToScene( tb->class_->shader, 4, &verts[ 0 ], numVerts / 4 );
}