/* ================= 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 *paliashdr; float an; vec3_t bbox[8]; image_t *skin; if ( !( e->flags & RF_WEAPONMODEL ) ) { if ( R_CullAliasModel( bbox, e ) ) return; } if ( e->flags & RF_WEAPONMODEL ) { if ( r_lefthand->value == 2 ) return; } paliashdr = (dmdl_t *)currentmodel->extradata; // // get lighting information // // PMM - rewrote, reordered to handle new shells & mixing // if ( currententity->flags & ( RF_SHELL_HALF_DAM | RF_SHELL_GREEN | RF_SHELL_RED | RF_SHELL_BLUE | RF_SHELL_DOUBLE ) ) { // PMM -special case for godmode if ( (currententity->flags & RF_SHELL_RED) && (currententity->flags & RF_SHELL_BLUE) && (currententity->flags & RF_SHELL_GREEN) ) { for (i=0 ; i<3 ; i++) shadelight[i] = 1.0; } else if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_BLUE | RF_SHELL_DOUBLE ) ) { VectorClear (shadelight); if ( currententity->flags & RF_SHELL_RED ) { shadelight[0] = 1.0; if (currententity->flags & (RF_SHELL_BLUE|RF_SHELL_DOUBLE) ) shadelight[2] = 1.0; } else if ( currententity->flags & RF_SHELL_BLUE ) { if ( currententity->flags & RF_SHELL_DOUBLE ) { shadelight[1] = 1.0; shadelight[2] = 1.0; } else { shadelight[2] = 1.0; } } else if ( currententity->flags & RF_SHELL_DOUBLE ) { shadelight[0] = 0.9; shadelight[1] = 0.7; } } else if ( currententity->flags & ( RF_SHELL_HALF_DAM | RF_SHELL_GREEN ) ) { VectorClear (shadelight); // PMM - new colors if ( currententity->flags & RF_SHELL_HALF_DAM ) { shadelight[0] = 0.56; shadelight[1] = 0.59; shadelight[2] = 0.45; } if ( currententity->flags & RF_SHELL_GREEN ) { shadelight[1] = 1.0; } } } //PMM - ok, now flatten these down to range from 0 to 1.0. // max_shell_val = max(shadelight[0], max(shadelight[1], shadelight[2])); // if (max_shell_val > 0) // { // for (i=0; i<3; i++) // { // shadelight[i] = shadelight[i] / max_shell_val; // } // } // pmm else if ( currententity->flags & RF_FULLBRIGHT ) { for (i=0 ; i<3 ; i++) shadelight[i] = 1.0; } else { R_LightPoint (currententity->origin, shadelight); // player lighting hack for communication back to server // big hack! if ( currententity->flags & RF_WEAPONMODEL ) { // pick the greatest component, which should be the same // as the mono value returned by software if (shadelight[0] > shadelight[1]) { if (shadelight[0] > shadelight[2]) r_lightlevel->value = 150*shadelight[0]; else r_lightlevel->value = 150*shadelight[2]; } else { if (shadelight[1] > shadelight[2]) r_lightlevel->value = 150*shadelight[1]; else r_lightlevel->value = 150*shadelight[2]; } } if ( gl_monolightmap->string[0] != '0' ) { float s = shadelight[0]; if ( s < shadelight[1] ) s = shadelight[1]; if ( s < shadelight[2] ) s = shadelight[2]; shadelight[0] = s; shadelight[1] = s; shadelight[2] = s; } } if ( currententity->flags & RF_MINLIGHT ) { for (i=0 ; i<3 ; i++) if (shadelight[i] > 0.1) break; if (i == 3) { shadelight[0] = 0.1; shadelight[1] = 0.1; shadelight[2] = 0.1; } } if ( currententity->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 = shadelight[i] * 0.8; shadelight[i] += scale; if (shadelight[i] < min) shadelight[i] = min; } } // ================= // PGM ir goggles color override if ( r_newrefdef.rdflags & RDF_IRGOGGLES && currententity->flags & RF_IR_VISIBLE) { shadelight[0] = 1.0; shadelight[1] = 0.0; shadelight[2] = 0.0; } // PGM // ================= shadedots = r_avertexnormal_dots[((int)(currententity->angles[1] * (SHADEDOT_QUANT / 360.0))) & (SHADEDOT_QUANT - 1)]; an = currententity->angles[1]/180*M_PI; shadevector[0] = cos(-an); shadevector[1] = sin(-an); shadevector[2] = 1; VectorNormalize (shadevector); // // locate the proper data // c_alias_polys += paliashdr->num_tris; // // draw all the triangles // if (currententity->flags & RF_DEPTHHACK) // hack the depth range to prevent view model from poking into walls qglDepthRange (gldepthmin, gldepthmin + 0.3*(gldepthmax-gldepthmin)); if ( ( currententity->flags & RF_WEAPONMODEL ) && ( r_lefthand->value == 1.0F ) ) { extern void MYgluPerspective( GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar ); qglMatrixMode( GL_PROJECTION ); qglPushMatrix(); qglLoadIdentity(); qglScalef( -1, 1, 1 ); MYgluPerspective( r_newrefdef.fov_y, ( float ) r_newrefdef.width / r_newrefdef.height, 4, 4096); qglMatrixMode( GL_MODELVIEW ); qglCullFace( GL_BACK ); } qglPushMatrix (); e->angles[PITCH] = -e->angles[PITCH]; // sigh. R_RotateForEntity (e); e->angles[PITCH] = -e->angles[PITCH]; // sigh. // select skin if (currententity->skin) skin = currententity->skin; // custom player skin else { if (currententity->skinnum >= MAX_MD2SKINS) skin = currentmodel->skins[0]; else { skin = currentmodel->skins[currententity->skinnum]; if (!skin) skin = currentmodel->skins[0]; } } if (!skin) skin = r_notexture; // fallback... GL_Bind(skin->texnum); // draw it qglShadeModel (GL_SMOOTH); GL_TexEnv( GL_MODULATE ); if ( currententity->flags & RF_TRANSLUCENT ) { qglEnable (GL_BLEND); } if ( (currententity->frame >= paliashdr->num_frames) || (currententity->frame < 0) ) { ri.Con_Printf (PRINT_ALL, "R_DrawAliasModel %s: no such frame %d\n", currentmodel->name, currententity->frame); currententity->frame = 0; currententity->oldframe = 0; } if ( (currententity->oldframe >= paliashdr->num_frames) || (currententity->oldframe < 0)) { ri.Con_Printf (PRINT_ALL, "R_DrawAliasModel %s: no such oldframe %d\n", currentmodel->name, currententity->oldframe); currententity->frame = 0; currententity->oldframe = 0; } if ( !r_lerpmodels->value ) currententity->backlerp = 0; GL_DrawAliasFrameLerp (paliashdr, currententity->backlerp); GL_TexEnv( GL_REPLACE ); qglShadeModel (GL_FLAT); qglPopMatrix (); #if 0 qglDisable( GL_CULL_FACE ); qglPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); qglDisable( GL_TEXTURE_2D ); qglBegin( GL_TRIANGLE_STRIP ); for ( i = 0; i < 8; i++ ) { qglVertex3fv( bbox[i] ); } qglEnd(); qglEnable( GL_TEXTURE_2D ); qglPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); qglEnable( GL_CULL_FACE ); #endif if ( ( currententity->flags & RF_WEAPONMODEL ) && ( r_lefthand->value == 1.0F ) ) { qglMatrixMode( GL_PROJECTION ); qglPopMatrix(); qglMatrixMode( GL_MODELVIEW ); qglCullFace( GL_FRONT ); } if ( currententity->flags & RF_TRANSLUCENT ) { qglDisable (GL_BLEND); } if (currententity->flags & RF_DEPTHHACK) qglDepthRange (gldepthmin, gldepthmax); #if 1 if (gl_shadows->value && !(currententity->flags & (RF_TRANSLUCENT | RF_WEAPONMODEL))) { qglPushMatrix (); R_RotateForEntity (e); qglDisable (GL_TEXTURE_2D); qglEnable (GL_BLEND); qglColor4f (0,0,0,0.5); GL_DrawAliasShadow (paliashdr, currententity->frame ); qglEnable (GL_TEXTURE_2D); qglDisable (GL_BLEND); qglPopMatrix (); } #endif qglColor4f (1,1,1,1); }
/* ================= 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); }