/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // r_main.c #include #include "r_local.h" #include "vlights.h" void R_Clear (void); viddef_t vid; int GL_TEXTURE0, GL_TEXTURE1; model_t *r_worldmodel; float gldepthmin, gldepthmax; glconfig_t gl_config; glstate_t gl_state; image_t *r_notexture; // use for bad textures #ifdef ROQ_SUPPORT image_t *r_rawtexture; // used for cinematics #endif // ROQ_SUPPORT image_t *r_envmappic; image_t *r_spheremappic; image_t *r_shelltexture; image_t *r_particlebeam; //Knightmare- Psychospaz's enhanced particles image_t *r_particletextures[PARTICLE_TYPES]; //list for particles entity_t *currententity; int r_worldframe; // Knightmare added for trans animations model_t *currentmodel; cplane_t frustum[4]; int r_visframecount; // bumped when going to a new PVS int r_framecount; // used for dlight push checking int c_brush_polys, c_alias_polys; float v_blend[4]; // final blending color int maxsize; // Nexus void GL_Strings_f( void ); // // view origin // vec3_t vup; vec3_t vpn; vec3_t vright; vec3_t r_origin; float r_world_matrix[16]; float r_base_world_matrix[16]; // // screen size info // refdef_t r_newrefdef; int r_viewcluster, r_viewcluster2, r_oldviewcluster, r_oldviewcluster2; cvar_t *r_norefresh; cvar_t *r_drawentities; cvar_t *r_drawworld; cvar_t *r_speeds; cvar_t *r_fullbright; cvar_t *r_novis; cvar_t *r_nocull; cvar_t *r_lerpmodels; cvar_t *r_ignorehwgamma; // Knightmare- hardware gamma cvar_t *r_lefthand; cvar_t *r_waterwave; // Knightmare- water waves cvar_t *r_saveshotsize;// Knightmare- save shot size option // Knightmare- lerped dlights on models cvar_t *r_dlights_normal; cvar_t *r_model_shading; cvar_t *r_model_dlights; cvar_t *r_lightlevel; // FIXME: This is a HACK to get the client's light level #ifdef FLARES cvar_t *r_flares; cvar_t *r_flare_force_size; cvar_t *r_flare_force_style; cvar_t *r_flare_intensity; cvar_t *r_flare_maxdist; cvar_t *r_flare_scale; #endif // Knightmare- added Vic's overbright rendering cvar_t *r_overbrightbits; cvar_t *gl_nosubimage; cvar_t *gl_allow_software; cvar_t *gl_vertex_arrays; // Knightmare- added Psychospaz's console font size option cvar_t *con_font; cvar_t *con_font_size; cvar_t *alt_text_color; cvar_t *scr_netgraph_pos; // Knigntmare- Psychospaz's chasecam cvar_t *cl_3dcam; cvar_t *cl_3dcam_angle; cvar_t *cl_3dcam_dist; cvar_t *cl_3dcam_alpha; cvar_t *cl_3dcam_adjust; // end Knightmare cvar_t *gl_ext_swapinterval; cvar_t *gl_ext_multitexture; cvar_t *gl_ext_compiled_vertex_array; // Knightmare- added Vic's overbright rendering cvar_t *gl_ext_mtexcombine; // Knightmare- allow disabling of lightmaps on trans and warp surfaces cvar_t *gl_trans_lightmaps; // Knightmare- allow disabling the nVidia water warp cvar_t *gl_pixel_shader_warp; // Knightmare- added Psychospaz's envmapping cvar_t *gl_glass_envmaps; cvar_t *r_trans_surf_sorting; // trans bmodel sorting cvar_t *r_shelltype; // entity shells: 0 = solid, 1 = warp, 2 = spheremap cvar_t *gl_ext_texture_compression; // Heffo - ARB Texture Compression cvar_t *gl_screenshot_jpeg; // Heffo - JPEG Screenshots cvar_t *gl_screenshot_jpeg_quality; // Heffo - JPEG Screenshots //cvar_t *gl_motionblur; // motionblur cvar_t *gl_lightcutoff; //** DMP - allow dynamic light cutoff to be user-settable cvar_t *gl_log; cvar_t *gl_bitdepth; cvar_t *gl_drawbuffer; cvar_t *gl_driver; cvar_t *gl_lightmap; cvar_t *gl_shadows; cvar_t *gl_shadowalpha; cvar_t *gl_stencil; cvar_t *gl_transrendersort; //Knightmare- correct trasparent sorting cvar_t *gl_particle_lighting; //Knightmare- particle lighting cvar_t *gl_particle_min; cvar_t *gl_particle_max; cvar_t *gl_particledistance; cvar_t *gl_particle_overdraw; cvar_t *gl_mode; cvar_t *gl_dynamic; cvar_t *gl_monolightmap; cvar_t *gl_modulate; cvar_t *gl_nobind; cvar_t *gl_round_down; cvar_t *gl_picmip; cvar_t *gl_skymip; cvar_t *gl_showtris; cvar_t *gl_showbbox; // Knightmare- show model bounding box cvar_t *gl_ztrick; cvar_t *gl_finish; cvar_t *gl_clear; cvar_t *gl_cull; cvar_t *gl_polyblend; cvar_t *gl_flashblend; cvar_t *gl_playermip; cvar_t *gl_saturatelighting; cvar_t *gl_swapinterval; cvar_t *gl_texturemode; cvar_t *gl_anisotropic; cvar_t *gl_anisotropic_avail; cvar_t *gl_swapinterval; cvar_t *gl_texturealphamode; cvar_t *gl_texturesolidmode; cvar_t *gl_lockpvs; cvar_t *gl_3dlabs_broken; cvar_t *vid_fullscreen; cvar_t *vid_gamma; cvar_t *vid_ref; #ifdef LIGHT_BLOOMS cvar_t *r_bloom; #endif cvar_t *r_skydistance; //Knightmare- variable sky range cvar_t *gl_saturation; //** DMP //Knightmare- stenciling for shadows & color shells /* ================= GL_Stencil setting stencil buffer ================= */ extern qboolean have_stencil; void GL_Stencil (qboolean enable, qboolean shell) { if (!have_stencil || !gl_stencil->value) return; if (enable) { if (shell) { qglPushAttrib(GL_STENCIL_BUFFER_BIT); qglClear(GL_STENCIL_BUFFER_BIT); } qglEnable(GL_STENCIL_TEST); qglStencilFunc(GL_EQUAL, 1, 2); qglStencilOp(GL_KEEP,GL_KEEP,GL_INCR); /*if (shell) { qglEnable(GL_STENCIL_TEST); //qglClearStencil(4); //qglClear(GL_STENCIL_BUFFER_BIT); qglStencilMask (4); // enable 3rd bit qglStencilFunc(GL_NOTEQUAL, 4, 4); qglStencilOp(GL_KEEP,GL_KEEP,GL_REPLACE); } else { qglEnable(GL_STENCIL_TEST); qglStencilMask (2); // enable 2nd bit qglStencilFunc(GL_NOTEQUAL, 2, 2); qglStencilOp(GL_KEEP,GL_KEEP,GL_REPLACE); }*/ } else { qglDisable(GL_STENCIL_TEST); if (shell) qglPopAttrib(); } } qboolean GL_HasStencil (void) { return (have_stencil && gl_stencil->value); } /* ================= GL_Envmap setting up envmap ================= */ void GL_Envmap (qboolean enable) { if (enable) { qglTexGenf(GL_S, GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP); qglTexGenf(GL_T, GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP); GLSTATE_ENABLE_TEXGEN } else { GLSTATE_DISABLE_TEXGEN } } /* ================= R_CullBox Returns true if the box is completely outside the frustom ================= */ qboolean R_CullBox (vec3_t mins, vec3_t maxs) { int i; if (r_nocull->value) return false; for (i=0 ; i<4 ; i++) if ( BOX_ON_PLANE_SIDE(mins, maxs, &frustum[i]) == 2) return true; return false; } /* ============== R_ShadowBlend Draws projection shadow(s) from stenciled volume ============== */ #ifdef PROJECTION_SHADOWS void R_ShadowBlend (float shadowalpha) { if (gl_shadows->value != 3) return; qglPushMatrix(); qglLoadIdentity (); // FIXME: get rid of these qglRotatef (-90, 1, 0, 0); // put Z going up qglRotatef (90, 0, 0, 1); // put Z going up qglColor4f (0,0,0, shadowalpha); GLSTATE_DISABLE_ALPHATEST qglEnable( GL_BLEND ); qglDisable (GL_DEPTH_TEST); qglDisable (GL_TEXTURE_2D); qglEnable(GL_STENCIL_TEST); qglStencilFunc( GL_NOTEQUAL, 0, 0xFF); qglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); qglBegin (GL_QUADS); qglVertex3f (10, 100, 100); qglVertex3f (10, -100, 100); qglVertex3f (10, -100, -100); qglVertex3f (10, 100, -100); qglEnd (); qglPopMatrix(); qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); qglDisable ( GL_BLEND ); qglEnable (GL_TEXTURE_2D); qglEnable (GL_DEPTH_TEST); //GLSTATE_ENABLE_ALPHATEST qglDisable(GL_STENCIL_TEST); qglColor4f(1,1,1,1); } #endif /* ============ R_PolyBlend ============ */ void R_PolyBlend (void) { if (!gl_polyblend->value) return; if (!v_blend[3]) return; qglDisable (GL_ALPHA_TEST); qglEnable (GL_BLEND); qglDisable (GL_DEPTH_TEST); qglDisable (GL_TEXTURE_2D); qglLoadIdentity (); // FIXME: get rid of these qglRotatef (-90, 1, 0, 0); // put Z going up qglRotatef (90, 0, 0, 1); // put Z going up qglColor4fv (v_blend); qglBegin (GL_QUADS); qglVertex3f (10, 100, 100); qglVertex3f (10, -100, 100); qglVertex3f (10, -100, -100); qglVertex3f (10, 100, -100); qglEnd (); qglDisable (GL_BLEND); qglEnable (GL_TEXTURE_2D); qglEnable (GL_ALPHA_TEST); qglColor4f(1,1,1,1); } //======================================================================= int SignbitsForPlane (cplane_t *out) { int bits, j; // for fast box on planeside test bits = 0; for (j=0 ; j<3 ; j++) { if (out->normal[j] < 0) bits |= 1<cluster; // check above and below so crossing solid water doesn't draw wrong if (!leaf->contents) { // look down a bit vec3_t temp; VectorCopy (r_origin, temp); temp[2] -= 16; leaf = Mod_PointInLeaf (temp, r_worldmodel); if ( !(leaf->contents & CONTENTS_SOLID) && (leaf->cluster != r_viewcluster2) ) r_viewcluster2 = leaf->cluster; } else { // look up a bit vec3_t temp; VectorCopy (r_origin, temp); temp[2] += 16; leaf = Mod_PointInLeaf (temp, r_worldmodel); if ( !(leaf->contents & CONTENTS_SOLID) && (leaf->cluster != r_viewcluster2) ) r_viewcluster2 = leaf->cluster; } } for (i=0 ; i<4 ; i++) v_blend[i] = r_newrefdef.blend[i]; c_brush_polys = 0; c_alias_polys = 0; // clear out the portion of the screen that the NOWORLDMODEL defines /*if ( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) { qglEnable( GL_SCISSOR_TEST ); qglClearColor( 0.3, 0.3, 0.3, 1 ); qglScissor( r_newrefdef.x, vid.height - r_newrefdef.height - r_newrefdef.y, r_newrefdef.width, r_newrefdef.height ); qglClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); qglClearColor( 1, 0, 0.5, 0.5 ); qglDisable( GL_SCISSOR_TEST ); }*/ } void MYgluPerspective( GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar ) { GLdouble xmin, xmax, ymin, ymax; ymax = zNear * tan( fovy * M_PI / 360.0 ); ymin = -ymax; xmin = ymin * aspect; xmax = ymax * aspect; xmin += -( 2 * gl_state.camera_separation ) / zNear; xmax += -( 2 * gl_state.camera_separation ) / zNear; qglFrustum( xmin, xmax, ymin, ymax, zNear, zFar ); } /* ============= R_SetupGL ============= */ void R_SetupGL (void) { float screenaspect; // float yfov; int x, x2, y2, y, w, h; //Knightmare- variable sky range static GLdouble farz; GLdouble boxsize; //end Knightmare // Knightmare- update gl_modulate in real time if (gl_modulate->modified && (r_worldmodel)) //Don't do this if no map is loaded { msurface_t *surf; int i; for (i=0,surf = r_worldmodel->surfaces; inumsurfaces; i++,surf++) surf->cached_light[0]=0; gl_modulate->modified = 0; } // // set up viewport // x = floor(r_newrefdef.x * vid.width / vid.width); x2 = ceil((r_newrefdef.x + r_newrefdef.width) * vid.width / vid.width); y = floor(vid.height - r_newrefdef.y * vid.height / vid.height); y2 = ceil(vid.height - (r_newrefdef.y + r_newrefdef.height) * vid.height / vid.height); w = x2 - x; h = y - y2; qglViewport (x, y2, w, h); // Knightmare- variable sky range // calc farz falue from skybox size if (r_skydistance->modified) { r_skydistance->modified = false; boxsize = r_skydistance->value; boxsize -= 252 * ceil (boxsize / 2300); farz = 1.0; while (farz < boxsize) //make this a power of 2 { farz *= 2.0; if (farz >= 65536) //don't make it larger than this break; } farz *= 2.0; //double since boxsize is distance from camera to edge of skybox //not total size of skybox VID_Printf(PRINT_DEVELOPER, "farz now set to %g\n", farz); } // end Knightmare // // set up projection matrix // screenaspect = (float)r_newrefdef.width/r_newrefdef.height; // yfov = 2*atan((float)r_newrefdef.height/r_newrefdef.width)*180/M_PI; qglMatrixMode(GL_PROJECTION); qglLoadIdentity (); //Knightmare- 12/26/2001- increase back clipping plane distance MYgluPerspective (r_newrefdef.fov_y, screenaspect, 4, farz); //was 4096 //end Knightmare qglCullFace(GL_FRONT); qglMatrixMode(GL_MODELVIEW); qglLoadIdentity (); qglRotatef (-90, 1, 0, 0); // put Z going up qglRotatef (90, 0, 0, 1); // put Z going up qglRotatef (-r_newrefdef.viewangles[2], 1, 0, 0); qglRotatef (-r_newrefdef.viewangles[0], 0, 1, 0); qglRotatef (-r_newrefdef.viewangles[1], 0, 0, 1); qglTranslatef (-r_newrefdef.vieworg[0], -r_newrefdef.vieworg[1], -r_newrefdef.vieworg[2]); // if ( gl_state.camera_separation != 0 && gl_state.stereo_enabled ) // qglTranslatef ( gl_state.camera_separation, 0, 0 ); qglGetFloatv (GL_MODELVIEW_MATRIX, r_world_matrix); // // set drawing parms // if (gl_cull->value) qglEnable(GL_CULL_FACE); else qglDisable(GL_CULL_FACE); qglDisable(GL_BLEND); qglDisable(GL_ALPHA_TEST); qglEnable(GL_DEPTH_TEST); } /* ============= R_Clear ============= */ void R_Clear (void) { if (gl_ztrick->value) { static int trickframe; if (gl_clear->value) qglClear (GL_COLOR_BUFFER_BIT); trickframe++; if (trickframe & 1) { gldepthmin = 0; gldepthmax = 0.49999; qglDepthFunc (GL_LEQUAL); } else { gldepthmin = 1; gldepthmax = 0.5; qglDepthFunc (GL_GEQUAL); } } else { if (gl_clear->value) qglClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); else qglClear (GL_DEPTH_BUFFER_BIT); gldepthmin = 0; gldepthmax = 1; qglDepthFunc (GL_LEQUAL); } qglDepthRange (gldepthmin, gldepthmax); //Knightmare- 12/24/2001- stencil buffer if (have_stencil) { #ifdef PROJECTION_SHADOWS if (gl_shadows->value == 3) // BeefQuake R6 shadows qglClearStencil(0); else #endif qglClearStencil(1); qglClear(GL_STENCIL_BUFFER_BIT); } qglDepthRange (gldepthmin, gldepthmax); //end Knightmare } void R_Flash (void) { R_PolyBlend (); } /* ============================================ SURFACE / ELEMENT SORTING (UNUSED) ============================================ */ #if 0 qboolean checkElementSurfaceScan (msurface_t *surf, vec3_t start) { float front, back, side, dist; vec3_t end, normal; cplane_t *plane; plane = surf->plane; if (!plane) return false; dist = plane->dist; VectorCopy(plane->normal, normal); VectorCopy(r_newrefdef.vieworg, end); front = DotProduct (start, normal) - dist; back = DotProduct (end, normal) - dist; side = front < 0; if ( (back < 0) == side) return false; return true; } sortedelement_t *listswap[2]; void ElementChecker (sortedelement_t *element, msurface_t *surf) { if (!element) return; ElementChecker(element->right, surf); ElementChecker(element->left, surf); element->left = element->right = NULL; if (checkElementSurfaceScan(surf, element->org)) { if (!listswap[0]) listswap[0] = element; else ElementAddNode(listswap[0], element); } else { if (!listswap[1]) listswap[1] = element; else ElementAddNode(listswap[1], element); } } void surf_ElementList(msurface_t *surf, qboolean ents) { sortedelement_t *last = NULL, *found = NULL; listswap[0] = listswap[1] = NULL; if (ents) ElementChecker(ents_prerender, surf); else ElementChecker(parts_prerender, surf); if (ents) { ents_prerender = listswap[1]; RenderEntTree(listswap[0]); } else { parts_prerender = listswap[1]; R_DrawParticles(listswap[0]); } } #endif void R_DrawLastElements (void) { //if (parts_prerender) // R_DrawParticles(parts_prerender); if (ents_prerender) R_DrawEntitiesOnList(ents_prerender); } //============================================ /* ================ R_RenderView r_newrefdef must be set before the first call ================ */ void R_RenderView (refdef_t *fd) { if (r_norefresh->value) return; r_newrefdef = *fd; if (!r_worldmodel && !( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) ) VID_Error (ERR_DROP, "R_RenderView: NULL worldmodel"); if (r_speeds->value) { c_brush_polys = 0; c_alias_polys = 0; } R_PushDlights (); if (gl_finish->value) qglFinish (); R_SetupFrame (); R_SetFrustum (); R_SetupGL (); R_MarkLeaves (); // done here so we know if we're in water R_DrawWorld (); #ifdef FLARES R_RenderFlares(); #endif if (r_newrefdef.rdflags & RDF_NOWORLDMODEL) // options menu { qboolean fog_on = false; //Knightmare- no fogging on menu/hud models if (qglIsEnabled(GL_FOG)) //check if fog is enabled { fog_on = true; qglDisable(GL_FOG); //if so, disable it } //R_DrawAllDecals(); R_DrawAllEntities(false); R_DrawAllParticles(); //re-enable fog if it was on if (fog_on) qglEnable(GL_FOG); } else { GLSTATE_DISABLE_ALPHATEST R_RenderDlights(); if (gl_transrendersort->value) { //R_BuildParticleList(); R_SortParticlesOnList(); #ifdef DECALS R_DrawAllDecals(); #endif R_DrawSolidEntities(); //R_DrawAllEntityShadows(); R_DrawLastElements(); /*if (gl_transrendersort->value == 1) { R_DrawLastElements(); R_DrawEntitiesOnList(ents_viewweaps); R_DrawAlphaSurfaces (false); // redraw over alpha surfaces, those behind are occluded if (gl_particle_overdraw->value) R_DrawLastElements(); } else { R_DrawAlphaSurfaces (true); R_DrawLastElements(); }*/ } else { #ifdef DECALS R_DrawAllDecals(); #endif //R_DrawAllEntityShadows(); R_DrawAllEntities(true); //R_DrawAllParticles(); //R_DrawEntitiesOnList(ents_viewweaps); //R_DrawAlphaSurfaces (false); // redraw over alpha surfaces, those behind are occluded //if (gl_particle_overdraw->value) // R_DrawAllParticles(); } R_DrawAllParticles (); R_DrawEntitiesOnList(ents_viewweaps); R_DrawAlphaSurfaces (false); if (gl_particle_overdraw->value) // redraw over alpha surfaces, those behind are occluded R_DrawAllParticles (); //always draw vwep last... R_DrawEntitiesOnList(ents_viewweaps_trans); #ifdef LIGHT_BLOOMS R_BloomBlend (fd);//BLOOMS #endif R_Flash(); GLSTATE_ENABLE_ALPHATEST } R_SetFog(); } /* ================ R_SetGL2D ================ */ void R_SetGL2D (void) { // set 2D virtual screen size qglViewport (0,0, vid.width, vid.height); qglMatrixMode(GL_PROJECTION); qglLoadIdentity (); qglOrtho (0, vid.width, vid.height, 0, -99999, 99999); qglMatrixMode(GL_MODELVIEW); qglLoadIdentity (); qglDisable (GL_DEPTH_TEST); qglDisable (GL_CULL_FACE); qglDisable (GL_BLEND); qglEnable (GL_ALPHA_TEST); qglColor4f (1,1,1,1); // Knightmare- draw r_speeds (modified from Echon's tutorial) if (r_speeds->value && !(r_newrefdef.rdflags & RDF_NOWORLDMODEL)) // don't do this for options menu { char S[128]; int i, j, x, y, n = 0; int red, green, blue; int shadowoffset_x, shadowoffset_y; float textscale = FONT_SIZE / MENU_FONT_SIZE; TextColor ((int)alt_text_color->value, &red, &green, &blue); shadowoffset_x = FONT_SIZE / 4; shadowoffset_y = FONT_SIZE / 8; //n = sprintf (S, "%5i wpoly %5i epoly %i tex %i lmaps", // c_brush_polys, c_alias_polys, c_visible_textures, c_visible_lightmaps); for (i = 0; i < 4; i++) { switch (i) { case 0: n = sprintf (S, "%5i wpoly", c_brush_polys); break; case 1: n = sprintf (S, "%5i epoly", c_alias_polys); break; case 2: n = sprintf (S, "%5i tex ", c_visible_textures); break; case 3: n = sprintf (S, "%5i lmaps", c_visible_lightmaps); break; default: break; } if (scr_netgraph_pos->value) x = r_newrefdef.width - (n*FONT_SIZE + FONT_SIZE/2); else x = FONT_SIZE/2; y = r_newrefdef.height-(4-i)*(FONT_SIZE+2); for (j = 0; j < n; j++) { R_DrawScaledChar (x+(j*FONT_SIZE)+shadowoffset_x, y+shadowoffset_y, 128+S[j], textscale, 0, 0, 0, 255, false); R_DrawScaledChar (x+(j*FONT_SIZE), y, 128+S[j], textscale, red, green, blue, 255, false); } } } } #if 0 static void GL_DrawColoredStereoLinePair( float r, float g, float b, float y ) { qglColor3f( r, g, b ); qglVertex2f( 0, y ); qglVertex2f( vid.width, y ); qglColor3f( 0, 0, 0 ); qglVertex2f( 0, y + 1 ); qglVertex2f( vid.width, y + 1 ); } static void GL_DrawStereoPattern( void ) { int i; if ( !( gl_config.renderer & GL_RENDERER_INTERGRAPH ) ) return; if ( !gl_state.stereo_enabled ) return; R_SetGL2D(); qglDrawBuffer( GL_BACK_LEFT ); for ( i = 0; i < 20; i++ ) { qglBegin( GL_LINES ); GL_DrawColoredStereoLinePair( 1, 0, 0, 0 ); GL_DrawColoredStereoLinePair( 1, 0, 0, 2 ); GL_DrawColoredStereoLinePair( 1, 0, 0, 4 ); GL_DrawColoredStereoLinePair( 1, 0, 0, 6 ); GL_DrawColoredStereoLinePair( 0, 1, 0, 8 ); GL_DrawColoredStereoLinePair( 1, 1, 0, 10); GL_DrawColoredStereoLinePair( 1, 1, 0, 12); GL_DrawColoredStereoLinePair( 0, 1, 0, 14); qglEnd(); GLimp_EndFrame(); } } #endif /* ==================== R_SetLightLevel ==================== */ void R_SetLightLevel (void) { vec3_t shadelight; if (r_newrefdef.rdflags & RDF_NOWORLDMODEL) return; // save off light value for server to look at (BIG HACK!) R_LightPoint (r_newrefdef.vieworg, shadelight, false);//true); // 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]; } } /* @@@@@@@@@@@@@@@@@@@@@ R_RenderFrame @@@@@@@@@@@@@@@@@@@@@ */ void R_RenderFrame (refdef_t *fd) { R_RenderView( fd ); R_SetLightLevel (); R_SetGL2D (); } void R_Register( void ) { r_lefthand = Cvar_Get( "hand", "0", CVAR_USERINFO | CVAR_ARCHIVE ); r_norefresh = Cvar_Get ("r_norefresh", "0", 0); r_fullbright = Cvar_Get ("r_fullbright", "0", 0); r_drawentities = Cvar_Get ("r_drawentities", "1", 0); r_drawworld = Cvar_Get ("r_drawworld", "1", 0); r_novis = Cvar_Get ("r_novis", "0", 0); r_nocull = Cvar_Get ("r_nocull", "0", 0); r_lerpmodels = Cvar_Get ("r_lerpmodels", "1", 0); r_speeds = Cvar_Get ("r_speeds", "0", 0); //Knightamre- hardware gamma r_ignorehwgamma = Cvar_Get ("r_ignorehwgamma", "0", CVAR_ARCHIVE); // Knightmare- added Psychospaz's console font size option con_font = Cvar_Get ("con_font", "default", CVAR_ARCHIVE); con_font_size = Cvar_Get ("con_font_size", "12", CVAR_ARCHIVE); alt_text_color = Cvar_Get ("alt_text_color", "2", CVAR_ARCHIVE); scr_netgraph_pos = Cvar_Get ("netgraph_pos", "0", CVAR_ARCHIVE); // Knigntmare- Psychospaz's chasecam cl_3dcam = Cvar_Get ("cl_3dcam", "0", CVAR_ARCHIVE); cl_3dcam_angle = Cvar_Get ("cl_3dcam_angle", "0", CVAR_ARCHIVE); cl_3dcam_dist = Cvar_Get ("cl_3dcam_dist", "50", CVAR_ARCHIVE); cl_3dcam_alpha = Cvar_Get ("cl_3dcam_alpha", "0", CVAR_ARCHIVE); cl_3dcam_adjust = Cvar_Get ("cl_3dcam_adjust", "1", CVAR_ARCHIVE); // Knightmare- lerped dlights on models r_dlights_normal = Cvar_Get("r_dlights_normal", "1", CVAR_ARCHIVE); r_model_shading = Cvar_Get( "r_model_shading", "2", CVAR_ARCHIVE ); r_model_dlights = Cvar_Get( "r_model_dlights", "8", CVAR_ARCHIVE ); r_lightlevel = Cvar_Get ("r_lightlevel", "0", 0); #ifdef FLARES r_flares = Cvar_Get("r_flares", "0", CVAR_ARCHIVE); r_flare_force_size = Cvar_Get("r_flare_force_size", "0", CVAR_ARCHIVE); r_flare_force_style = Cvar_Get("r_flare_force_style", "1", CVAR_ARCHIVE); r_flare_intensity = Cvar_Get("r_flare_intensity", "1", CVAR_ARCHIVE); r_flare_maxdist = Cvar_Get("r_flare_maxdist", "150", CVAR_ARCHIVE); r_flare_scale = Cvar_Get("r_flare_scale", "1.5", CVAR_ARCHIVE); #endif // Knightmare- added Vic's overbright rendering r_overbrightbits = Cvar_Get ("r_overbrightbits", "2", CVAR_ARCHIVE); r_waterwave = Cvar_Get ("r_waterwave", "0", CVAR_ARCHIVE ); r_saveshotsize = Cvar_Get ("r_saveshotsize", "1", CVAR_ARCHIVE ); gl_nosubimage = Cvar_Get( "gl_nosubimage", "0", 0 ); gl_allow_software = Cvar_Get( "gl_allow_software", "0", 0 ); // Knightmare- correct trasparent sorting gl_transrendersort = Cvar_Get ("gl_transrendersort", "1", CVAR_ARCHIVE ); // Knightmare- perticle lighting gl_particle_lighting = Cvar_Get ("gl_particle_lighting", "0.75", CVAR_ARCHIVE ); gl_particledistance = Cvar_Get ("gl_particledistance", "0", CVAR_ARCHIVE ); gl_particle_overdraw = Cvar_Get ("gl_particle_overdraw", "0", CVAR_ARCHIVE ); gl_particle_min = Cvar_Get ("gl_particle_min", "0", CVAR_ARCHIVE ); gl_particle_max = Cvar_Get ("gl_particle_max", "0", CVAR_ARCHIVE ); gl_modulate = Cvar_Get ("gl_modulate", "1", CVAR_ARCHIVE ); gl_log = Cvar_Get( "gl_log", "0", 0 ); gl_bitdepth = Cvar_Get( "gl_bitdepth", "0", 0 ); gl_mode = Cvar_Get( "gl_mode", "3", CVAR_ARCHIVE ); gl_lightmap = Cvar_Get ("gl_lightmap", "0", 0); gl_shadows = Cvar_Get ("gl_shadows", "0", CVAR_ARCHIVE ); gl_shadowalpha = Cvar_Get ("gl_shadowalpha", "0.4", CVAR_ARCHIVE ); gl_stencil = Cvar_Get ("gl_stencil", "1", CVAR_ARCHIVE ); gl_dynamic = Cvar_Get ("gl_dynamic", "1", 0); gl_nobind = Cvar_Get ("gl_nobind", "0", 0); gl_round_down = Cvar_Get ("gl_round_down", "1", 0); gl_picmip = Cvar_Get ("gl_picmip", "0", 0); gl_skymip = Cvar_Get ("gl_skymip", "0", 0); gl_showtris = Cvar_Get ("gl_showtris", "0", 0); gl_showbbox = Cvar_Get ("gl_showbbox", "0", 0); // Knightmare- show model bounding box gl_ztrick = Cvar_Get ("gl_ztrick", "0", 0); gl_finish = Cvar_Get ("gl_finish", "0", CVAR_ARCHIVE); gl_clear = Cvar_Get ("gl_clear", "0", 0); gl_cull = Cvar_Get ("gl_cull", "1", 0); gl_polyblend = Cvar_Get ("gl_polyblend", "1", 0); gl_flashblend = Cvar_Get ("gl_flashblend", "0", 0); gl_playermip = Cvar_Get ("gl_playermip", "0", 0); gl_monolightmap = Cvar_Get( "gl_monolightmap", "0", 0 ); #ifdef _WIN32 gl_driver = Cvar_Get( "gl_driver", "opengl32", CVAR_ARCHIVE ); #else gl_driver = Cvar_Get( "gl_driver", "libGL.so", CVAR_ARCHIVE ); #endif // Knightmare- changed default texture mode to bilinear gl_texturemode = Cvar_Get( "gl_texturemode", "GL_LINEAR_MIPMAP_NEAREST", CVAR_ARCHIVE ); gl_anisotropic = Cvar_Get( "gl_anisotropic", "0", CVAR_ARCHIVE ); gl_anisotropic_avail = Cvar_Get( "gl_anisotropic_avail", "0", 0 ); gl_texturealphamode = Cvar_Get( "gl_texturealphamode", "default", CVAR_ARCHIVE ); gl_texturesolidmode = Cvar_Get( "gl_texturesolidmode", "default", CVAR_ARCHIVE ); gl_lockpvs = Cvar_Get( "gl_lockpvs", "0", 0 ); gl_vertex_arrays = Cvar_Get( "gl_vertex_arrays", "1", CVAR_ARCHIVE ); //gl_ext_palettedtexture = Cvar_Get( "gl_ext_palettedtexture", "0", CVAR_ARCHIVE ); //gl_ext_pointparameters = Cvar_Get( "gl_ext_pointparameters", "1", CVAR_ARCHIVE ); gl_ext_swapinterval = Cvar_Get( "gl_ext_swapinterval", "1", CVAR_ARCHIVE ); gl_ext_multitexture = Cvar_Get( "gl_ext_multitexture", "1", CVAR_ARCHIVE ); gl_ext_compiled_vertex_array = Cvar_Get( "gl_ext_compiled_vertex_array", "1", CVAR_ARCHIVE ); // Knightmare- allow disabling the nVidia water warp gl_pixel_shader_warp = Cvar_Get( "gl_pixel_shader_warp", "1", CVAR_ARCHIVE ); // Knightmare- allow disabling of lightmaps on trans and warp surfaces gl_trans_lightmaps = Cvar_Get( "gl_trans_lightmaps", "1", CVAR_ARCHIVE ); // Knightmare- added Psychospaz's envmapping gl_glass_envmaps = Cvar_Get( "gl_glass_envmaps", "1", CVAR_ARCHIVE ); r_trans_surf_sorting = Cvar_Get( "r_trans_surf_sorting", "0", CVAR_ARCHIVE ); r_shelltype = Cvar_Get( "r_shelltype", "1", CVAR_ARCHIVE ); // Knightmare- added Vic's overbright rendering gl_ext_mtexcombine = Cvar_Get ("gl_ext_mtexcombine", "1", CVAR_ARCHIVE); gl_ext_texture_compression = Cvar_Get( "gl_ext_texture_compression", "0", CVAR_ARCHIVE ); // Heffo - ARB Texture Compression gl_screenshot_jpeg = Cvar_Get( "gl_screenshot_jpeg", "1", CVAR_ARCHIVE ); // Heffo - JPEG Screenshots gl_screenshot_jpeg_quality = Cvar_Get( "gl_screenshot_jpeg_quality", "85", CVAR_ARCHIVE ); // Heffo - JPEG Screenshots //gl_motionblur = Cvar_Get( "gl_motionblur", "0", CVAR_ARCHIVE ); // motionblur gl_drawbuffer = Cvar_Get( "gl_drawbuffer", "GL_BACK", 0 ); gl_swapinterval = Cvar_Get( "gl_swapinterval", "1", CVAR_ARCHIVE ); gl_saturatelighting = Cvar_Get( "gl_saturatelighting", "0", 0 ); gl_3dlabs_broken = Cvar_Get( "gl_3dlabs_broken", "1", CVAR_ARCHIVE ); vid_fullscreen = Cvar_Get( "vid_fullscreen", "1", CVAR_ARCHIVE ); vid_gamma = Cvar_Get( "vid_gamma", "0.8", CVAR_ARCHIVE ); // was 1.0 #ifdef _WIN32 vid_ref = Cvar_Get( "vid_ref", "gl", CVAR_ARCHIVE ); #else vid_ref = Cvar_Get( "vid_ref", "kmglx", CVAR_ARCHIVE ); #endif #ifdef LIGHT_BLOOMS r_bloom = Cvar_Get( "r_bloom", "0", CVAR_ARCHIVE ); #endif r_skydistance = Cvar_Get("r_skydistance", "10000", CVAR_ARCHIVE); //Knightmare- variable sky range gl_saturation = Cvar_Get( "gl_saturation", "1.0", CVAR_ARCHIVE ); //** DMP saturation setting (.89 good for nvidia) gl_lightcutoff = Cvar_Get( "gl_lightcutoff", "0", CVAR_ARCHIVE ); //** DMP dynamic light cutoffnow variable Cmd_AddCommand( "imagelist", GL_ImageList_f ); Cmd_AddCommand( "screenshot", GL_ScreenShot_f ); Cmd_AddCommand( "modellist", Mod_Modellist_f ); Cmd_AddCommand( "gl_strings", GL_Strings_f ); } /* ================== R_SetMode ================== */ qboolean R_SetMode (void) { rserr_t err; qboolean fullscreen; if ( vid_fullscreen->modified && !gl_config.allow_cds ) { VID_Printf( PRINT_ALL, "R_SetMode() - CDS not allowed with this driver\n" ); Cvar_SetValue( "vid_fullscreen", !vid_fullscreen->value ); vid_fullscreen->modified = false; } fullscreen = vid_fullscreen->value; //Knightmare- skybox size variable r_skydistance->modified = true; //end Knightmare vid_fullscreen->modified = false; gl_mode->modified = false; if ( ( err = GLimp_SetMode( (int *)&vid.width, (int *)&vid.height, gl_mode->value, fullscreen ) ) == rserr_ok ) { gl_state.prev_mode = gl_mode->value; } else { if ( err == rserr_invalid_fullscreen ) { Cvar_SetValue( "vid_fullscreen", 0); vid_fullscreen->modified = false; VID_Printf( PRINT_ALL, "ref_gl::R_SetMode() - fullscreen unavailable in this mode\n" ); if ( ( err = GLimp_SetMode( (int *)&vid.width, (int *)&vid.height, gl_mode->value, false ) ) == rserr_ok ) return true; } else if ( err == rserr_invalid_mode ) { Cvar_SetValue( "gl_mode", gl_state.prev_mode ); gl_mode->modified = false; VID_Printf( PRINT_ALL, "ref_gl::R_SetMode() - invalid mode\n" ); } // try setting it back to something safe if ( ( err = GLimp_SetMode( (int *)&vid.width, (int *)&vid.height, gl_state.prev_mode, false ) ) != rserr_ok ) { VID_Printf( PRINT_ALL, "ref_gl::R_SetMode() - could not revert to safe mode\n" ); return false; } } return true; } /* =============== R_Init =============== */ qboolean R_Init ( void *hinstance, void *hWnd, char *reason ) { char renderer_buffer[1000]; char vendor_buffer[1000]; int err; int j; extern float r_turbsin[256]; for ( j = 0; j < 256; j++ ) { r_turbsin[j] *= 0.5; } Draw_GetPalette (); R_Register(); VLight_Init(); // Vic's bmodel lights // place default error memcpy (reason, "Unknown failure on intialization!\0", 34); // initialize our QGL dynamic bindings if ( !QGL_Init( gl_driver->string ) ) { QGL_Shutdown(); VID_Printf (PRINT_ALL, "ref_gl::R_Init() - could not load \"%s\"\n", gl_driver->string ); memcpy (reason, "Init of QGL dynamic bindings Failed!\0", 37); return false; } // initialize OS-specific parts of OpenGL if ( !GLimp_Init( hinstance, hWnd ) ) { QGL_Shutdown(); memcpy (reason, "Init of OS-specific parts of OpenGL Failed!\0", 44); return false; } // set our "safe" modes gl_state.prev_mode = 3; // create the window and set up the context if ( !R_SetMode () ) { QGL_Shutdown(); VID_Printf (PRINT_ALL, "ref_gl::R_Init() - could not R_SetMode()\n" ); memcpy (reason, "Creation of the window/context set-up Failed!\0", 46); return false; } VID_MenuInit(); /* ** get our various GL strings */ gl_config.vendor_string = (char *)qglGetString (GL_VENDOR); VID_Printf (PRINT_ALL, "GL_VENDOR: %s\n", gl_config.vendor_string ); gl_config.renderer_string = (char *)qglGetString (GL_RENDERER); VID_Printf (PRINT_ALL, "GL_RENDERER: %s\n", gl_config.renderer_string ); gl_config.version_string = (char *)qglGetString (GL_VERSION); VID_Printf (PRINT_ALL, "GL_VERSION: %s\n", gl_config.version_string ); // Knighmare- added max texture size qglGetIntegerv(GL_MAX_TEXTURE_SIZE,&gl_config.max_texsize); VID_Printf (PRINT_ALL, "GL_MAX_TEXTURE_SIZE: %i\n", gl_config.max_texsize ); gl_config.extensions_string = (char *)qglGetString (GL_EXTENSIONS); VID_Printf (PRINT_ALL, "GL_EXTENSIONS: %s\n", gl_config.extensions_string ); strcpy( renderer_buffer, gl_config.renderer_string ); //strlwr( renderer_buffer ); strcpy( vendor_buffer, gl_config.vendor_string ); //strlwr( vendor_buffer ); if ( strstr( renderer_buffer, "voodoo" ) ) { if ( !strstr( renderer_buffer, "rush" ) ) gl_config.renderer = GL_RENDERER_VOODOO; else gl_config.renderer = GL_RENDERER_VOODOO_RUSH; } else if ( strstr( vendor_buffer, "sgi" ) ) gl_config.renderer = GL_RENDERER_SGI; else if ( strstr( renderer_buffer, "permedia" ) ) gl_config.renderer = GL_RENDERER_PERMEDIA2; else if ( strstr( renderer_buffer, "glint" ) ) gl_config.renderer = GL_RENDERER_GLINT_MX; else if ( strstr( renderer_buffer, "glzicd" ) ) gl_config.renderer = GL_RENDERER_REALIZM; else if ( strstr( renderer_buffer, "gdi" ) ) gl_config.renderer = GL_RENDERER_MCD; else if ( strstr( renderer_buffer, "pcx2" ) ) gl_config.renderer = GL_RENDERER_PCX2; else if ( strstr( renderer_buffer, "verite" ) ) gl_config.renderer = GL_RENDERER_RENDITION; else gl_config.renderer = GL_RENDERER_OTHER; if ( toupper( gl_monolightmap->string[1] ) != 'F' ) { if ( gl_config.renderer == GL_RENDERER_PERMEDIA2 ) { Cvar_Set( "gl_monolightmap", "A" ); VID_Printf( PRINT_ALL, "...using gl_monolightmap 'a'\n" ); } else if ( gl_config.renderer & GL_RENDERER_POWERVR ) { Cvar_Set( "gl_monolightmap", "0" ); } else { Cvar_Set( "gl_monolightmap", "0" ); } } // power vr can't have anything stay in the framebuffer, so // the screen needs to redraw the tiled background every frame if ( gl_config.renderer & GL_RENDERER_POWERVR ) { Cvar_Set( "scr_drawall", "1" ); } else { Cvar_Set( "scr_drawall", "0" ); } #ifdef __unix__ Cvar_SetValue( "gl_finish", 1 ); #else Cvar_SetValue( "gl_finish", 0 ); #endif // MCD has buffering issues if ( gl_config.renderer == GL_RENDERER_MCD ) { Cvar_SetValue( "gl_finish", 1 ); } if ( gl_config.renderer & GL_RENDERER_3DLABS ) { if ( gl_3dlabs_broken->value ) gl_config.allow_cds = false; else gl_config.allow_cds = true; } else { gl_config.allow_cds = true; } if ( gl_config.allow_cds ) VID_Printf( PRINT_ALL, "...allowing CDS\n" ); else VID_Printf( PRINT_ALL, "...disabling CDS\n" ); /* ** grab extensions */ if ( strstr( gl_config.extensions_string, "GL_EXT_compiled_vertex_array" ) || strstr( gl_config.extensions_string, "GL_SGI_compiled_vertex_array" ) ) { VID_Printf( PRINT_ALL, "...enabling GL_EXT_compiled_vertex_array\n" ); qglLockArraysEXT = ( void * ) qwglGetProcAddress( "glLockArraysEXT" ); qglUnlockArraysEXT = ( void * ) qwglGetProcAddress( "glUnlockArraysEXT" ); } else { VID_Printf( PRINT_ALL, "...GL_EXT_compiled_vertex_array not found\n" ); } #ifdef _WIN32 if ( strstr( gl_config.extensions_string, "WGL_EXT_swap_control" ) ) { qwglSwapIntervalEXT = ( BOOL (WINAPI *)(int)) qwglGetProcAddress( "wglSwapIntervalEXT" ); VID_Printf( PRINT_ALL, "...enabling WGL_EXT_swap_control\n" ); } else { VID_Printf( PRINT_ALL, "...WGL_EXT_swap_control not found\n" ); } #endif /*if ( strstr( gl_config.extensions_string, "GL_EXT_point_parameters" ) ) { if ( gl_ext_pointparameters->value ) { qglPointParameterfEXT = ( void (APIENTRY *)( GLenum, GLfloat ) ) qwglGetProcAddress( "glPointParameterfEXT" ); qglPointParameterfvEXT = ( void (APIENTRY *)( GLenum, const GLfloat * ) ) qwglGetProcAddress( "glPointParameterfvEXT" ); VID_Printf( PRINT_ALL, "...using GL_EXT_point_parameters\n" ); } else { VID_Printf( PRINT_ALL, "...ignoring GL_EXT_point_parameters\n" ); } } else { VID_Printf( PRINT_ALL, "...GL_EXT_point_parameters not found\n" ); }*/ /*if ( !qglColorTableEXT && strstr( gl_config.extensions_string, "GL_EXT_paletted_texture" ) && strstr( gl_config.extensions_string, "GL_EXT_shared_texture_palette" ) ) { if ( gl_ext_palettedtexture->value ) { VID_Printf( PRINT_ALL, "...using GL_EXT_shared_texture_palette\n" ); qglColorTableEXT = ( void ( APIENTRY * ) ( int, int, int, int, int, const void * ) ) qwglGetProcAddress( "glColorTableEXT" ); } else { VID_Printf( PRINT_ALL, "...ignoring GL_EXT_shared_texture_palette\n" ); } } else { VID_Printf( PRINT_ALL, "...GL_EXT_shared_texture_palette not found\n" ); }*/ if ( strstr( gl_config.extensions_string, "GL_ARB_multitexture" ) ) { if ( gl_ext_multitexture->value ) { VID_Printf( PRINT_ALL, "...using GL_ARB_multitexture\n" ); qglMTexCoord2fSGIS = ( void * ) qwglGetProcAddress( "glMultiTexCoord2fARB" ); qglActiveTextureARB = ( void * ) qwglGetProcAddress( "glActiveTextureARB" ); qglClientActiveTextureARB = ( void * ) qwglGetProcAddress( "glClientActiveTextureARB" ); GL_TEXTURE0 = GL_TEXTURE0_ARB; GL_TEXTURE1 = GL_TEXTURE1_ARB; } else { VID_Printf( PRINT_ALL, "...ignoring GL_ARB_multitexture\n" ); } } else { VID_Printf( PRINT_ALL, "...GL_ARB_multitexture not found\n" ); } if ( strstr( gl_config.extensions_string, "GL_SGIS_multitexture" ) ) { if ( qglActiveTextureARB ) { VID_Printf( PRINT_ALL, "...GL_SGIS_multitexture deprecated in favor of ARB_multitexture\n" ); } else if ( gl_ext_multitexture->value ) { VID_Printf( PRINT_ALL, "...using GL_SGIS_multitexture\n" ); qglMTexCoord2fSGIS = ( void * ) qwglGetProcAddress( "glMTexCoord2fSGIS" ); qglSelectTextureSGIS = ( void * ) qwglGetProcAddress( "glSelectTextureSGIS" ); GL_TEXTURE0 = GL_TEXTURE0_SGIS; GL_TEXTURE1 = GL_TEXTURE1_SGIS; } else { VID_Printf( PRINT_ALL, "...ignoring GL_SGIS_multitexture\n" ); } } else { VID_Printf( PRINT_ALL, "...GL_SGIS_multitexture not found\n" ); } // Knightmare- added Vic's overbright rendering gl_config.mtexcombine = false; if (strstr(gl_config.extensions_string, "GL_ARB_texture_env_combine")) { if (gl_ext_mtexcombine->value) { Com_Printf("...using GL_ARB_texture_env_combine\n"); gl_config.mtexcombine = true; } else Com_Printf("..ignoring GL_ARB_texture_env_combine\n"); } else Com_Printf("...GL_ARB_texture_env_combine not found\n"); if (!gl_config.mtexcombine) { if (strstr(gl_config.extensions_string, "GL_EXT_texture_env_combine")) { if (gl_ext_mtexcombine->value) { Com_Printf("..using GL_EXT_texture_env_combine\n"); gl_config.mtexcombine = true; } else Com_Printf("...ignoring GL_EXT_texture_env_combine\n"); } else Com_Printf("...GL_EXT_texture_env_combine not found\n"); } // end Knightmare #ifndef __unix__ //Knightmare- added Vic's hardware gamma control if( strstr( gl_config.extensions_string, "WGL_3DFX_gamma_control" )) { if( !r_ignorehwgamma->value ) { qwglGetDeviceGammaRamp3DFX = ( BOOL (WINAPI *)(HDC, WORD *)) qwglGetProcAddress( "wglGetDeviceGammaRamp3DFX" ); qwglSetDeviceGammaRamp3DFX = ( BOOL (WINAPI *)(HDC, WORD *)) qwglGetProcAddress( "wglSetDeviceGammaRamp3DFX" ); Com_Printf( "...using WGL_3DFX_gamma_control\n" ); } else Com_Printf( "...ignoring WGL_3DFX_gamma_control\n" ); } else Com_Printf( "...WGL_3DFX_gamma_control not found\n" ); // end Knightmare #endif // Texture Shader support - MrG if ( strstr( gl_config.extensions_string, "GL_NV_texture_shader" ) ) { VID_Printf(PRINT_ALL, "...using GL_NV_texture_shader\n"); gl_config.NV_texshaders = true; } else { VID_Printf(PRINT_ALL, "...GL_NV_texture_shader not found\n"); gl_config.NV_texshaders = false; } // NeVo - Anisotropic Filtering Support gl_config.anisotropic = false; if ( strstr(gl_config.extensions_string,"GL_EXT_texture_filter_anisotropic") ) { VID_Printf(PRINT_ALL,"...using GL_EXT_texture_filter_anisotropic\n"); gl_config.anisotropic = true; qglGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gl_config.max_anisotropy); Cvar_SetValue("gl_anisotropic_avail", gl_config.max_anisotropy); } else { VID_Printf(PRINT_ALL,"..GL_EXT_texture_filter_anisotropic not found\n"); gl_config.anisotropic = false; gl_config.max_anisotropy = 0.0; Cvar_SetValue("gl_anisotropic_avail", 0.0); } if ( strstr( gl_config.extensions_string, "GL_SGIS_generate_mipmap" ) ) { VID_Printf(PRINT_ALL, "...using GL_SGIS_generate_mipmap\n"); gl_state.sgis_mipmap=true; } else { VID_Printf(PRINT_ALL, "...GL_SGIS_generate_mipmap not found\n"); gl_state.sgis_mipmap=false; } // Heffo - ARB Texture Compression if ( strstr( gl_config.extensions_string, "GL_ARB_texture_compression" ) ) { if(!gl_ext_texture_compression->value) { VID_Printf(PRINT_ALL, "...ignoring GL_ARB_texture_compression\n"); gl_state.texture_compression = false; } else { VID_Printf(PRINT_ALL, "...using GL_ARB_texture_compression\n"); gl_state.texture_compression = true; } } else { VID_Printf(PRINT_ALL, "...GL_ARB_texture_compression not found\n"); gl_state.texture_compression = false; Cvar_Set("gl_ext_texture_compression", "0"); } GL_SetDefaultState(); // draw our stereo patterns #if 0 // commented out until H3D pays us the money they owe us GL_DrawStereoPattern(); #endif GL_InitImages (); Mod_Init (); R_InitParticleTexture (); R_DrawInitLocal (); ResetDSTTex (); // reset shader warp texture R_InitFogVars(); // reset fog variables err = qglGetError(); if ( err != GL_NO_ERROR ) VID_Printf (PRINT_ALL, "glGetError() = 0x%x\n", err); return true; } /* =============== R_Shutdown =============== */ void R_Shutdown (void) { Cmd_RemoveCommand ("modellist"); Cmd_RemoveCommand ("screenshot"); Cmd_RemoveCommand ("imagelist"); Cmd_RemoveCommand ("gl_strings"); // Knightmare- Free saveshot buffer #ifdef __linux__ if (saveshotdata) { free(saveshotdata); saveshotdata = NULL; } #else if (saveshotdata) free(saveshotdata); #endif Mod_FreeAll (); GL_ShutdownImages (); /* ** shut down OS specific OpenGL stuff like contexts, etc. */ GLimp_Shutdown(); /* ** shutdown our QGL subsystem */ QGL_Shutdown(); } /* @@@@@@@@@@@@@@@@@@@@@ R_BeginFrame @@@@@@@@@@@@@@@@@@@@@ */ void UpdateGammaRamp (void); //Knightmare added void RefreshFont (void); void R_BeginFrame( float camera_separation ) { gl_state.camera_separation = camera_separation; // Knightmare- added Psychospaz's console font size option if (con_font->modified) RefreshFont (); if (con_font_size->modified) { if (con_font_size->value<8) Cvar_Set( "con_font_size", "8" ); else if (con_font_size->value>32) Cvar_Set( "con_font_size", "32" ); con_font_size->modified = false; } // end Knightmare /* ** change modes if necessary */ if ( gl_mode->modified || vid_fullscreen->modified ) { // FIXME: only restart if CDS is required cvar_t *ref; #ifdef _WIN32 ref = Cvar_Get ("vid_ref", "gl", 0); #else ref = Cvar_Get ("vid_ref", "kmglx", 0); #endif ref->modified = true; } if ( gl_log->modified ) { GLimp_EnableLogging( gl_log->value ); gl_log->modified = false; } if ( gl_log->value ) { GLimp_LogNewFrame(); } /* ** update 3Dfx gamma -- it is expected that a user will do a vid_restart ** after tweaking this value */ if ( vid_gamma->modified ) { vid_gamma->modified = false; #ifndef _WIN32 if ( gl_state.gammaramp ) { UpdateGammaRamp (); } else #endif if ( gl_config.renderer & ( GL_RENDERER_VOODOO ) ) { char envbuffer[1024]; float g; g = 2.00 * ( 0.8 - ( vid_gamma->value - 0.5 ) ) + 1.0F; Com_sprintf( envbuffer, sizeof(envbuffer), "SSTV2_GAMMA=%f", g ); putenv( envbuffer ); Com_sprintf( envbuffer, sizeof(envbuffer), "SST_GAMMA=%f", g ); putenv( envbuffer ); } #ifdef _WIN32 UpdateGammaRamp (); #endif } GLimp_BeginFrame( camera_separation ); /* ** go into 2D mode */ qglViewport (0,0, vid.width, vid.height); qglMatrixMode(GL_PROJECTION); qglLoadIdentity (); qglOrtho (0, vid.width, vid.height, 0, -99999, 99999); qglMatrixMode(GL_MODELVIEW); qglLoadIdentity (); qglDisable (GL_DEPTH_TEST); qglDisable (GL_CULL_FACE); qglDisable (GL_BLEND); qglEnable (GL_ALPHA_TEST); qglColor4f (1,1,1,1); /* ** draw buffer stuff */ if ( gl_drawbuffer->modified ) { gl_drawbuffer->modified = false; if ( gl_state.camera_separation == 0 || !gl_state.stereo_enabled ) { if ( Q_stricmp( gl_drawbuffer->string, "GL_FRONT" ) == 0 ) qglDrawBuffer( GL_FRONT ); else qglDrawBuffer( GL_BACK ); } } /* ** texturemode stuff */ if ( gl_texturemode->modified ) { GL_TextureMode( gl_texturemode->string ); gl_texturemode->modified = false; } if ( gl_texturealphamode->modified ) { GL_TextureAlphaMode( gl_texturealphamode->string ); gl_texturealphamode->modified = false; } if ( gl_texturesolidmode->modified ) { GL_TextureSolidMode( gl_texturesolidmode->string ); gl_texturesolidmode->modified = false; } /* ** swapinterval stuff */ GL_UpdateSwapInterval(); // // clear screen if desired // R_Clear (); } /* ============= R_SetPalette ============= */ unsigned r_rawpalette[256]; void R_SetPalette ( const unsigned char *palette) { int i; byte *rp = ( byte * ) r_rawpalette; if ( palette ) { for ( i = 0; i < 256; i++ ) { rp[i*4+0] = palette[i*3+0]; rp[i*4+1] = palette[i*3+1]; rp[i*4+2] = palette[i*3+2]; rp[i*4+3] = 0xff; } } else { for ( i = 0; i < 256; i++ ) { rp[i*4+0] = d_8to24table[i] & 0xff; rp[i*4+1] = ( d_8to24table[i] >> 8 ) & 0xff; rp[i*4+2] = ( d_8to24table[i] >> 16 ) & 0xff; rp[i*4+3] = 0xff; } } //GL_SetTexturePalette( r_rawpalette ); qglClearColor (0,0,0,0); qglClear (GL_COLOR_BUFFER_BIT); qglClearColor (1,0, 0.5 , 0.5); }