Esempio n. 1
0
void CL_FlyParticles (const vec3_t origin, int count)
{
	int			i;
	cparticle_t	*p;
	float		sp, sy, cp, cy;
	vec3_t		forward;
	float		dist = 64;
	float		ltime;


	if (count > NUMVERTEXNORMALS)
		count = NUMVERTEXNORMALS;

	if (!avelocities[0][0])
	{
		for (i = 0; i < NUMVERTEXNORMALS; i++) {
			avelocities[i][0] = (rand()&255) * 0.01f;
			avelocities[i][1] = (rand()&255) * 0.01f;
			avelocities[i][2] = (rand()&255) * 0.01f;
		}
	}


	ltime = (float)cl.time / 1000.0f;
	for (i=0 ; i<count ; i+=2)
	{
		if (!free_particles)
			return;

		p = free_particles;
		free_particles = p->next;
		p->next = active_particles;
		active_particles = p;

		Q_sincos(ltime * avelocities[i][0], &sy, &cy);
		Q_sincos(ltime * avelocities[i][1], &sp, &cp);
		//Q_sincos(ltime * avelocities[i][2], &sr, &cr);
	
		forward[0] = cp*cy;
		forward[1] = cp*sy;
		forward[2] = -sp;

		p->time = cl.time;

		dist = (float)sin(ltime + i)*64.0f;
		p->org[0] = origin[0] + bytedirs[i][0]*dist + forward[0]*BEAMLENGTH;
		p->org[1] = origin[1] + bytedirs[i][1]*dist + forward[1]*BEAMLENGTH;
		p->org[2] = origin[2] + bytedirs[i][2]*dist + forward[2]*BEAMLENGTH;

		VectorClear (p->vel);
		VectorClear (p->accel);

		p->color = 0;
		//p->colorvel = 0;

		p->alpha = 1.0f;
		p->alphavel = -100;
	}
}
Esempio n. 2
0
/*
==============
R_DrawSkyBox
==============
*/
static void R_RotateMatrix (float dstM[16], const float srcM[16], vec_t angle, vec_t x, vec_t y, vec_t z )
{
	vec_t	c, s, mc, t1, t2, t3, t4, t5;

	dstM[3] = dstM[7] = dstM[11] = dstM[12] = dstM[13] = dstM[14] = 0.0f;
	dstM[15] = 1.0f;

	t1 = (float)sqrt(x*x + y*y + z*z);
	if (t1 == 0.0f) {
		dstM[0] = srcM[0], dstM[1] = srcM[1], dstM[2]  = srcM[2];
		dstM[4] = srcM[4], dstM[5] = srcM[5], dstM[6]  = srcM[6];
		dstM[8] = srcM[8], dstM[9] = srcM[9], dstM[10] = srcM[10];
		return;
	}

	t1 = 1.0f / t1;
	x *= t1;
	y *= t1;
	z *= t1;

	Q_sincos(DEG2RAD(angle), &s, &c);
	mc = 1.0f - c;

	t1 = y * x * mc;
	t2 = z * s;
	t3 = t1 + t2;
	t4 = t1 - t2;
	
	t1 = x * z * mc;
	t2 = y * s;
	t5 = t1 + t2;
	t2 = t1 - t2;
	t1 = (x * x * mc) + c;
	dstM[0]  = srcM[0] * t1 + srcM[4] * t3 + srcM[8 ] * t2;
	dstM[1]  = srcM[1] * t1 + srcM[5] * t3 + srcM[9 ] * t2;
	dstM[2]  = srcM[2] * t1 + srcM[6] * t3 + srcM[10] * t2;

	t1 = y * z * mc;
	t2 = x * s;
	t3 = t1 + t2;
	t2 = t1 - t2;
	t1 = (y * y * mc) + c;
	dstM[4]  = srcM[0] * t4 + srcM[4] * t1 + srcM[8 ] * t3;
	dstM[5]  = srcM[1] * t4 + srcM[5] * t1 + srcM[9 ] * t3;
	dstM[6]  = srcM[2] * t4 + srcM[6] * t1 + srcM[10] * t3;

	t1 = (z * z * mc) + c;
	dstM[8]  = srcM[0] * t5 + srcM[4] * t2 + srcM[8 ] * t1;
	dstM[9]  = srcM[1] * t5 + srcM[5] * t2 + srcM[9 ] * t1;
	dstM[10] = srcM[2] * t5 + srcM[6] * t2 + srcM[10] * t1;
}
Esempio n. 3
0
/*
===============
CL_BigTeleportParticles
===============
*/
void CL_BigTeleportParticles (const vec3_t org)
{
	int			i;
	cparticle_t	*p;
	float		dist, s, c;
	static int colortable[4] = {2*8,13*8,21*8,18*8};

	for (i=0 ; i<4096 ; i++)
	{
		if (!free_particles)
			return;
		p = free_particles;
		free_particles = p->next;
		p->next = active_particles;
		active_particles = p;

		p->time = cl.time;

		p->color = colortable[rand()&3];

		Q_sincos(M_TWOPI*(rand()&1023)/1023.0f, &s, &c);

		dist = rand()&31;
		p->org[0] = org[0] + c*dist;
		p->vel[0] = c*(70+(rand()&63));
		p->accel[0] = -c*100;

		p->org[1] = org[1] + s*dist;
		p->vel[1] = s*(70+(rand()&63));
		p->accel[1] = -s*100;

		p->org[2] = org[2] + 8 + (rand()%90);
		p->vel[2] = -100.0f + (rand()&31);
		p->accel[2] = PARTICLE_GRAVITY*4;
		p->alpha = 1.0f;

		p->alphavel = -0.3f / (0.5f + frand()*0.3f);
	}
}
Esempio n. 4
0
//void CL_Heatbeam (vec3_t start, vec3_t end)
void CL_Heatbeam (const vec3_t start, const vec3_t forward)
{
	vec3_t		move, vec, right, up;
	cparticle_t	*p;
	float		i, c, s, len;
	vec3_t		dir;
	float		ltime;
	float		step = 32.0f, rstep;
	float		start_pt, rot, variance = 0.5f;
	vec3_t		end;

	VectorMA (start, 4096, forward, end);

	VectorCopy (start, move);
	VectorSubtract (end, start, vec);
	len = VectorNormalize (vec);

	// FIXME - pmm - these might end up using old values?
	VectorCopy (cl.v_right, right);
	VectorCopy (cl.v_up, up);
#ifdef GL_QUAKE
	// GL mode
	VectorMA (move, -0.5f, right, move);
	VectorMA (move, -0.5f, up, move);
#endif
	// otherwise assume SOFT

	ltime = (float)cl.time/1000.0f;
	start_pt = (float)fmod(ltime*96.0f,step);
	VectorMA (move, start_pt, vec, move);

	VectorScale (vec, step, vec);

	rstep = M_PI/10.0f;
	for (i=start_pt ; i<len ; i+=step)
	{
		if (i>step*5) // don't bother after the 5th ring
			break;

		for (rot = 0; rot < M_TWOPI; rot += rstep)
		{
			if (!free_particles)
				return;

			p = free_particles;
			free_particles = p->next;
			p->next = active_particles;
			active_particles = p;
			
			p->time = cl.time;
			VectorClear (p->accel);

			Q_sincos(rot, &s, &c);
			
			// trim it so it looks like it's starting at the origin
			if (i < 10) {
				c *= variance * (i/10.0f);
				s *= variance * (i/10.0f);
			} else {
				c *= variance;
				s *= variance;
			}
		
			VectorScale (right, c, dir);
			VectorMA (dir, s, up, dir);

			p->alpha = 0.5f;
			p->alphavel = -1000.0;
			p->color = 223 - (rand()&7);
			
			p->org[0] = move[0] + dir[0]*3;
			p->org[1] = move[1] + dir[1]*3;
			p->org[2] = move[2] + dir[2]*3;
			VectorClear(p->vel);
		}
		VectorAdd (move, vec, move);
	}
}
Esempio n. 5
0
void CL_BfgParticles (entity_t *ent)
{
	int			i;
	cparticle_t	*p;
	float		angle;
	float		sr, sp, sy, cr, cp, cy;
	vec3_t		forward;
	float		dist = 64;
	vec3_t		v;
	float		ltime;

	if (!avelocities[0][0])
	{
		for (i = 0; i < NUMVERTEXNORMALS * 3; i++)
			avelocities[0][i] = (rand () & 255) * 0.01;
	}

	ltime = (float) cl.time / 1000.0;

	for (i = 0; i < NUMVERTEXNORMALS; i++)
	{
		angle = ltime * avelocities[i][0];
		Q_sincos (angle, &sy, &cy);

		angle = ltime * avelocities[i][1];
		Q_sincos (angle, &sp, &cp);

		angle = ltime * avelocities[i][2];
		Q_sincos (angle, &sr, &cr);

		forward[0] = cp * cy;
		forward[1] = cp * sy;
		forward[2] = -sp;

		if (!free_particles)
			return;

		p = free_particles;
		free_particles = p->next;
		p->next = active_particles;
		active_particles = p;

		p->time = cl.time;

		dist = sin (ltime + i) * 64;
		p->org[0] = ent->currorigin[0] + r_avertexnormals[i][0] * dist + forward[0] * BEAMLENGTH;
		p->org[1] = ent->currorigin[1] + r_avertexnormals[i][1] * dist + forward[1] * BEAMLENGTH;
		p->org[2] = ent->currorigin[2] + r_avertexnormals[i][2] * dist + forward[2] * BEAMLENGTH;

		VectorClear (p->vel);
		VectorClear (p->accel);

		VectorSubtract (p->org, ent->currorigin, v);
		dist = VectorLength (v) / 90.0;
		p->color = floor (0xd0 + dist * 7);
		p->colorvel = 0;

		p->alpha = 1.0 - dist;
		p->alphavel = -100;

		p->bounceFactor = 0.3f;

		p->ignoreGrav = false;
	}
}
Esempio n. 6
0
void CL_FlyParticles (vec3_t origin, int count)
{
	int			i;
	cparticle_t	*p;
	float		angle;
	float		sr, sp, sy, cr, cp, cy;
	vec3_t		forward;
	float		dist = 64;
	float		ltime;

	if (count > NUMVERTEXNORMALS)
		count = NUMVERTEXNORMALS;

	if (!avelocities[0][0])
	{
		for (i = 0; i < NUMVERTEXNORMALS * 3; i++)
			avelocities[0][i] = (rand () & 255) * 0.01;
	}

	ltime = (float) cl.time / 1000.0;

	for (i = 0; i < count; i += 2)
	{
		angle = ltime * avelocities[i][0];
		Q_sincos (angle, &sy, &cy);

		angle = ltime * avelocities[i][1];
		Q_sincos (angle, &sp, &cp);

		angle = ltime * avelocities[i][2];
		Q_sincos (angle, &sr, &cr);

		forward[0] = cp * cy;
		forward[1] = cp * sy;
		forward[2] = -sp;

		if (!free_particles)
			return;

		p = free_particles;
		free_particles = p->next;
		p->next = active_particles;
		active_particles = p;

		p->time = cl.time;

		dist = sin (ltime + i) * 64;
		p->org[0] = origin[0] + r_avertexnormals[i][0] * dist + forward[0] * BEAMLENGTH;
		p->org[1] = origin[1] + r_avertexnormals[i][1] * dist + forward[1] * BEAMLENGTH;
		p->org[2] = origin[2] + r_avertexnormals[i][2] * dist + forward[2] * BEAMLENGTH;

		VectorClear (p->vel);
		VectorClear (p->accel);

		p->color = 0;
		p->colorvel = 0;

		p->alpha = 1;
		p->alphavel = -100;

		p->bounceFactor = 0.0f;

		p->ignoreGrav = true;
	}
}
Esempio n. 7
0
/*
===============
CL_RailTrail
===============
*/
void CL_RailTrail (vec3_t start, vec3_t end)
{
	vec3_t		move;
	vec3_t		vec;
	float		len;
	int			j;
	cparticle_t	*p;
	float		dec;
	vec3_t		right, up;
	int			i;
	float		d, c, s;
	vec3_t		dir;
	byte		clr = 0x74;

	VectorCopy (start, move);
	VectorSubtract (end, start, vec);
	len = VectorNormalize (vec);

	MakeNormalVectors (vec, right, up);

	for (i = 0; i < len; i++)
	{
		if (!free_particles)
			return;

		p = free_particles;
		free_particles = p->next;
		p->next = active_particles;
		active_particles = p;

		p->time = cl.time;
		VectorClear (p->accel);

		d = i * 0.1;

		Q_sincos (d, &s, &c);

		VectorScale (right, c, dir);
		VectorMA (dir, s, up, dir);

		p->alpha = 1.0;
		p->alphavel = -1.0 / (1 + frand () * 0.2);
		p->color = clr + (rand () & 7);

		for (j = 0; j < 3; j++)
		{
			p->org[j] = move[j] + dir[j] * 3;
			p->vel[j] = dir[j] * 6;
		}

		VectorAdd (move, vec, move);

		p->bounceFactor = 0.1f;
		p->ignoreGrav = true;
	}

	dec = 0.75;
	VectorScale (vec, dec, vec);
	VectorCopy (start, move);

	while (len > 0)
	{
		len -= dec;

		if (!free_particles)
			return;

		p = free_particles;
		free_particles = p->next;
		p->next = active_particles;
		active_particles = p;

		p->time = cl.time;
		VectorClear (p->accel);

		p->alpha = 1.0;
		p->alphavel = -1.0 / (0.6 + frand () * 0.2);
		p->color = 0x0 + rand () & 15;

		for (j = 0; j < 3; j++)
		{
			p->org[j] = move[j] + crand () * 3;
			p->vel[j] = crand () * 3;
			p->accel[j] = 0;
		}

		VectorAdd (move, vec, move);

		p->bounceFactor = 0.1f;
		p->ignoreGrav = true;
	}
}
Esempio n. 8
0
/*
===============
CL_RailTrail

===============
*/
void CL_RailTrail (const vec3_t start, const vec3_t end)
{
	vec3_t		move, vec, right, up, dir;
	float		len, dec, c, s;
	cparticle_t	*p;
	int			i;
	byte		clr = 0x74;
	cdlight_t *dl;

	VectorCopy (start, move);
	VectorSubtract (end, start, vec);
	len = VectorNormalize (vec);

	// add a light at the dest
	dl = CL_AllocDlight(0);
	VectorCopy(end, dl->origin);
	dl->radius = 100;
	dl->die = cl.time + 200;
	VectorSet(dl->color, 0.3, 0.5, 1.0);

	MakeNormalVectors (vec, right, up);

	for (i=0 ; i<len ; i++)
	{

		if(i % 3 == 0){
			VectorAdd(move, vec, move);
			continue;
		}

		if (!free_particles)
			return;

		p = free_particles;
		free_particles = p->next;
		p->next = active_particles;
		active_particles = p;
		
		p->time = cl.time;
		VectorClear (p->accel);

		Q_sincos(i * 0.1f, &s, &c);

		VectorScale (right, c, dir);
		VectorMA (dir, s, up, dir);

		p->alpha = 1.0f;
		p->alphavel = -1.0f / (1.0f+frand()*0.2f);
		p->color = clr + (rand()&7);

		p->org[0] = move[0] + dir[0]*3;
		p->org[1] = move[1] + dir[1]*3;
		p->org[2] = move[2] + dir[2]*3;
		p->vel[0] = dir[0]*6;
		p->vel[1] = dir[1]*6;
		p->vel[2] = dir[2]*6;

		VectorAdd (move, vec, move);
	}

	dec = 2.0f;
	VectorScale (vec, dec, vec);
	VectorCopy (start, move);

	while (len > 0)
	{
		len -= dec;

		if (!free_particles)
			return;
		p = free_particles;
		free_particles = p->next;
		p->next = active_particles;
		active_particles = p;

		p->time = cl.time;
		VectorClear (p->accel);

		p->alpha = 1.0f;
		p->alphavel = -1.0f / (0.6f+frand()*0.2f);
		p->color = 0x0 + (rand()&15);

		p->org[0] = move[0] + crand()*3;
		p->org[1] = move[1] + crand()*3;
		p->org[2] = move[2] + crand()*3;
		p->vel[0] = crand()*3;
		p->vel[1] = crand()*3;
		p->vel[2] = crand()*3;

		VectorAdd (move, vec, move);
	}
}
Esempio n. 9
0
/*
=================
R_DrawAliasModelShadow
=================
*/
void R_DrawAliasModelShadow(entity_t *e)
{
	int			i;
	dmdl_t		*hdr;
	float		an;
	vec3_t		bbox[8];
	image_t		*skin;
	float		lightspot[3];
	glmatrix	shadowmatrix;
	float		lheight;

	if (gl_shadows->value && (e->flags & (RF_TRANSLUCENT | RF_WEAPONMODEL | RF_NOSHADOW)))
		return;

	if (!(e->flags & RF_WEAPONMODEL))
	{
		if (R_CullAliasModel(bbox, e))
			return;
	}

	if (e->flags & RF_WEAPONMODEL)
	{
		if (r_lefthand->value == 2)
			return;
	}

	hdr = (dmdl_t *)e->model->extradata;

	if (e->flags & (RF_SHELL_GREEN | RF_SHELL_RED | RF_SHELL_BLUE))
	{
		VectorClear(gl_meshuboupdate.shadelight);

		if (e->flags & RF_SHELL_RED) gl_meshuboupdate.shadelight[0] = 1.0;
		if (e->flags & RF_SHELL_GREEN) gl_meshuboupdate.shadelight[1] = 1.0;
		if (e->flags & RF_SHELL_BLUE) gl_meshuboupdate.shadelight[2] = 1.0;
	}
	else if (e->flags & RF_FULLBRIGHT)
	{
		gl_meshuboupdate.shadelight[0] = 1.0;
		gl_meshuboupdate.shadelight[1] = 1.0;
		gl_meshuboupdate.shadelight[2] = 1.0;
	}
	else
	{
		R_LightPoint(e->currorigin, gl_meshuboupdate.shadelight, lightspot);

		// player lighting hack for communication back to server
		// big hack!
		if (e->flags & RF_WEAPONMODEL)
		{
			// pick the greatest component, which should be the same
			// as the mono value returned by software
			if (gl_meshuboupdate.shadelight[0] > gl_meshuboupdate.shadelight[1])
			{
				if (gl_meshuboupdate.shadelight[0] > gl_meshuboupdate.shadelight[2])
					r_lightlevel->value = 150 * gl_meshuboupdate.shadelight[0];
				else r_lightlevel->value = 150 * gl_meshuboupdate.shadelight[2];
			}
			else
			{
				if (gl_meshuboupdate.shadelight[1] > gl_meshuboupdate.shadelight[2])
					r_lightlevel->value = 150 * gl_meshuboupdate.shadelight[1];
				else r_lightlevel->value = 150 * gl_meshuboupdate.shadelight[2];
			}
		}
	}

	if (e->flags & RF_MINLIGHT)
	{
		for (i = 0; i < 3; i++)
			if (gl_meshuboupdate.shadelight[i] > 0.1)
				break;

		if (i == 3)
		{
			gl_meshuboupdate.shadelight[0] = 0.1;
			gl_meshuboupdate.shadelight[1] = 0.1;
			gl_meshuboupdate.shadelight[2] = 0.1;
		}
	}

	if (e->flags & RF_GLOW)
	{
		// bonus items will pulse with time
		float	scale;
		float	min;

		scale = 0.1 * sin(r_newrefdef.time * 7);

		for (i = 0; i < 3; i++)
		{
			min = gl_meshuboupdate.shadelight[i] * 0.8;
			gl_meshuboupdate.shadelight[i] += scale;

			if (gl_meshuboupdate.shadelight[i] < min)
				gl_meshuboupdate.shadelight[i] = min;
		}
	}

	an = e->angles[1] / 180 * M_PI;
	Q_sincos(-an, &gl_meshuboupdate.shadevector[1], &gl_meshuboupdate.shadevector[0]);
	gl_meshuboupdate.shadevector[2] = 1;
	VectorNormalize(gl_meshuboupdate.shadevector);

	// locate the proper data
	c_alias_polys += hdr->num_tris;

	// draw all the triangles
	GL_LoadMatrix(&gl_meshuboupdate.localMatrix, &r_mvpmatrix);

	GL_TranslateMatrix(&gl_meshuboupdate.localMatrix, e->currorigin[0], e->currorigin[1], e->currorigin[2]);
	GL_RotateMatrix(&gl_meshuboupdate.localMatrix, e->angles[1], 0, 0, 1);
	GL_RotateMatrix(&gl_meshuboupdate.localMatrix, e->angles[0], 0, 1, 0);
	GL_RotateMatrix(&gl_meshuboupdate.localMatrix, -e->angles[2], 1, 0, 0);

	// select skin
	if (e->skin)
		skin = e->skin;	// custom player skin
	else
	{
		if (e->skinnum >= MAX_MD2SKINS)
			skin = e->model->skins[0];
		else
		{
			skin = e->model->skins[e->skinnum];

			if (!skin)
				skin = e->model->skins[0];
		}
	}

	if (!skin)
		skin = r_notexture;	// fallback...

	GL_BindTexture(GL_TEXTURE0, GL_TEXTURE_2D, r_modelsampler, skin->texnum);

	if ((e->currframe >= hdr->num_frames) || (e->currframe < 0))
	{
		VID_Printf(PRINT_ALL, S_COLOR_RED "R_DrawAliasModel %s: no such frame %d\n", e->model->name, e->currframe);
		e->currframe = 0;
		e->lastframe = 0;
	}

	if ((e->lastframe >= hdr->num_frames) || (e->lastframe < 0))
	{
		VID_Printf(PRINT_ALL, S_COLOR_RED "R_DrawAliasModel %s: no such oldframe %d\n", e->model->name, e->lastframe);
		e->currframe = 0;
		e->lastframe = 0;
	}

	if (!r_lerpmodels->value)
		e->backlerp = 0;

	lheight = e->currorigin[2] - lightspot[2];
	GL_TranslateMatrix(&gl_meshuboupdate.localMatrix, 0.0f, 0.0f, -lheight);

	shadowmatrix.m[0][0] = 1;
	shadowmatrix.m[0][1] = 0;
	shadowmatrix.m[0][2] = 0;
	shadowmatrix.m[0][3] = 0;

	shadowmatrix.m[1][0] = 0;
	shadowmatrix.m[1][1] = 1;
	shadowmatrix.m[1][2] = 0;
	shadowmatrix.m[1][3] = 0;

	shadowmatrix.m[2][0] = SHADOW_SKEW_X;
	shadowmatrix.m[2][1] = SHADOW_SKEW_Y;
	shadowmatrix.m[2][2] = SHADOW_VSCALE;
	shadowmatrix.m[2][3] = 0;

	shadowmatrix.m[3][0] = 0;
	shadowmatrix.m[3][1] = 0;
	shadowmatrix.m[3][2] = SHADOW_HEIGHT;
	shadowmatrix.m[3][3] = 1;

	GL_MultMatrix(&gl_meshuboupdate.localMatrix, &gl_meshuboupdate.localMatrix, &shadowmatrix);

	GL_TranslateMatrix(&gl_meshuboupdate.localMatrix, 0.0f, 0.0f, lheight);

	// draw shadow
	GL_DrawAliasFrameLerp(e, hdr, e->backlerp);
}
Esempio n. 10
0
/*
=================
R_DrawAliasModel
=================
*/
void R_DrawAliasModel (entity_t *e)
{
	int			i;
	dmdl_t		*hdr;
	float		an;
	vec3_t		bbox[8];
	image_t		*skin;
	float		lightspot[3];

	if (!(e->flags & RF_WEAPONMODEL))
	{
		if (R_CullAliasModel (bbox, e))
			return;
	}

	if (e->flags & RF_WEAPONMODEL)
	{
		if (r_lefthand->value == 2)
			return;
	}

	hdr = (dmdl_t *) e->model->extradata;

	if (e->flags & (RF_SHELL_GREEN | RF_SHELL_RED | RF_SHELL_BLUE))
	{
		VectorClear (gl_meshuboupdate.shadelight);

		if (e->flags & RF_SHELL_RED) gl_meshuboupdate.shadelight[0] = 1.0;
		if (e->flags & RF_SHELL_GREEN) gl_meshuboupdate.shadelight[1] = 1.0;
		if (e->flags & RF_SHELL_BLUE) gl_meshuboupdate.shadelight[2] = 1.0;
	}
	else if (e->flags & RF_FULLBRIGHT)
	{
		gl_meshuboupdate.shadelight[0] = 1.0;
		gl_meshuboupdate.shadelight[1] = 1.0;
		gl_meshuboupdate.shadelight[2] = 1.0;
	}
	else
	{
		dlight_t *l;
		int i;

		// grab static lighting from lightmap
		R_LightPoint (e->currorigin, gl_meshuboupdate.shadelight, lightspot);

		// grab dynamic lighting
		glProgramUniform1i (gl_meshprog, u_meshMaxLights, r_newrefdef.num_dlights);
		glProgramUniform3fv (gl_meshprog, u_meshEntOrig, 1, e->currorigin);
		for (i = 0, l = r_newrefdef.dlights; i < r_newrefdef.num_dlights; i++, l++)
		{
			glProgramUniform3fv (gl_meshprog, u_meshLightPos[i], 1, l->origin);
			glProgramUniform3fv (gl_meshprog, u_meshLightColor[i], 1, l->color);
			glProgramUniform1f (gl_meshprog, u_meshLightAtten[i], l->radius);
		}

		// player lighting hack for communication back to server
		// big hack!
		if (e->flags & RF_WEAPONMODEL)
		{
			// pick the greatest component, which should be the same
			// as the mono value returned by software
			if (gl_meshuboupdate.shadelight[0] > gl_meshuboupdate.shadelight[1])
			{
				if (gl_meshuboupdate.shadelight[0] > gl_meshuboupdate.shadelight[2])
					r_lightlevel->value = 150 * gl_meshuboupdate.shadelight[0];
				else r_lightlevel->value = 150 * gl_meshuboupdate.shadelight[2];
			}
			else
			{
				if (gl_meshuboupdate.shadelight[1] > gl_meshuboupdate.shadelight[2])
					r_lightlevel->value = 150 * gl_meshuboupdate.shadelight[1];
				else r_lightlevel->value = 150 * gl_meshuboupdate.shadelight[2];
			}
		}
	}

	if (e->flags & RF_MINLIGHT)
	{
		for (i = 0; i < 3; i++)
		{
			if (gl_meshuboupdate.shadelight[i] > 0.1)
				break;
		}

		if (i == 3)
		{
			gl_meshuboupdate.shadelight[0] = 0.1;
			gl_meshuboupdate.shadelight[1] = 0.1;
			gl_meshuboupdate.shadelight[2] = 0.1;
		}
	}

	if (e->flags & RF_GLOW)
	{
		// bonus items will pulse with time
		float	scale;
		float	min;

		scale = 0.1 * sin (r_newrefdef.time * 7);

		for (i = 0; i < 3; i++)
		{
			min = gl_meshuboupdate.shadelight[i] * 0.8;
			gl_meshuboupdate.shadelight[i] += scale;

			if (gl_meshuboupdate.shadelight[i] < min)
				gl_meshuboupdate.shadelight[i] = min;
		}
	}

	an = e->angles[1] / 180 * M_PI;
	Q_sincos (-an, &gl_meshuboupdate.shadevector[1], &gl_meshuboupdate.shadevector[0]);
	gl_meshuboupdate.shadevector[2] = 1;
	VectorNormalize (gl_meshuboupdate.shadevector);

	// locate the proper data
	c_alias_polys += hdr->num_tris;

	// draw all the triangles
	if (e->flags & RF_DEPTHHACK) // hack the depth range to prevent view model from poking into walls
		glDepthRange (gldepthmin, gldepthmin + 0.3 * (gldepthmax - gldepthmin));

	if ((e->flags & RF_WEAPONMODEL) && (r_lefthand->value == 1.0F))
	{
		glmatrix gunmatrix;

		GL_LoadIdentity (&gunmatrix);
		GL_ScaleMatrix (&gunmatrix, -1, 1, 1);
		GL_PerspectiveMatrix (&gunmatrix, r_newrefdef.fov_y, (float) r_newrefdef.width / r_newrefdef.height);

		// eval a new mvp for left-handedness
		GL_LoadMatrix (&gl_meshuboupdate.localMatrix, &r_worldmatrix);
		GL_MultMatrix (&gl_meshuboupdate.localMatrix, &gl_meshuboupdate.localMatrix, &gunmatrix);

		glCullFace (GL_BACK);
	}
	else
		GL_LoadMatrix (&gl_meshuboupdate.localMatrix, &r_mvpmatrix);

	GL_TranslateMatrix (&gl_meshuboupdate.localMatrix, e->currorigin[0], e->currorigin[1], e->currorigin[2]);
	GL_RotateMatrix (&gl_meshuboupdate.localMatrix, e->angles[1], 0, 0, 1);
	GL_RotateMatrix (&gl_meshuboupdate.localMatrix, e->angles[0], 0, 1, 0);
	GL_RotateMatrix (&gl_meshuboupdate.localMatrix, -e->angles[2], 1, 0, 0);

	// select skin
	if (e->skin)
		skin = e->skin;	// custom player skin
	else
	{
		if (e->skinnum >= MAX_MD2SKINS)
			skin = e->model->skins[0];
		else
		{
			skin = e->model->skins[e->skinnum];

			if (!skin)
				skin = e->model->skins[0];
		}
	}

	if (!skin)
		skin = r_notexture;	// fallback...

	GL_BindTexture (GL_TEXTURE0, GL_TEXTURE_2D, r_modelsampler, skin->texnum);

	if ((e->currframe >= hdr->num_frames) || (e->currframe < 0))
	{
		VID_Printf (PRINT_ALL, S_COLOR_RED "R_DrawAliasModel %s: no such frame %d\n", e->model->name, e->currframe);
		e->currframe = 0;
		e->lastframe = 0;
	}

	if ((e->lastframe >= hdr->num_frames) || (e->lastframe < 0))
	{
		VID_Printf (PRINT_ALL, S_COLOR_RED "R_DrawAliasModel %s: no such oldframe %d\n", e->model->name, e->lastframe);
		e->currframe = 0;
		e->lastframe = 0;
	}

	if (!r_lerpmodels->value)
		e->backlerp = 0;

	GL_DrawAliasFrameLerp (e, hdr, e->backlerp);

	if ((e->flags & RF_WEAPONMODEL) && (r_lefthand->value == 1.0F))
	{
		glCullFace (GL_FRONT);
	}

	if (e->flags & RF_DEPTHHACK)
		glDepthRange (gldepthmin, gldepthmax);
}