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; } }
/* ============== 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; }
/* =============== 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); } }
//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); } }
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; } }
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; } }
/* =============== 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; } }
/* =============== 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); } }
/* ================= 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); }
/* ================= 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); }