/* ============= RB_DrawMeshTris Re-draws a mesh in outline mode ============= */ void RB_DrawMeshTris (void) { int i, numTMUs = 0; if (!r_showtris->value) return; if (r_showtris->value == 1) GL_Disable(GL_DEPTH_TEST); qglPolygonMode (GL_FRONT_AND_BACK, GL_LINE); for (i=0; i<glConfig.max_texunits; i++) if (glState.activetmu[i]) { numTMUs++; GL_DisableTexture (i); } qglDisableClientState (GL_COLOR_ARRAY); qglColor4f(1.0, 1.0, 1.0, 1.0); RB_DrawArrays (); qglEnableClientState (GL_COLOR_ARRAY); for (i=0; i<numTMUs; i++) GL_EnableTexture(i); qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL); if (r_showtris->value == 1) GL_Enable(GL_DEPTH_TEST); }
/* ============= RB_DrawMeshTris Re-draws a mesh in outline mode ============= */ void RB_DrawMeshTris (GLenum polyMode, int numTMUs) { int i; if (!r_showtris->value) return; if (r_showtris->value == 1) GL_Disable(GL_DEPTH_TEST); qglPolygonMode (GL_FRONT_AND_BACK, GL_LINE); for (i=0; i<numTMUs; i++) GL_DisableTexture (i); qglDisableClientState (GL_COLOR_ARRAY); qglColor4f(1.0, 1.0, 1.0, 1.0); RB_DrawArrays(polyMode); qglEnableClientState (GL_COLOR_ARRAY); for (i=0; i<numTMUs; i++) GL_EnableTexture(i); qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL); if (r_showtris->value == 1) GL_Enable(GL_DEPTH_TEST); }
/* ============== R_ShadowBlend Draws projection shadow(s) from stenciled volume ============== */ void R_ShadowBlend (float shadowalpha) { const vec4_t color[4] = { {0, 0, 0, shadowalpha}, {0, 0, 0, shadowalpha}, {0, 0, 0, shadowalpha}, {0, 0, 0, shadowalpha} }; static const vec3_t verts[4] = { {10, 100, 100}, {10, -100, 100}, {10, -100, -100}, {10, 100, -100} }; static const uint32_t indices[6] = { 0, 1, 2, 0, 2, 3 }; if (r_shadows->value != 3) return; GL_PushMatrix(GL_MODELVIEW); GL_LoadMatrix(GL_MODELVIEW, glState.axisRotation); GL_Disable (GL_ALPHA_TEST); GL_Enable (GL_BLEND); GL_Disable (GL_DEPTH_TEST); GL_DisableTexture(0); GL_StencilFunc(GL_NOTEQUAL, 0, 255); glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP); GL_Enable(GL_STENCIL_TEST); rb_vertex = rb_index = 0; memcpy(indexArray, indices, sizeof(indices)); memcpy(vertexArray, verts, sizeof(vec3_t) * 4); memcpy(colorArray, color, sizeof(vec4_t) * 4); rb_index += 6; rb_vertex += 4; RB_RenderMeshGeneric (false); GL_PopMatrix(GL_MODELVIEW); GL_BlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); GL_Disable (GL_BLEND); GL_EnableTexture(0); GL_Enable (GL_DEPTH_TEST); GL_Disable(GL_STENCIL_TEST); //GL_Enable (GL_ALPHA_TEST); glColor4f(1,1,1,1); }
/* ================= R_SetShellBlend ================= */ void R_SetShellBlend (qboolean toggle) { // shells only if ( !(currententity->flags & RF_MASK_SHELL) ) return; if (toggle) //turn on { // Psychospaz's envmapping if (EnvMapShell()) { glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); GL_Bind(glMedia.spheremappic->texnum); glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); } else if (FlowingShell()) GL_Bind(glMedia.shelltexture->texnum); else GL_DisableTexture(0); GL_ClearStencil(0); glClear(GL_STENCIL_BUFFER_BIT); GL_StencilFunc(GL_EQUAL, 1, 2); glStencilOp(GL_KEEP,GL_KEEP,GL_INCR); GL_Enable(GL_STENCIL_TEST); shellFlowH = 0.25 * sin(r_newrefdef.time * 0.5 * M_PI); shellFlowV = -(r_newrefdef.time / 2.0); } else // turn off { // Psychospaz's envmapping if (EnvMapShell()) { glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); } else if (FlowingShell()) { /*nothing*/ } else GL_EnableTexture(0); GL_Disable(GL_STENCIL_TEST); } }
/* ================= R_DrawAliasModelBBox ================= */ void R_DrawAliasModelBBox (vec3_t bbox[8], entity_t *e) { if (!r_showbbox->value) return; if (e->flags & RF_WEAPONMODEL || e->flags & RF_VIEWERMODEL || e->flags & RF_BEAM || e->renderfx & RF2_CAMERAMODEL) return; GL_Disable (GL_CULL_FACE); glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); GL_DisableTexture (0); // Draw top and sides glBegin(GL_TRIANGLE_STRIP); glVertex3fv( bbox[2] ); glVertex3fv( bbox[1] ); glVertex3fv( bbox[0] ); glVertex3fv( bbox[1] ); glVertex3fv( bbox[4] ); glVertex3fv( bbox[5] ); glVertex3fv( bbox[1] ); glVertex3fv( bbox[7] ); glVertex3fv( bbox[3] ); glVertex3fv( bbox[2] ); glVertex3fv( bbox[7] ); glVertex3fv( bbox[6] ); glVertex3fv( bbox[2] ); glVertex3fv( bbox[4] ); glVertex3fv( bbox[0] ); glEnd(); // Draw bottom glBegin(GL_TRIANGLE_STRIP); glVertex3fv( bbox[4] ); glVertex3fv( bbox[6] ); glVertex3fv( bbox[7] ); glEnd(); GL_EnableTexture (0); glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); GL_Enable (GL_CULL_FACE); }
/* ============= RB_RenderWarpSurface backend for R_DrawWarpSurface ============= */ void RB_RenderWarpSurface (msurface_t *fa) { float args[7] = {0,0.05,0,0,0.04,0,0}; float alpha = colorArray[0][3]; image_t *image = R_TextureAnimation (fa); qboolean light = r_warp_lighting->value && !(fa->texinfo->flags & SURF_NOLIGHTENV); qboolean texShaderWarpNV = glConfig.NV_texshaders && glConfig.multitexture && r_pixel_shader_warp->value; qboolean texShaderWarpARB = glConfig.arb_fragment_program && glConfig.multitexture && r_pixel_shader_warp->value; qboolean texShaderWarp = (texShaderWarpNV || texShaderWarpARB); if (texShaderWarpNV && texShaderWarpARB) texShaderWarpARB = (r_pixel_shader_warp->value == 1.0f); if (rb_vertex == 0 || rb_index == 0) // nothing to render return; c_brush_calls++; // Psychospaz's vertex lighting if (light) { GL_ShadeModel (GL_SMOOTH); if (!texShaderWarp) R_SetVertexRGBScale (true); } /* Texture Shader waterwarp Damn this looks fantastic WHY texture shaders? because I can! - MrG */ if (texShaderWarpARB) { GL_SelectTexture(0); GL_MBind(0, image->texnum); GL_EnableTexture(1); GL_MBind(1, dst_texture_ARB); GL_Enable (GL_FRAGMENT_PROGRAM_ARB); qglBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, fragment_programs[F_PROG_WARP]); qglProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, r_rgbscale->value, r_rgbscale->value, r_rgbscale->value, 1.0); } else if (texShaderWarpNV) { GL_SelectTexture(0); GL_MBind(0, dst_texture_NV); qglTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_2D); GL_EnableTexture(1); GL_MBind(1, image->texnum); qglTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_2D); qglTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_OFFSET_TEXTURE_2D_NV); qglTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB); qglTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV, &args[1]); // Psychospaz's lighting // use this so that the new water isnt so bright anymore // We won't bother check for the extensions availabiliy, as the hardware required // to make it this far definately supports this as well if (light) qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); GL_Enable (GL_TEXTURE_SHADER_NV); } else GL_Bind(image->texnum); RB_DrawArrays (); // MrG - texture shader waterwarp if (texShaderWarpARB) { GL_Disable (GL_FRAGMENT_PROGRAM_ARB); GL_DisableTexture(1); GL_SelectTexture(0); } else if (texShaderWarpNV) { GL_DisableTexture(1); if (light) qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); // Psychospaz's lighting GL_SelectTexture(0); GL_Disable (GL_TEXTURE_SHADER_NV); } // Psychospaz's vertex lighting if (light) { GL_ShadeModel (GL_FLAT); if (!texShaderWarp) R_SetVertexRGBScale (false); } RB_DrawMeshTris (); rb_vertex = rb_index = 0; }
/* ================= R_DrawAliasModelShadow Just draws the shadow for a model ================= */ void R_DrawAliasModelShadow (entity_t *e) { maliasmodel_t *paliashdr; vec3_t bbox[8]; qboolean mirrormodel = false; if (!r_shadows->value) return; if (e->flags & (RF_WEAPONMODEL | RF_NOSHADOW)) return; // no shadows from shells if ( (e->flags & (RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM)) && (e->flags & RF_TRANSLUCENT) ) return; // also skip this for viewermodels and cameramodels if ( !(e->flags & RF_WEAPONMODEL || e->flags & RF_VIEWERMODEL || e->renderfx & RF2_CAMERAMODEL) ) { if (R_CullAliasModel(bbox, e)) return; } aliasShadowAlpha = R_CalcShadowAlpha(e); if (aliasShadowAlpha < DIV255) // out of range return; if (e->renderfx & RF2_CAMERAMODEL) { if (r_lefthand->value==1) mirrormodel = true; } else if (e->flags & RF_MIRRORMODEL) mirrormodel = true; paliashdr = (maliasmodel_t *)currentmodel->extradata; // mirroring support // if (mirrormodel) // R_FlipModel(true); if ( (e->frame >= paliashdr->num_frames) || (e->frame < 0) ) { e->frame = 0; e->oldframe = 0; } if ( (e->oldframe >= paliashdr->num_frames) || (e->oldframe < 0)) { e->frame = 0; e->oldframe = 0; } //if ( !r_lerpmodels->value ) // e->backlerp = 0; qglPushMatrix (); GL_DisableTexture(0); GL_Enable (GL_BLEND); if (r_shadows->value == 3) { e->angles[ROLL] = -e->angles[ROLL]; // roll is backwards R_RotateForEntity (e, true); e->angles[ROLL] = -e->angles[ROLL]; // roll is backwards R_DrawAliasVolumeShadow (paliashdr, bbox); } else { R_RotateForEntity (e, false); R_DrawAliasPlanarShadow (paliashdr); } GL_Disable (GL_BLEND); GL_EnableTexture(0); qglPopMatrix (); // mirroring support // if (mirrormodel) // R_FlipModel(false); }
/* ================= R_DrawAliasModel ================= */ void R_DrawAliasModel (entity_t *e) { maliasmodel_t *paliashdr; vec3_t bbox[8]; qboolean mirrormodel = false; int i; // also skip this for viewermodels and cameramodels if ( !(e->flags & RF_WEAPONMODEL || e->flags & RF_VIEWERMODEL || e->renderfx & RF2_CAMERAMODEL) ) { if (R_CullAliasModel(bbox, e)) return; } // mirroring support if (e->flags & RF_WEAPONMODEL) { if (r_lefthand->value == 2) return; else if (r_lefthand->value == 1) mirrormodel = true; } else if (e->renderfx & RF2_CAMERAMODEL) { if (r_lefthand->value==1) mirrormodel = true; } else if (e->flags & RF_MIRRORMODEL) mirrormodel = true; // end mirroring support paliashdr = (maliasmodel_t *)currentmodel->extradata; R_SetShadeLight (); if (e->flags & RF_DEPTHHACK) // hack the depth range to prevent view model from poking into walls { if (r_newrefdef.rdflags & RDF_NOWORLDMODEL) GL_DepthRange (gldepthmin, gldepthmin + 0.01*(gldepthmax-gldepthmin)); else GL_DepthRange (gldepthmin, gldepthmin + 0.3*(gldepthmax-gldepthmin)); } // mirroring support if (mirrormodel) R_FlipModel(true); for (i=0; i < paliashdr->num_meshes; i++) c_alias_polys += paliashdr->meshes[i].num_tris; qglPushMatrix (); e->angles[ROLL] = -e->angles[ROLL]; // roll is backwards R_RotateForEntity (e, true); e->angles[ROLL] = -e->angles[ROLL]; // roll is backwards GL_ShadeModel (GL_SMOOTH); GL_TexEnv(GL_MODULATE); if ( (e->frame >= paliashdr->num_frames) || (e->frame < 0) ) { VID_Printf (PRINT_ALL, "R_DrawAliasModel %s: no such frame %d\n", currentmodel->name, e->frame); e->frame = 0; e->oldframe = 0; } if ( (e->oldframe >= paliashdr->num_frames) || (e->oldframe < 0)) { VID_Printf (PRINT_ALL, "R_DrawAliasModel %s: no such oldframe %d\n", currentmodel->name, e->oldframe); e->frame = 0; e->oldframe = 0; } if (!r_lerpmodels->value) e->backlerp = 0; R_DrawAliasFrameLerp (paliashdr, e); GL_TexEnv(GL_REPLACE); GL_ShadeModel (GL_FLAT); qglPopMatrix (); // mirroring support if (mirrormodel) R_FlipModel(false); // show model bounding box R_DrawAliasModelBBox (bbox, e); if (e->flags & RF_DEPTHHACK) GL_DepthRange (gldepthmin, gldepthmax); aliasShadowAlpha = R_CalcShadowAlpha(e); if (!(e->flags & (RF_WEAPONMODEL | RF_NOSHADOW)) // no shadows from shells && !( (e->flags & (RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM)) && (e->flags & RF_TRANSLUCENT) ) && r_shadows->value >= 1 && aliasShadowAlpha >= DIV255) { qglPushMatrix (); GL_DisableTexture(0); GL_Enable (GL_BLEND); if (r_shadows->value == 3) { e->angles[ROLL] = -e->angles[ROLL]; // roll is backwards R_RotateForEntity (e, true); e->angles[ROLL] = -e->angles[ROLL]; // roll is backwards R_DrawAliasVolumeShadow (paliashdr, bbox); } else { R_RotateForEntity (e, false); R_DrawAliasPlanarShadow (paliashdr); } GL_Disable (GL_BLEND); GL_EnableTexture(0); qglPopMatrix (); } }