2 ===========================================================================
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
26 ===========================================================================
29 #include "../idlib/precompiled.h"
34 // Vista OpenGL wrapper check
36 #include "../sys/win32/win_local.h"
39 // functions that are not called every frame
43 static void GfxInfo_f( void );
45 const char *r_rendererArgs[] = { "best", "arb", "arb2", "Cg", "exp", "nv10", "nv20", "r200", NULL };
47 idCVar r_inhibitFragmentProgram( "r_inhibitFragmentProgram", "0", CVAR_RENDERER | CVAR_BOOL, "ignore the fragment program extension" );
48 idCVar r_glDriver( "r_glDriver", "", CVAR_RENDERER, "\"opengl32\", etc." );
49 idCVar r_useLightPortalFlow( "r_useLightPortalFlow", "1", CVAR_RENDERER | CVAR_BOOL, "use a more precise area reference determination" );
50 idCVar r_multiSamples( "r_multiSamples", "0", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, "number of antialiasing samples" );
51 idCVar r_mode( "r_mode", "3", CVAR_ARCHIVE | CVAR_RENDERER | CVAR_INTEGER, "video mode number" );
52 idCVar r_displayRefresh( "r_displayRefresh", "0", CVAR_RENDERER | CVAR_INTEGER | CVAR_NOCHEAT, "optional display refresh rate option for vid mode", 0.0f, 200.0f );
53 idCVar r_fullscreen( "r_fullscreen", "1", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_BOOL, "0 = windowed, 1 = full screen" );
54 idCVar r_customWidth( "r_customWidth", "720", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, "custom screen width. set r_mode to -1 to activate" );
55 idCVar r_customHeight( "r_customHeight", "486", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, "custom screen height. set r_mode to -1 to activate" );
56 idCVar r_singleTriangle( "r_singleTriangle", "0", CVAR_RENDERER | CVAR_BOOL, "only draw a single triangle per primitive" );
57 idCVar r_checkBounds( "r_checkBounds", "0", CVAR_RENDERER | CVAR_BOOL, "compare all surface bounds with precalculated ones" );
59 idCVar r_useNV20MonoLights( "r_useNV20MonoLights", "1", CVAR_RENDERER | CVAR_INTEGER, "use pass optimization for mono lights" );
60 idCVar r_useConstantMaterials( "r_useConstantMaterials", "1", CVAR_RENDERER | CVAR_BOOL, "use pre-calculated material registers if possible" );
61 idCVar r_useTripleTextureARB( "r_useTripleTextureARB", "1", CVAR_RENDERER | CVAR_BOOL, "cards with 3+ texture units do a two pass instead of three pass" );
62 idCVar r_useSilRemap( "r_useSilRemap", "1", CVAR_RENDERER | CVAR_BOOL, "consider verts with the same XYZ, but different ST the same for shadows" );
63 idCVar r_useNodeCommonChildren( "r_useNodeCommonChildren", "1", CVAR_RENDERER | CVAR_BOOL, "stop pushing reference bounds early when possible" );
64 idCVar r_useShadowProjectedCull( "r_useShadowProjectedCull", "1", CVAR_RENDERER | CVAR_BOOL, "discard triangles outside light volume before shadowing" );
65 idCVar r_useShadowVertexProgram( "r_useShadowVertexProgram", "1", CVAR_RENDERER | CVAR_BOOL, "do the shadow projection in the vertex program on capable cards" );
66 idCVar r_useShadowSurfaceScissor( "r_useShadowSurfaceScissor", "1", CVAR_RENDERER | CVAR_BOOL, "scissor shadows by the scissor rect of the interaction surfaces" );
67 idCVar r_useInteractionTable( "r_useInteractionTable", "1", CVAR_RENDERER | CVAR_BOOL, "create a full entityDefs * lightDefs table to make finding interactions faster" );
68 idCVar r_useTurboShadow( "r_useTurboShadow", "1", CVAR_RENDERER | CVAR_BOOL, "use the infinite projection with W technique for dynamic shadows" );
69 idCVar r_useTwoSidedStencil( "r_useTwoSidedStencil", "1", CVAR_RENDERER | CVAR_BOOL, "do stencil shadows in one pass with different ops on each side" );
70 idCVar r_useDeferredTangents( "r_useDeferredTangents", "1", CVAR_RENDERER | CVAR_BOOL, "defer tangents calculations after deform" );
71 idCVar r_useCachedDynamicModels( "r_useCachedDynamicModels", "1", CVAR_RENDERER | CVAR_BOOL, "cache snapshots of dynamic models" );
73 idCVar r_useVertexBuffers( "r_useVertexBuffers", "1", CVAR_RENDERER | CVAR_INTEGER, "use ARB_vertex_buffer_object for vertexes", 0, 1, idCmdSystem::ArgCompletion_Integer<0,1> );
74 idCVar r_useIndexBuffers( "r_useIndexBuffers", "0", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, "use ARB_vertex_buffer_object for indexes", 0, 1, idCmdSystem::ArgCompletion_Integer<0,1> );
76 idCVar r_useStateCaching( "r_useStateCaching", "1", CVAR_RENDERER | CVAR_BOOL, "avoid redundant state changes in GL_*() calls" );
77 idCVar r_useInfiniteFarZ( "r_useInfiniteFarZ", "1", CVAR_RENDERER | CVAR_BOOL, "use the no-far-clip-plane trick" );
79 idCVar r_znear( "r_znear", "3", CVAR_RENDERER | CVAR_FLOAT, "near Z clip plane distance", 0.001f, 200.0f );
81 idCVar r_ignoreGLErrors( "r_ignoreGLErrors", "1", CVAR_RENDERER | CVAR_BOOL, "ignore GL errors" );
82 idCVar r_finish( "r_finish", "0", CVAR_RENDERER | CVAR_BOOL, "force a call to glFinish() every frame" );
83 idCVar r_swapInterval( "r_swapInterval", "0", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, "changes wglSwapIntarval" );
85 idCVar r_gamma( "r_gamma", "1", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_FLOAT, "changes gamma tables", 0.5f, 3.0f );
86 idCVar r_brightness( "r_brightness", "1", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_FLOAT, "changes gamma tables", 0.5f, 2.0f );
88 idCVar r_renderer( "r_renderer", "best", CVAR_RENDERER | CVAR_ARCHIVE, "hardware specific renderer path to use", r_rendererArgs, idCmdSystem::ArgCompletion_String<r_rendererArgs> );
90 idCVar r_jitter( "r_jitter", "0", CVAR_RENDERER | CVAR_BOOL, "randomly subpixel jitter the projection matrix" );
92 idCVar r_skipSuppress( "r_skipSuppress", "0", CVAR_RENDERER | CVAR_BOOL, "ignore the per-view suppressions" );
93 idCVar r_skipPostProcess( "r_skipPostProcess", "0", CVAR_RENDERER | CVAR_BOOL, "skip all post-process renderings" );
94 idCVar r_skipLightScale( "r_skipLightScale", "0", CVAR_RENDERER | CVAR_BOOL, "don't do any post-interaction light scaling, makes things dim on low-dynamic range cards" );
95 idCVar r_skipInteractions( "r_skipInteractions", "0", CVAR_RENDERER | CVAR_BOOL, "skip all light/surface interaction drawing" );
96 idCVar r_skipDynamicTextures( "r_skipDynamicTextures", "0", CVAR_RENDERER | CVAR_BOOL, "don't dynamically create textures" );
97 idCVar r_skipCopyTexture( "r_skipCopyTexture", "0", CVAR_RENDERER | CVAR_BOOL, "do all rendering, but don't actually copyTexSubImage2D" );
98 idCVar r_skipBackEnd( "r_skipBackEnd", "0", CVAR_RENDERER | CVAR_BOOL, "don't draw anything" );
99 idCVar r_skipRender( "r_skipRender", "0", CVAR_RENDERER | CVAR_BOOL, "skip 3D rendering, but pass 2D" );
100 idCVar r_skipRenderContext( "r_skipRenderContext", "0", CVAR_RENDERER | CVAR_BOOL, "NULL the rendering context during backend 3D rendering" );
101 idCVar r_skipTranslucent( "r_skipTranslucent", "0", CVAR_RENDERER | CVAR_BOOL, "skip the translucent interaction rendering" );
102 idCVar r_skipAmbient( "r_skipAmbient", "0", CVAR_RENDERER | CVAR_BOOL, "bypasses all non-interaction drawing" );
103 idCVar r_skipNewAmbient( "r_skipNewAmbient", "0", CVAR_RENDERER | CVAR_BOOL | CVAR_ARCHIVE, "bypasses all vertex/fragment program ambient drawing" );
104 idCVar r_skipBlendLights( "r_skipBlendLights", "0", CVAR_RENDERER | CVAR_BOOL, "skip all blend lights" );
105 idCVar r_skipFogLights( "r_skipFogLights", "0", CVAR_RENDERER | CVAR_BOOL, "skip all fog lights" );
106 idCVar r_skipDeforms( "r_skipDeforms", "0", CVAR_RENDERER | CVAR_BOOL, "leave all deform materials in their original state" );
107 idCVar r_skipFrontEnd( "r_skipFrontEnd", "0", CVAR_RENDERER | CVAR_BOOL, "bypasses all front end work, but 2D gui rendering still draws" );
108 idCVar r_skipUpdates( "r_skipUpdates", "0", CVAR_RENDERER | CVAR_BOOL, "1 = don't accept any entity or light updates, making everything static" );
109 idCVar r_skipOverlays( "r_skipOverlays", "0", CVAR_RENDERER | CVAR_BOOL, "skip overlay surfaces" );
110 idCVar r_skipSpecular( "r_skipSpecular", "0", CVAR_RENDERER | CVAR_BOOL | CVAR_CHEAT | CVAR_ARCHIVE, "use black for specular1" );
111 idCVar r_skipBump( "r_skipBump", "0", CVAR_RENDERER | CVAR_BOOL | CVAR_ARCHIVE, "uses a flat surface instead of the bump map" );
112 idCVar r_skipDiffuse( "r_skipDiffuse", "0", CVAR_RENDERER | CVAR_BOOL, "use black for diffuse" );
113 idCVar r_skipROQ( "r_skipROQ", "0", CVAR_RENDERER | CVAR_BOOL, "skip ROQ decoding" );
115 idCVar r_ignore( "r_ignore", "0", CVAR_RENDERER, "used for random debugging without defining new vars" );
116 idCVar r_ignore2( "r_ignore2", "0", CVAR_RENDERER, "used for random debugging without defining new vars" );
117 idCVar r_usePreciseTriangleInteractions( "r_usePreciseTriangleInteractions", "0", CVAR_RENDERER | CVAR_BOOL, "1 = do winding clipping to determine if each ambiguous tri should be lit" );
118 idCVar r_useCulling( "r_useCulling", "2", CVAR_RENDERER | CVAR_INTEGER, "0 = none, 1 = sphere, 2 = sphere + box", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> );
119 idCVar r_useLightCulling( "r_useLightCulling", "3", CVAR_RENDERER | CVAR_INTEGER, "0 = none, 1 = box, 2 = exact clip of polyhedron faces, 3 = also areas", 0, 3, idCmdSystem::ArgCompletion_Integer<0,3> );
120 idCVar r_useLightScissors( "r_useLightScissors", "1", CVAR_RENDERER | CVAR_BOOL, "1 = use custom scissor rectangle for each light" );
121 idCVar r_useClippedLightScissors( "r_useClippedLightScissors", "1", CVAR_RENDERER | CVAR_INTEGER, "0 = full screen when near clipped, 1 = exact when near clipped, 2 = exact always", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> );
122 idCVar r_useEntityCulling( "r_useEntityCulling", "1", CVAR_RENDERER | CVAR_BOOL, "0 = none, 1 = box" );
123 idCVar r_useEntityScissors( "r_useEntityScissors", "0", CVAR_RENDERER | CVAR_BOOL, "1 = use custom scissor rectangle for each entity" );
124 idCVar r_useInteractionCulling( "r_useInteractionCulling", "1", CVAR_RENDERER | CVAR_BOOL, "1 = cull interactions" );
125 idCVar r_useInteractionScissors( "r_useInteractionScissors", "2", CVAR_RENDERER | CVAR_INTEGER, "1 = use a custom scissor rectangle for each shadow interaction, 2 = also crop using portal scissors", -2, 2, idCmdSystem::ArgCompletion_Integer<-2,2> );
126 idCVar r_useShadowCulling( "r_useShadowCulling", "1", CVAR_RENDERER | CVAR_BOOL, "try to cull shadows from partially visible lights" );
127 idCVar r_useFrustumFarDistance( "r_useFrustumFarDistance", "0", CVAR_RENDERER | CVAR_FLOAT, "if != 0 force the view frustum far distance to this distance" );
128 idCVar r_logFile( "r_logFile", "0", CVAR_RENDERER | CVAR_INTEGER, "number of frames to emit GL logs" );
129 idCVar r_clear( "r_clear", "2", CVAR_RENDERER, "force screen clear every frame, 1 = purple, 2 = black, 'r g b' = custom" );
130 idCVar r_offsetFactor( "r_offsetfactor", "0", CVAR_RENDERER | CVAR_FLOAT, "polygon offset parameter" );
131 idCVar r_offsetUnits( "r_offsetunits", "-600", CVAR_RENDERER | CVAR_FLOAT, "polygon offset parameter" );
132 idCVar r_shadowPolygonOffset( "r_shadowPolygonOffset", "-1", CVAR_RENDERER | CVAR_FLOAT, "bias value added to depth test for stencil shadow drawing" );
133 idCVar r_shadowPolygonFactor( "r_shadowPolygonFactor", "0", CVAR_RENDERER | CVAR_FLOAT, "scale value for stencil shadow drawing" );
134 idCVar r_frontBuffer( "r_frontBuffer", "0", CVAR_RENDERER | CVAR_BOOL, "draw to front buffer for debugging" );
135 idCVar r_skipSubviews( "r_skipSubviews", "0", CVAR_RENDERER | CVAR_INTEGER, "1 = don't render any gui elements on surfaces" );
136 idCVar r_skipGuiShaders( "r_skipGuiShaders", "0", CVAR_RENDERER | CVAR_INTEGER, "1 = skip all gui elements on surfaces, 2 = skip drawing but still handle events, 3 = draw but skip events", 0, 3, idCmdSystem::ArgCompletion_Integer<0,3> );
137 idCVar r_skipParticles( "r_skipParticles", "0", CVAR_RENDERER | CVAR_INTEGER, "1 = skip all particle systems", 0, 1, idCmdSystem::ArgCompletion_Integer<0,1> );
138 idCVar r_subviewOnly( "r_subviewOnly", "0", CVAR_RENDERER | CVAR_BOOL, "1 = don't render main view, allowing subviews to be debugged" );
139 idCVar r_shadows( "r_shadows", "1", CVAR_RENDERER | CVAR_BOOL | CVAR_ARCHIVE, "enable shadows" );
140 idCVar r_testARBProgram( "r_testARBProgram", "0", CVAR_RENDERER | CVAR_BOOL, "experiment with vertex/fragment programs" );
141 idCVar r_testGamma( "r_testGamma", "0", CVAR_RENDERER | CVAR_FLOAT, "if > 0 draw a grid pattern to test gamma levels", 0, 195 );
142 idCVar r_testGammaBias( "r_testGammaBias", "0", CVAR_RENDERER | CVAR_FLOAT, "if > 0 draw a grid pattern to test gamma levels" );
143 idCVar r_testStepGamma( "r_testStepGamma", "0", CVAR_RENDERER | CVAR_FLOAT, "if > 0 draw a grid pattern to test gamma levels" );
144 idCVar r_lightScale( "r_lightScale", "2", CVAR_RENDERER | CVAR_FLOAT, "all light intensities are multiplied by this" );
145 idCVar r_lightSourceRadius( "r_lightSourceRadius", "0", CVAR_RENDERER | CVAR_FLOAT, "for soft-shadow sampling" );
146 idCVar r_flareSize( "r_flareSize", "1", CVAR_RENDERER | CVAR_FLOAT, "scale the flare deforms from the material def" );
148 idCVar r_useExternalShadows( "r_useExternalShadows", "1", CVAR_RENDERER | CVAR_INTEGER, "1 = skip drawing caps when outside the light volume, 2 = force to no caps for testing", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> );
149 idCVar r_useOptimizedShadows( "r_useOptimizedShadows", "1", CVAR_RENDERER | CVAR_BOOL, "use the dmap generated static shadow volumes" );
150 idCVar r_useScissor( "r_useScissor", "1", CVAR_RENDERER | CVAR_BOOL, "scissor clip as portals and lights are processed" );
151 idCVar r_useCombinerDisplayLists( "r_useCombinerDisplayLists", "1", CVAR_RENDERER | CVAR_BOOL | CVAR_NOCHEAT, "put all nvidia register combiner programming in display lists" );
152 idCVar r_useDepthBoundsTest( "r_useDepthBoundsTest", "1", CVAR_RENDERER | CVAR_BOOL, "use depth bounds test to reduce shadow fill" );
154 idCVar r_screenFraction( "r_screenFraction", "100", CVAR_RENDERER | CVAR_INTEGER, "for testing fill rate, the resolution of the entire screen can be changed" );
155 idCVar r_demonstrateBug( "r_demonstrateBug", "0", CVAR_RENDERER | CVAR_BOOL, "used during development to show IHV's their problems" );
156 idCVar r_usePortals( "r_usePortals", "1", CVAR_RENDERER | CVAR_BOOL, " 1 = use portals to perform area culling, otherwise draw everything" );
157 idCVar r_singleLight( "r_singleLight", "-1", CVAR_RENDERER | CVAR_INTEGER, "suppress all but one light" );
158 idCVar r_singleEntity( "r_singleEntity", "-1", CVAR_RENDERER | CVAR_INTEGER, "suppress all but one entity" );
159 idCVar r_singleSurface( "r_singleSurface", "-1", CVAR_RENDERER | CVAR_INTEGER, "suppress all but one surface on each entity" );
160 idCVar r_singleArea( "r_singleArea", "0", CVAR_RENDERER | CVAR_BOOL, "only draw the portal area the view is actually in" );
161 idCVar r_forceLoadImages( "r_forceLoadImages", "0", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_BOOL, "draw all images to screen after registration" );
162 idCVar r_orderIndexes( "r_orderIndexes", "1", CVAR_RENDERER | CVAR_BOOL, "perform index reorganization to optimize vertex use" );
163 idCVar r_lightAllBackFaces( "r_lightAllBackFaces", "0", CVAR_RENDERER | CVAR_BOOL, "light all the back faces, even when they would be shadowed" );
165 // visual debugging info
166 idCVar r_showPortals( "r_showPortals", "0", CVAR_RENDERER | CVAR_BOOL, "draw portal outlines in color based on passed / not passed" );
167 idCVar r_showUnsmoothedTangents( "r_showUnsmoothedTangents", "0", CVAR_RENDERER | CVAR_BOOL, "if 1, put all nvidia register combiner programming in display lists" );
168 idCVar r_showSilhouette( "r_showSilhouette", "0", CVAR_RENDERER | CVAR_BOOL, "highlight edges that are casting shadow planes" );
169 idCVar r_showVertexColor( "r_showVertexColor", "0", CVAR_RENDERER | CVAR_BOOL, "draws all triangles with the solid vertex color" );
170 idCVar r_showUpdates( "r_showUpdates", "0", CVAR_RENDERER | CVAR_BOOL, "report entity and light updates and ref counts" );
171 idCVar r_showDemo( "r_showDemo", "0", CVAR_RENDERER | CVAR_BOOL, "report reads and writes to the demo file" );
172 idCVar r_showDynamic( "r_showDynamic", "0", CVAR_RENDERER | CVAR_BOOL, "report stats on dynamic surface generation" );
173 idCVar r_showLightScale( "r_showLightScale", "0", CVAR_RENDERER | CVAR_BOOL, "report the scale factor applied to drawing for overbrights" );
174 idCVar r_showDefs( "r_showDefs", "0", CVAR_RENDERER | CVAR_BOOL, "report the number of modeDefs and lightDefs in view" );
175 idCVar r_showTrace( "r_showTrace", "0", CVAR_RENDERER | CVAR_INTEGER, "show the intersection of an eye trace with the world", idCmdSystem::ArgCompletion_Integer<0,2> );
176 idCVar r_showIntensity( "r_showIntensity", "0", CVAR_RENDERER | CVAR_BOOL, "draw the screen colors based on intensity, red = 0, green = 128, blue = 255" );
177 idCVar r_showImages( "r_showImages", "0", CVAR_RENDERER | CVAR_INTEGER, "1 = show all images instead of rendering, 2 = show in proportional size", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> );
178 idCVar r_showSmp( "r_showSmp", "0", CVAR_RENDERER | CVAR_BOOL, "show which end (front or back) is blocking" );
179 idCVar r_showLights( "r_showLights", "0", CVAR_RENDERER | CVAR_INTEGER, "1 = just print volumes numbers, highlighting ones covering the view, 2 = also draw planes of each volume, 3 = also draw edges of each volume", 0, 3, idCmdSystem::ArgCompletion_Integer<0,3> );
180 idCVar r_showShadows( "r_showShadows", "0", CVAR_RENDERER | CVAR_INTEGER, "1 = visualize the stencil shadow volumes, 2 = draw filled in", 0, 3, idCmdSystem::ArgCompletion_Integer<0,3> );
181 idCVar r_showShadowCount( "r_showShadowCount", "0", CVAR_RENDERER | CVAR_INTEGER, "colors screen based on shadow volume depth complexity, >= 2 = print overdraw count based on stencil index values, 3 = only show turboshadows, 4 = only show static shadows", 0, 4, idCmdSystem::ArgCompletion_Integer<0,4> );
182 idCVar r_showLightScissors( "r_showLightScissors", "0", CVAR_RENDERER | CVAR_BOOL, "show light scissor rectangles" );
183 idCVar r_showEntityScissors( "r_showEntityScissors", "0", CVAR_RENDERER | CVAR_BOOL, "show entity scissor rectangles" );
184 idCVar r_showInteractionFrustums( "r_showInteractionFrustums", "0", CVAR_RENDERER | CVAR_INTEGER, "1 = show a frustum for each interaction, 2 = also draw lines to light origin, 3 = also draw entity bbox", 0, 3, idCmdSystem::ArgCompletion_Integer<0,3> );
185 idCVar r_showInteractionScissors( "r_showInteractionScissors", "0", CVAR_RENDERER | CVAR_INTEGER, "1 = show screen rectangle which contains the interaction frustum, 2 = also draw construction lines", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> );
186 idCVar r_showLightCount( "r_showLightCount", "0", CVAR_RENDERER | CVAR_INTEGER, "1 = colors surfaces based on light count, 2 = also count everything through walls, 3 = also print overdraw", 0, 3, idCmdSystem::ArgCompletion_Integer<0,3> );
187 idCVar r_showViewEntitys( "r_showViewEntitys", "0", CVAR_RENDERER | CVAR_INTEGER, "1 = displays the bounding boxes of all view models, 2 = print index numbers" );
188 idCVar r_showTris( "r_showTris", "0", CVAR_RENDERER | CVAR_INTEGER, "enables wireframe rendering of the world, 1 = only draw visible ones, 2 = draw all front facing, 3 = draw all", 0, 3, idCmdSystem::ArgCompletion_Integer<0,3> );
189 idCVar r_showSurfaceInfo( "r_showSurfaceInfo", "0", CVAR_RENDERER | CVAR_BOOL, "show surface material name under crosshair" );
190 idCVar r_showNormals( "r_showNormals", "0", CVAR_RENDERER | CVAR_FLOAT, "draws wireframe normals" );
191 idCVar r_showMemory( "r_showMemory", "0", CVAR_RENDERER | CVAR_BOOL, "print frame memory utilization" );
192 idCVar r_showCull( "r_showCull", "0", CVAR_RENDERER | CVAR_BOOL, "report sphere and box culling stats" );
193 idCVar r_showInteractions( "r_showInteractions", "0", CVAR_RENDERER | CVAR_BOOL, "report interaction generation activity" );
194 idCVar r_showDepth( "r_showDepth", "0", CVAR_RENDERER | CVAR_BOOL, "display the contents of the depth buffer and the depth range" );
195 idCVar r_showSurfaces( "r_showSurfaces", "0", CVAR_RENDERER | CVAR_BOOL, "report surface/light/shadow counts" );
196 idCVar r_showPrimitives( "r_showPrimitives", "0", CVAR_RENDERER | CVAR_INTEGER, "report drawsurf/index/vertex counts" );
197 idCVar r_showEdges( "r_showEdges", "0", CVAR_RENDERER | CVAR_BOOL, "draw the sil edges" );
198 idCVar r_showTexturePolarity( "r_showTexturePolarity", "0", CVAR_RENDERER | CVAR_BOOL, "shade triangles by texture area polarity" );
199 idCVar r_showTangentSpace( "r_showTangentSpace", "0", CVAR_RENDERER | CVAR_INTEGER, "shade triangles by tangent space, 1 = use 1st tangent vector, 2 = use 2nd tangent vector, 3 = use normal vector", 0, 3, idCmdSystem::ArgCompletion_Integer<0,3> );
200 idCVar r_showDominantTri( "r_showDominantTri", "0", CVAR_RENDERER | CVAR_BOOL, "draw lines from vertexes to center of dominant triangles" );
201 idCVar r_showAlloc( "r_showAlloc", "0", CVAR_RENDERER | CVAR_BOOL, "report alloc/free counts" );
202 idCVar r_showTextureVectors( "r_showTextureVectors", "0", CVAR_RENDERER | CVAR_FLOAT, " if > 0 draw each triangles texture (tangent) vectors" );
203 idCVar r_showOverDraw( "r_showOverDraw", "0", CVAR_RENDERER | CVAR_INTEGER, "1 = geometry overdraw, 2 = light interaction overdraw, 3 = geometry and light interaction overdraw", 0, 3, idCmdSystem::ArgCompletion_Integer<0,3> );
205 idCVar r_lockSurfaces( "r_lockSurfaces", "0", CVAR_RENDERER | CVAR_BOOL, "allow moving the view point without changing the composition of the scene, including culling" );
206 idCVar r_useEntityCallbacks( "r_useEntityCallbacks", "1", CVAR_RENDERER | CVAR_BOOL, "if 0, issue the callback immediately at update time, rather than defering" );
208 idCVar r_showSkel( "r_showSkel", "0", CVAR_RENDERER | CVAR_INTEGER, "draw the skeleton when model animates, 1 = draw model with skeleton, 2 = draw skeleton only", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> );
209 idCVar r_jointNameScale( "r_jointNameScale", "0.02", CVAR_RENDERER | CVAR_FLOAT, "size of joint names when r_showskel is set to 1" );
210 idCVar r_jointNameOffset( "r_jointNameOffset", "0.5", CVAR_RENDERER | CVAR_FLOAT, "offset of joint names when r_showskel is set to 1" );
212 idCVar r_cgVertexProfile( "r_cgVertexProfile", "best", CVAR_RENDERER | CVAR_ARCHIVE, "arbvp1, vp20, vp30" );
213 idCVar r_cgFragmentProfile( "r_cgFragmentProfile", "best", CVAR_RENDERER | CVAR_ARCHIVE, "arbfp1, fp30" );
215 idCVar r_debugLineDepthTest( "r_debugLineDepthTest", "0", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_BOOL, "perform depth test on debug lines" );
216 idCVar r_debugLineWidth( "r_debugLineWidth", "1", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_BOOL, "width of debug lines" );
217 idCVar r_debugArrowStep( "r_debugArrowStep", "120", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, "step size of arrow cone line rotation in degrees", 0, 120 );
218 idCVar r_debugPolygonFilled( "r_debugPolygonFilled", "1", CVAR_RENDERER | CVAR_BOOL, "draw a filled polygon" );
220 idCVar r_materialOverride( "r_materialOverride", "", CVAR_RENDERER, "overrides all materials", idCmdSystem::ArgCompletion_Decl<DECL_MATERIAL> );
222 idCVar r_debugRenderToTexture( "r_debugRenderToTexture", "0", CVAR_RENDERER | CVAR_INTEGER, "" );
224 void ( APIENTRY * qglMultiTexCoord2fARB )( GLenum texture, GLfloat s, GLfloat t );
225 void ( APIENTRY * qglMultiTexCoord2fvARB )( GLenum texture, GLfloat *st );
226 void ( APIENTRY * qglActiveTextureARB )( GLenum texture );
227 void ( APIENTRY * qglClientActiveTextureARB )( GLenum texture );
229 void ( APIENTRY *qglCombinerParameterfvNV )( GLenum pname, const GLfloat *params );
230 void ( APIENTRY *qglCombinerParameterivNV )( GLenum pname, const GLint *params );
231 void ( APIENTRY *qglCombinerParameterfNV )( GLenum pname, const GLfloat param );
232 void ( APIENTRY *qglCombinerParameteriNV )( GLenum pname, const GLint param );
233 void ( APIENTRY *qglCombinerInputNV )( GLenum stage, GLenum portion, GLenum variable, GLenum input,
234 GLenum mapping, GLenum componentUsage );
235 void ( APIENTRY *qglCombinerOutputNV )( GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput,
236 GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct,
237 GLboolean cdDotProduct, GLboolean muxSum );
238 void ( APIENTRY *qglFinalCombinerInputNV )( GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage );
241 void (APIENTRY *qglVertexArrayRangeNV)( GLsizei length, void *pointer );
243 // http://oss.sgi.com/projects/ogl-sample/registry/NV/vertex_array_range.txt
244 // since APIs are the same anyway, let's be wgl/glX agnostic
245 void *(APIENTRY *qAllocateMemoryNV)( GLsizei size, float readFrequency, float writeFrequency, float priority);
246 void (APIENTRY *qFreeMemoryNV)( void *pointer );
247 #ifdef GLX_VERSION_1_1
248 #define Q_ALLOCATE_MEMORY_NV "glXAllocateMemoryNV"
249 #define Q_FREE_MEMORY_NV "glXFreeMemoryNV"
251 #define Q_ALLOCATE_MEMORY_NV "wglAllocateMemoryNV"
252 #define Q_FREE_MEMORY_NV "wglFreeMemoryNV"
255 void (APIENTRY *qglTexImage3D)(GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *);
257 void (APIENTRY * qglColorTableEXT)( int, int, int, int, int, const void * );
260 // ATI_fragment_shader
261 PFNGLGENFRAGMENTSHADERSATIPROC qglGenFragmentShadersATI;
262 PFNGLBINDFRAGMENTSHADERATIPROC qglBindFragmentShaderATI;
263 PFNGLDELETEFRAGMENTSHADERATIPROC qglDeleteFragmentShaderATI;
264 PFNGLBEGINFRAGMENTSHADERATIPROC qglBeginFragmentShaderATI;
265 PFNGLENDFRAGMENTSHADERATIPROC qglEndFragmentShaderATI;
266 PFNGLPASSTEXCOORDATIPROC qglPassTexCoordATI;
267 PFNGLSAMPLEMAPATIPROC qglSampleMapATI;
268 PFNGLCOLORFRAGMENTOP1ATIPROC qglColorFragmentOp1ATI;
269 PFNGLCOLORFRAGMENTOP2ATIPROC qglColorFragmentOp2ATI;
270 PFNGLCOLORFRAGMENTOP3ATIPROC qglColorFragmentOp3ATI;
271 PFNGLALPHAFRAGMENTOP1ATIPROC qglAlphaFragmentOp1ATI;
272 PFNGLALPHAFRAGMENTOP2ATIPROC qglAlphaFragmentOp2ATI;
273 PFNGLALPHAFRAGMENTOP3ATIPROC qglAlphaFragmentOp3ATI;
274 PFNGLSETFRAGMENTSHADERCONSTANTATIPROC qglSetFragmentShaderConstantATI;
276 // EXT_stencil_two_side
277 PFNGLACTIVESTENCILFACEEXTPROC qglActiveStencilFaceEXT;
279 // ATI_separate_stencil
280 PFNGLSTENCILOPSEPARATEATIPROC qglStencilOpSeparateATI;
281 PFNGLSTENCILFUNCSEPARATEATIPROC qglStencilFuncSeparateATI;
283 // ARB_texture_compression
284 PFNGLCOMPRESSEDTEXIMAGE2DARBPROC qglCompressedTexImage2DARB;
285 PFNGLGETCOMPRESSEDTEXIMAGEARBPROC qglGetCompressedTexImageARB;
287 // ARB_vertex_buffer_object
288 PFNGLBINDBUFFERARBPROC qglBindBufferARB;
289 PFNGLDELETEBUFFERSARBPROC qglDeleteBuffersARB;
290 PFNGLGENBUFFERSARBPROC qglGenBuffersARB;
291 PFNGLISBUFFERARBPROC qglIsBufferARB;
292 PFNGLBUFFERDATAARBPROC qglBufferDataARB;
293 PFNGLBUFFERSUBDATAARBPROC qglBufferSubDataARB;
294 PFNGLGETBUFFERSUBDATAARBPROC qglGetBufferSubDataARB;
295 PFNGLMAPBUFFERARBPROC qglMapBufferARB;
296 PFNGLUNMAPBUFFERARBPROC qglUnmapBufferARB;
297 PFNGLGETBUFFERPARAMETERIVARBPROC qglGetBufferParameterivARB;
298 PFNGLGETBUFFERPOINTERVARBPROC qglGetBufferPointervARB;
300 // ARB_vertex_program / ARB_fragment_program
301 PFNGLVERTEXATTRIBPOINTERARBPROC qglVertexAttribPointerARB;
302 PFNGLENABLEVERTEXATTRIBARRAYARBPROC qglEnableVertexAttribArrayARB;
303 PFNGLDISABLEVERTEXATTRIBARRAYARBPROC qglDisableVertexAttribArrayARB;
304 PFNGLPROGRAMSTRINGARBPROC qglProgramStringARB;
305 PFNGLBINDPROGRAMARBPROC qglBindProgramARB;
306 PFNGLGENPROGRAMSARBPROC qglGenProgramsARB;
307 PFNGLPROGRAMENVPARAMETER4FVARBPROC qglProgramEnvParameter4fvARB;
308 PFNGLPROGRAMLOCALPARAMETER4FVARBPROC qglProgramLocalParameter4fvARB;
310 // GL_EXT_depth_bounds_test
311 PFNGLDEPTHBOUNDSEXTPROC qglDepthBoundsEXT;
318 bool R_CheckExtension( char *name ) {
319 if ( !strstr( glConfig.extensions_string, name ) ) {
320 common->Printf( "X..%s not found\n", name );
324 common->Printf( "...using %s\n", name );
330 R_CheckPortableExtensions
334 static void R_CheckPortableExtensions( void ) {
335 glConfig.glVersion = atof( glConfig.version_string );
337 // GL_ARB_multitexture
338 glConfig.multitextureAvailable = R_CheckExtension( "GL_ARB_multitexture" );
339 if ( glConfig.multitextureAvailable ) {
340 qglMultiTexCoord2fARB = (void(APIENTRY *)(GLenum, GLfloat, GLfloat))GLimp_ExtensionPointer( "glMultiTexCoord2fARB" );
341 qglMultiTexCoord2fvARB = (void(APIENTRY *)(GLenum, GLfloat *))GLimp_ExtensionPointer( "glMultiTexCoord2fvARB" );
342 qglActiveTextureARB = (void(APIENTRY *)(GLenum))GLimp_ExtensionPointer( "glActiveTextureARB" );
343 qglClientActiveTextureARB = (void(APIENTRY *)(GLenum))GLimp_ExtensionPointer( "glClientActiveTextureARB" );
344 qglGetIntegerv( GL_MAX_TEXTURE_UNITS_ARB, (GLint *)&glConfig.maxTextureUnits );
345 if ( glConfig.maxTextureUnits > MAX_MULTITEXTURE_UNITS ) {
346 glConfig.maxTextureUnits = MAX_MULTITEXTURE_UNITS;
348 if ( glConfig.maxTextureUnits < 2 ) {
349 glConfig.multitextureAvailable = false; // shouldn't ever happen
351 qglGetIntegerv( GL_MAX_TEXTURE_COORDS_ARB, (GLint *)&glConfig.maxTextureCoords );
352 qglGetIntegerv( GL_MAX_TEXTURE_IMAGE_UNITS_ARB, (GLint *)&glConfig.maxTextureImageUnits );
355 // GL_ARB_texture_env_combine
356 glConfig.textureEnvCombineAvailable = R_CheckExtension( "GL_ARB_texture_env_combine" );
358 // GL_ARB_texture_cube_map
359 glConfig.cubeMapAvailable = R_CheckExtension( "GL_ARB_texture_cube_map" );
361 // GL_ARB_texture_env_dot3
362 glConfig.envDot3Available = R_CheckExtension( "GL_ARB_texture_env_dot3" );
364 // GL_ARB_texture_env_add
365 glConfig.textureEnvAddAvailable = R_CheckExtension( "GL_ARB_texture_env_add" );
367 // GL_ARB_texture_non_power_of_two
368 glConfig.textureNonPowerOfTwoAvailable = R_CheckExtension( "GL_ARB_texture_non_power_of_two" );
370 // GL_ARB_texture_compression + GL_S3_s3tc
371 // DRI drivers may have GL_ARB_texture_compression but no GL_EXT_texture_compression_s3tc
372 if ( R_CheckExtension( "GL_ARB_texture_compression" ) && R_CheckExtension( "GL_EXT_texture_compression_s3tc" ) ) {
373 glConfig.textureCompressionAvailable = true;
374 qglCompressedTexImage2DARB = (PFNGLCOMPRESSEDTEXIMAGE2DARBPROC)GLimp_ExtensionPointer( "glCompressedTexImage2DARB" );
375 qglGetCompressedTexImageARB = (PFNGLGETCOMPRESSEDTEXIMAGEARBPROC)GLimp_ExtensionPointer( "glGetCompressedTexImageARB" );
377 glConfig.textureCompressionAvailable = false;
380 // GL_EXT_texture_filter_anisotropic
381 glConfig.anisotropicAvailable = R_CheckExtension( "GL_EXT_texture_filter_anisotropic" );
382 if ( glConfig.anisotropicAvailable ) {
383 qglGetFloatv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &glConfig.maxTextureAnisotropy );
384 common->Printf( " maxTextureAnisotropy: %f\n", glConfig.maxTextureAnisotropy );
386 glConfig.maxTextureAnisotropy = 1;
389 // GL_EXT_texture_lod_bias
390 // The actual extension is broken as specificed, storing the state in the texture unit instead
391 // of the texture object. The behavior in GL 1.4 is the behavior we use.
392 if ( glConfig.glVersion >= 1.4 || R_CheckExtension( "GL_EXT_texture_lod" ) ) {
393 common->Printf( "...using %s\n", "GL_1.4_texture_lod_bias" );
394 glConfig.textureLODBiasAvailable = true;
396 common->Printf( "X..%s not found\n", "GL_1.4_texture_lod_bias" );
397 glConfig.textureLODBiasAvailable = false;
400 // GL_EXT_shared_texture_palette
401 glConfig.sharedTexturePaletteAvailable = R_CheckExtension( "GL_EXT_shared_texture_palette" );
402 if ( glConfig.sharedTexturePaletteAvailable ) {
403 qglColorTableEXT = ( void ( APIENTRY * ) ( int, int, int, int, int, const void * ) ) GLimp_ExtensionPointer( "glColorTableEXT" );
406 // GL_EXT_texture3D (not currently used for anything)
407 glConfig.texture3DAvailable = R_CheckExtension( "GL_EXT_texture3D" );
408 if ( glConfig.texture3DAvailable ) {
410 (void (APIENTRY *)(GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *) )
411 GLimp_ExtensionPointer( "glTexImage3D" );
415 // This isn't very important, but some pathological case might cause a clamp error and give a shadow bug.
416 // Nvidia also believes that future hardware may be able to run faster with this enabled to avoid the
417 // serialization of clamping.
418 if ( R_CheckExtension( "GL_EXT_stencil_wrap" ) ) {
419 tr.stencilIncr = GL_INCR_WRAP_EXT;
420 tr.stencilDecr = GL_DECR_WRAP_EXT;
422 tr.stencilIncr = GL_INCR;
423 tr.stencilDecr = GL_DECR;
426 // GL_NV_register_combiners
427 glConfig.registerCombinersAvailable = R_CheckExtension( "GL_NV_register_combiners" );
428 if ( glConfig.registerCombinersAvailable ) {
429 qglCombinerParameterfvNV = (void (APIENTRY *)( GLenum pname, const GLfloat *params ))
430 GLimp_ExtensionPointer( "glCombinerParameterfvNV" );
431 qglCombinerParameterivNV = (void (APIENTRY *)( GLenum pname, const GLint *params ))
432 GLimp_ExtensionPointer( "glCombinerParameterivNV" );
433 qglCombinerParameterfNV = (void (APIENTRY *)( GLenum pname, const GLfloat param ))
434 GLimp_ExtensionPointer( "glCombinerParameterfNV" );
435 qglCombinerParameteriNV = (void (APIENTRY *)( GLenum pname, const GLint param ))
436 GLimp_ExtensionPointer( "glCombinerParameteriNV" );
437 qglCombinerInputNV = (void (APIENTRY *)( GLenum stage, GLenum portion, GLenum variable, GLenum input,
438 GLenum mapping, GLenum componentUsage ))
439 GLimp_ExtensionPointer( "glCombinerInputNV" );
440 qglCombinerOutputNV = (void (APIENTRY *)( GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput,
441 GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct,
442 GLboolean cdDotProduct, GLboolean muxSum ))
443 GLimp_ExtensionPointer( "glCombinerOutputNV" );
444 qglFinalCombinerInputNV = (void (APIENTRY *)( GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage ))
445 GLimp_ExtensionPointer( "glFinalCombinerInputNV" );
448 // GL_EXT_stencil_two_side
449 glConfig.twoSidedStencilAvailable = R_CheckExtension( "GL_EXT_stencil_two_side" );
450 if ( glConfig.twoSidedStencilAvailable ) {
451 qglActiveStencilFaceEXT = (PFNGLACTIVESTENCILFACEEXTPROC)GLimp_ExtensionPointer( "glActiveStencilFaceEXT" );
453 glConfig.atiTwoSidedStencilAvailable = R_CheckExtension( "GL_ATI_separate_stencil" );
454 if ( glConfig.atiTwoSidedStencilAvailable ) {
455 qglStencilFuncSeparateATI = (PFNGLSTENCILFUNCSEPARATEATIPROC)GLimp_ExtensionPointer( "glStencilFuncSeparateATI" );
456 qglStencilOpSeparateATI = (PFNGLSTENCILOPSEPARATEATIPROC)GLimp_ExtensionPointer( "glStencilOpSeparateATI" );
460 // GL_ATI_fragment_shader
461 glConfig.atiFragmentShaderAvailable = R_CheckExtension( "GL_ATI_fragment_shader" );
462 if (! glConfig.atiFragmentShaderAvailable ) {
463 // only on OSX: ATI_fragment_shader is faked through ATI_text_fragment_shader (macosx_glimp.cpp)
464 glConfig.atiFragmentShaderAvailable = R_CheckExtension( "GL_ATI_text_fragment_shader" );
466 if ( glConfig.atiFragmentShaderAvailable ) {
467 qglGenFragmentShadersATI = (PFNGLGENFRAGMENTSHADERSATIPROC)GLimp_ExtensionPointer( "glGenFragmentShadersATI" );
468 qglBindFragmentShaderATI = (PFNGLBINDFRAGMENTSHADERATIPROC)GLimp_ExtensionPointer( "glBindFragmentShaderATI" );
469 qglDeleteFragmentShaderATI = (PFNGLDELETEFRAGMENTSHADERATIPROC)GLimp_ExtensionPointer( "glDeleteFragmentShaderATI" );
470 qglBeginFragmentShaderATI = (PFNGLBEGINFRAGMENTSHADERATIPROC)GLimp_ExtensionPointer( "glBeginFragmentShaderATI" );
471 qglEndFragmentShaderATI = (PFNGLENDFRAGMENTSHADERATIPROC)GLimp_ExtensionPointer( "glEndFragmentShaderATI" );
472 qglPassTexCoordATI = (PFNGLPASSTEXCOORDATIPROC)GLimp_ExtensionPointer( "glPassTexCoordATI" );
473 qglSampleMapATI = (PFNGLSAMPLEMAPATIPROC)GLimp_ExtensionPointer( "glSampleMapATI" );
474 qglColorFragmentOp1ATI = (PFNGLCOLORFRAGMENTOP1ATIPROC)GLimp_ExtensionPointer( "glColorFragmentOp1ATI" );
475 qglColorFragmentOp2ATI = (PFNGLCOLORFRAGMENTOP2ATIPROC)GLimp_ExtensionPointer( "glColorFragmentOp2ATI" );
476 qglColorFragmentOp3ATI = (PFNGLCOLORFRAGMENTOP3ATIPROC)GLimp_ExtensionPointer( "glColorFragmentOp3ATI" );
477 qglAlphaFragmentOp1ATI = (PFNGLALPHAFRAGMENTOP1ATIPROC)GLimp_ExtensionPointer( "glAlphaFragmentOp1ATI" );
478 qglAlphaFragmentOp2ATI = (PFNGLALPHAFRAGMENTOP2ATIPROC)GLimp_ExtensionPointer( "glAlphaFragmentOp2ATI" );
479 qglAlphaFragmentOp3ATI = (PFNGLALPHAFRAGMENTOP3ATIPROC)GLimp_ExtensionPointer( "glAlphaFragmentOp3ATI" );
480 qglSetFragmentShaderConstantATI = (PFNGLSETFRAGMENTSHADERCONSTANTATIPROC)GLimp_ExtensionPointer( "glSetFragmentShaderConstantATI" );
483 // ARB_vertex_buffer_object
484 glConfig.ARBVertexBufferObjectAvailable = R_CheckExtension( "GL_ARB_vertex_buffer_object" );
485 if(glConfig.ARBVertexBufferObjectAvailable) {
486 qglBindBufferARB = (PFNGLBINDBUFFERARBPROC)GLimp_ExtensionPointer( "glBindBufferARB");
487 qglDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)GLimp_ExtensionPointer( "glDeleteBuffersARB");
488 qglGenBuffersARB = (PFNGLGENBUFFERSARBPROC)GLimp_ExtensionPointer( "glGenBuffersARB");
489 qglIsBufferARB = (PFNGLISBUFFERARBPROC)GLimp_ExtensionPointer( "glIsBufferARB");
490 qglBufferDataARB = (PFNGLBUFFERDATAARBPROC)GLimp_ExtensionPointer( "glBufferDataARB");
491 qglBufferSubDataARB = (PFNGLBUFFERSUBDATAARBPROC)GLimp_ExtensionPointer( "glBufferSubDataARB");
492 qglGetBufferSubDataARB = (PFNGLGETBUFFERSUBDATAARBPROC)GLimp_ExtensionPointer( "glGetBufferSubDataARB");
493 qglMapBufferARB = (PFNGLMAPBUFFERARBPROC)GLimp_ExtensionPointer( "glMapBufferARB");
494 qglUnmapBufferARB = (PFNGLUNMAPBUFFERARBPROC)GLimp_ExtensionPointer( "glUnmapBufferARB");
495 qglGetBufferParameterivARB = (PFNGLGETBUFFERPARAMETERIVARBPROC)GLimp_ExtensionPointer( "glGetBufferParameterivARB");
496 qglGetBufferPointervARB = (PFNGLGETBUFFERPOINTERVARBPROC)GLimp_ExtensionPointer( "glGetBufferPointervARB");
499 // ARB_vertex_program
500 glConfig.ARBVertexProgramAvailable = R_CheckExtension( "GL_ARB_vertex_program" );
501 if (glConfig.ARBVertexProgramAvailable) {
502 qglVertexAttribPointerARB = (PFNGLVERTEXATTRIBPOINTERARBPROC)GLimp_ExtensionPointer( "glVertexAttribPointerARB" );
503 qglEnableVertexAttribArrayARB = (PFNGLENABLEVERTEXATTRIBARRAYARBPROC)GLimp_ExtensionPointer( "glEnableVertexAttribArrayARB" );
504 qglDisableVertexAttribArrayARB = (PFNGLDISABLEVERTEXATTRIBARRAYARBPROC)GLimp_ExtensionPointer( "glDisableVertexAttribArrayARB" );
505 qglProgramStringARB = (PFNGLPROGRAMSTRINGARBPROC)GLimp_ExtensionPointer( "glProgramStringARB" );
506 qglBindProgramARB = (PFNGLBINDPROGRAMARBPROC)GLimp_ExtensionPointer( "glBindProgramARB" );
507 qglGenProgramsARB = (PFNGLGENPROGRAMSARBPROC)GLimp_ExtensionPointer( "glGenProgramsARB" );
508 qglProgramEnvParameter4fvARB = (PFNGLPROGRAMENVPARAMETER4FVARBPROC)GLimp_ExtensionPointer( "glProgramEnvParameter4fvARB" );
509 qglProgramLocalParameter4fvARB = (PFNGLPROGRAMLOCALPARAMETER4FVARBPROC)GLimp_ExtensionPointer( "glProgramLocalParameter4fvARB" );
512 // ARB_fragment_program
513 if ( r_inhibitFragmentProgram.GetBool() ) {
514 glConfig.ARBFragmentProgramAvailable = false;
516 glConfig.ARBFragmentProgramAvailable = R_CheckExtension( "GL_ARB_fragment_program" );
517 if (glConfig.ARBFragmentProgramAvailable) {
518 // these are the same as ARB_vertex_program
519 qglProgramStringARB = (PFNGLPROGRAMSTRINGARBPROC)GLimp_ExtensionPointer( "glProgramStringARB" );
520 qglBindProgramARB = (PFNGLBINDPROGRAMARBPROC)GLimp_ExtensionPointer( "glBindProgramARB" );
521 qglProgramEnvParameter4fvARB = (PFNGLPROGRAMENVPARAMETER4FVARBPROC)GLimp_ExtensionPointer( "glProgramEnvParameter4fvARB" );
522 qglProgramLocalParameter4fvARB = (PFNGLPROGRAMLOCALPARAMETER4FVARBPROC)GLimp_ExtensionPointer( "glProgramLocalParameter4fvARB" );
526 // check for minimum set
527 if ( !glConfig.multitextureAvailable || !glConfig.textureEnvCombineAvailable || !glConfig.cubeMapAvailable
528 || !glConfig.envDot3Available ) {
529 common->Error( common->GetLanguageDict()->GetString( "#str_06780" ) );
532 // GL_EXT_depth_bounds_test
533 glConfig.depthBoundsTestAvailable = R_CheckExtension( "EXT_depth_bounds_test" );
534 if ( glConfig.depthBoundsTestAvailable ) {
535 qglDepthBoundsEXT = (PFNGLDEPTHBOUNDSEXTPROC)GLimp_ExtensionPointer( "glDepthBoundsEXT" );
545 r_mode is normally a small non-negative integer that
546 looks resolutions up in a table, but if it is set to -1,
547 the values from r_customWidth, amd r_customHeight
548 will be used instead.
551 typedef struct vidmode_s {
552 const char *description;
556 vidmode_t r_vidModes[] = {
557 { "Mode 0: 320x240", 320, 240 },
558 { "Mode 1: 400x300", 400, 300 },
559 { "Mode 2: 512x384", 512, 384 },
560 { "Mode 3: 640x480", 640, 480 },
561 { "Mode 4: 800x600", 800, 600 },
562 { "Mode 5: 1024x768", 1024, 768 },
563 { "Mode 6: 1152x864", 1152, 864 },
564 { "Mode 7: 1280x1024", 1280, 1024 },
565 { "Mode 8: 1600x1200", 1600, 1200 },
567 static int s_numVidModes = ( sizeof( r_vidModes ) / sizeof( r_vidModes[0] ) );
570 bool R_GetModeInfo( int *width, int *height, int mode ) {
572 static bool R_GetModeInfo( int *width, int *height, int mode ) {
579 if ( mode >= s_numVidModes ) {
584 *width = r_customWidth.GetInteger();
585 *height = r_customHeight.GetInteger();
589 vm = &r_vidModes[mode];
595 *height = vm->height;
606 This function is responsible for initializing a valid OpenGL subsystem
607 for rendering. This is done by calling the system specific GLimp_Init,
608 which gives us a working OGL subsystem, then setting all necessary openGL
609 state, including images, vertex programs, and display lists.
611 Changes to the vertex cache size or smp state require a vid_restart.
613 If glConfig.isInitialized is false, no rendering can take place, but
614 all renderSystem functions will still operate properly, notably the material
615 and model information functions.
618 void R_InitOpenGL( void ) {
623 common->Printf( "----- R_InitOpenGL -----\n" );
625 if ( glConfig.isInitialized ) {
626 common->FatalError( "R_InitOpenGL called while active" );
629 // in case we had an error while doing a tiled rendering
630 tr.viewportOffset[0] = 0;
631 tr.viewportOffset[1] = 0;
634 // initialize OS specific portions of the renderSystem
636 for ( i = 0 ; i < 2 ; i++ ) {
637 // set the parameters we are trying
638 R_GetModeInfo( &glConfig.vidWidth, &glConfig.vidHeight, r_mode.GetInteger() );
640 parms.width = glConfig.vidWidth;
641 parms.height = glConfig.vidHeight;
642 parms.fullScreen = r_fullscreen.GetBool();
643 parms.displayHz = r_displayRefresh.GetInteger();
644 parms.multiSamples = r_multiSamples.GetInteger();
645 parms.stereo = false;
647 if ( GLimp_Init( parms ) ) {
653 common->FatalError( "Unable to initialize OpenGL" );
656 // if we failed, set everything back to "safe mode"
658 r_mode.SetInteger( 3 );
659 r_fullscreen.SetInteger( 1 );
660 r_displayRefresh.SetInteger( 0 );
661 r_multiSamples.SetInteger( 0 );
664 // input and sound systems need to be tied to the new window
666 soundSystem->InitHW();
668 // get our config strings
669 glConfig.vendor_string = (const char *)qglGetString(GL_VENDOR);
670 glConfig.renderer_string = (const char *)qglGetString(GL_RENDERER);
671 glConfig.version_string = (const char *)qglGetString(GL_VERSION);
672 glConfig.extensions_string = (const char *)qglGetString(GL_EXTENSIONS);
674 // OpenGL driver constants
675 qglGetIntegerv( GL_MAX_TEXTURE_SIZE, &temp );
676 glConfig.maxTextureSize = temp;
678 // stubbed or broken drivers may have reported 0...
679 if ( glConfig.maxTextureSize <= 0 ) {
680 glConfig.maxTextureSize = 256;
683 glConfig.isInitialized = true;
685 // recheck all the extensions (FIXME: this might be dangerous)
686 R_CheckPortableExtensions();
688 // parse our vertex and fragment programs, possibly disably support for
689 // one of the paths if there was an error
695 cmdSystem->AddCommand( "reloadARBprograms", R_ReloadARBPrograms_f, CMD_FL_RENDERER, "reloads ARB programs" );
696 R_ReloadARBPrograms_f( idCmdArgs() );
698 // allocate the vertex array range or vertex objects
701 // select which renderSystem we are going to use
702 r_renderer.SetModified();
703 tr.SetBackEndRenderer();
705 // allocate the frame data, which may be more if smp is enabled
709 R_SetColorMappings();
712 static bool glCheck = false;
713 if ( !glCheck && win32.osversion.dwMajorVersion == 6 ) {
715 if ( !idStr::Icmp( glConfig.vendor_string, "Microsoft" ) && idStr::FindText( glConfig.renderer_string, "OpenGL-D3D" ) != -1 ) {
716 if ( cvarSystem->GetCVarBool( "r_fullscreen" ) ) {
717 cmdSystem->BufferCommandText( CMD_EXEC_NOW, "vid_restart partial windowed\n" );
718 Sys_GrabMouseCursor( false );
720 int ret = MessageBox( NULL, "Please install OpenGL drivers from your graphics hardware vendor to run " GAME_NAME ".\nYour OpenGL functionality is limited.",
721 "Insufficient OpenGL capabilities", MB_OKCANCEL | MB_ICONWARNING | MB_TASKMODAL );
722 if ( ret == IDCANCEL ) {
723 cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "quit\n" );
724 cmdSystem->ExecuteCommandBuffer();
726 if ( cvarSystem->GetCVarBool( "r_fullscreen" ) ) {
727 cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "vid_restart\n" );
739 void GL_CheckErrors( void ) {
744 // check for up to 10 errors pending
745 for ( i = 0 ; i < 10 ; i++ ) {
747 if ( err == GL_NO_ERROR ) {
751 case GL_INVALID_ENUM:
752 strcpy( s, "GL_INVALID_ENUM" );
754 case GL_INVALID_VALUE:
755 strcpy( s, "GL_INVALID_VALUE" );
757 case GL_INVALID_OPERATION:
758 strcpy( s, "GL_INVALID_OPERATION" );
760 case GL_STACK_OVERFLOW:
761 strcpy( s, "GL_STACK_OVERFLOW" );
763 case GL_STACK_UNDERFLOW:
764 strcpy( s, "GL_STACK_UNDERFLOW" );
766 case GL_OUT_OF_MEMORY:
767 strcpy( s, "GL_OUT_OF_MEMORY" );
770 idStr::snPrintf( s, sizeof(s), "%i", err);
774 if ( !r_ignoreGLErrors.GetBool() ) {
775 common->Printf( "GL_CheckErrors: %s\n", s );
781 =====================
784 Reload the material displayed by r_showSurfaceInfo
785 =====================
787 static void R_ReloadSurface_f( const idCmdArgs &args ) {
791 // start far enough away that we don't hit the player model
792 start = tr.primaryView->renderView.vieworg + tr.primaryView->renderView.viewaxis[0] * 16;
793 end = start + tr.primaryView->renderView.viewaxis[0] * 1000.0f;
794 if ( !tr.primaryWorld->Trace( mt, start, end, 0.0f, false ) ) {
798 common->Printf( "Reloading %s\n", mt.material->GetName() );
801 mt.material->base->Reload();
803 // reload any images used by the decl
804 mt.material->ReloadImages( false );
814 static void R_ListModes_f( const idCmdArgs &args ) {
817 common->Printf( "\n" );
818 for ( i = 0; i < s_numVidModes; i++ ) {
819 common->Printf( "%s\n", r_vidModes[i].description );
821 common->Printf( "\n" );
830 Display the given image centered on the screen.
835 void R_TestImage_f( const idCmdArgs &args ) {
838 if ( tr.testVideo ) {
844 if ( args.Argc() != 2 ) {
848 if ( idStr::IsNumeric( args.Argv(1) ) ) {
849 imageNum = atoi( args.Argv(1) );
850 if ( imageNum >= 0 && imageNum < globalImages->images.Num() ) {
851 tr.testImage = globalImages->images[imageNum];
854 tr.testImage = globalImages->ImageFromFile( args.Argv( 1 ), TF_DEFAULT, false, TR_REPEAT, TD_DEFAULT );
862 Plays the cinematic file in a testImage
865 void R_TestVideo_f( const idCmdArgs &args ) {
866 if ( tr.testVideo ) {
872 if ( args.Argc() < 2 ) {
876 tr.testImage = globalImages->ImageFromFile( "_scratch", TF_DEFAULT, false, TR_REPEAT, TD_DEFAULT );
877 tr.testVideo = idCinematic::Alloc();
878 tr.testVideo->InitFromFile( args.Argv( 1 ), true );
881 cin = tr.testVideo->ImageForTime( 0 );
889 common->Printf( "%i x %i images\n", cin.imageWidth, cin.imageHeight );
891 int len = tr.testVideo->AnimationLength();
892 common->Printf( "%5.1f seconds of video\n", len * 0.001 );
894 tr.testVideoStartTime = tr.primaryRenderView.time * 0.001;
896 // try to play the matching wav file
897 idStr wavString = args.Argv( ( args.Argc() == 2 ) ? 1 : 2 );
898 wavString.StripFileExtension();
899 wavString = wavString + ".wav";
900 session->sw->PlayShaderDirectly( wavString.c_str() );
903 static int R_QsortSurfaceAreas( const void *a, const void *b ) {
904 const idMaterial *ea, *eb;
907 ea = *(idMaterial **)a;
908 if ( !ea->EverReferenced() ) {
911 ac = ea->GetSurfaceArea();
913 eb = *(idMaterial **)b;
914 if ( !eb->EverReferenced() ) {
917 bc = eb->GetSurfaceArea();
927 return idStr::Icmp( ea->GetName(), eb->GetName() );
933 R_ReportSurfaceAreas_f
935 Prints a list of the materials sorted by surface area
938 void R_ReportSurfaceAreas_f( const idCmdArgs &args ) {
942 count = declManager->GetNumDecls( DECL_MATERIAL );
943 list = (idMaterial **)_alloca( count * sizeof( *list ) );
945 for ( i = 0 ; i < count ; i++ ) {
946 list[i] = (idMaterial *)declManager->DeclByIndex( DECL_MATERIAL, i, false );
949 qsort( list, count, sizeof( list[0] ), R_QsortSurfaceAreas );
951 // skip over ones with 0 area
952 for ( i = 0 ; i < count ; i++ ) {
953 if ( list[i]->GetSurfaceArea() > 0 ) {
958 for ( ; i < count ; i++ ) {
959 // report size in "editor blocks"
960 int blocks = list[i]->GetSurfaceArea() / 4096.0;
961 common->Printf( "%7i %s\n", blocks, list[i]->GetName() );
967 R_ReportImageDuplication_f
969 Checks for images with the same hash value and does a better comparison
972 void R_ReportImageDuplication_f( const idCmdArgs &args ) {
975 common->Printf( "Images with duplicated contents:\n" );
979 for ( i = 0 ; i < globalImages->images.Num() ; i++ ) {
980 idImage *image1 = globalImages->images[i];
982 if ( image1->isPartialImage ) {
983 // ignore background loading stubs
986 if ( image1->generatorFunction ) {
987 // ignore procedural images
990 if ( image1->cubeFiles != CF_2D ) {
994 if ( image1->defaulted ) {
1000 R_LoadImageProgram( image1->imgName, &data1, &w1, &h1, NULL );
1002 for ( j = 0 ; j < i ; j++ ) {
1003 idImage *image2 = globalImages->images[j];
1005 if ( image2->isPartialImage ) {
1008 if ( image2->generatorFunction ) {
1011 if ( image2->cubeFiles != CF_2D ) {
1014 if ( image2->defaulted ) {
1017 if ( image1->imageHash != image2->imageHash ) {
1020 if ( image2->uploadWidth != image1->uploadWidth
1021 || image2->uploadHeight != image1->uploadHeight ) {
1024 if ( !idStr::Icmp( image1->imgName, image2->imgName ) ) {
1025 // ignore same image-with-different-parms
1032 R_LoadImageProgram( image2->imgName, &data2, &w2, &h2, NULL );
1034 if ( w2 != w1 || h2 != h1 ) {
1035 R_StaticFree( data2 );
1039 if ( memcmp( data1, data2, w1*h1*4 ) ) {
1040 R_StaticFree( data2 );
1044 R_StaticFree( data2 );
1046 common->Printf( "%s == %s\n", image1->imgName.c_str(), image2->imgName.c_str() );
1047 session->UpdateScreen( true );
1052 R_StaticFree( data1 );
1054 common->Printf( "%i / %i collisions\n", count, globalImages->images.Num() );
1058 ==============================================================================
1060 THROUGHPUT BENCHMARKING
1062 ==============================================================================
1070 static float R_RenderingFPS( const renderView_t *renderView ) {
1073 int start = Sys_Milliseconds();
1074 static const int SAMPLE_MSEC = 1000;
1080 renderSystem->BeginFrame( glConfig.vidWidth, glConfig.vidHeight );
1081 tr.primaryWorld->RenderScene( renderView );
1082 renderSystem->EndFrame( NULL, NULL );
1085 end = Sys_Milliseconds();
1086 if ( end - start > SAMPLE_MSEC ) {
1091 float fps = count * 1000.0 / ( end - start );
1101 void R_Benchmark_f( const idCmdArgs &args ) {
1105 if ( !tr.primaryView ) {
1106 common->Printf( "No primaryView for benchmarking\n" );
1109 view = tr.primaryRenderView;
1111 for ( int size = 100 ; size >= 10 ; size -= 10 ) {
1112 r_screenFraction.SetInteger( size );
1113 fps = R_RenderingFPS( &view );
1114 int kpix = glConfig.vidWidth * glConfig.vidHeight * ( size * 0.01 ) * ( size * 0.01 ) * 0.001;
1115 msec = 1000.0 / fps;
1116 common->Printf( "kpix: %4i msec:%5.1f fps:%5.1f\n", kpix, msec, fps );
1119 // enable r_singleTriangle 1 while r_screenFraction is still at 10
1120 r_singleTriangle.SetBool( 1 );
1121 fps = R_RenderingFPS( &view );
1122 msec = 1000.0 / fps;
1123 common->Printf( "single tri msec:%5.1f fps:%5.1f\n", msec, fps );
1124 r_singleTriangle.SetBool( 0 );
1125 r_screenFraction.SetInteger( 100 );
1127 // enable r_skipRenderContext 1
1128 r_skipRenderContext.SetBool( true );
1129 fps = R_RenderingFPS( &view );
1130 msec = 1000.0 / fps;
1131 common->Printf( "no context msec:%5.1f fps:%5.1f\n", msec, fps );
1132 r_skipRenderContext.SetBool( false );
1137 ==============================================================================
1141 ==============================================================================
1145 ====================
1148 Allows the rendering of an image larger than the actual window by
1149 tiling it into window-sized chunks and rendering each chunk separately
1151 If ref isn't specified, the full session UpdateScreen will be done.
1152 ====================
1154 void R_ReadTiledPixels( int width, int height, byte *buffer, renderView_t *ref = NULL ) {
1155 // include extra space for OpenGL padding to word boundaries
1156 byte *temp = (byte *)R_StaticAlloc( (glConfig.vidWidth+3) * glConfig.vidHeight * 3 );
1158 int oldWidth = glConfig.vidWidth;
1159 int oldHeight = glConfig.vidHeight;
1161 tr.tiledViewport[0] = width;
1162 tr.tiledViewport[1] = height;
1164 // disable scissor, so we don't need to adjust all those rects
1165 r_useScissor.SetBool( false );
1167 for ( int xo = 0 ; xo < width ; xo += oldWidth ) {
1168 for ( int yo = 0 ; yo < height ; yo += oldHeight ) {
1169 tr.viewportOffset[0] = -xo;
1170 tr.viewportOffset[1] = -yo;
1173 tr.BeginFrame( oldWidth, oldHeight );
1174 tr.primaryWorld->RenderScene( ref );
1175 tr.EndFrame( NULL, NULL );
1177 session->UpdateScreen();
1181 if ( xo + w > width ) {
1185 if ( yo + h > height ) {
1189 qglReadBuffer( GL_FRONT );
1190 qglReadPixels( 0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, temp );
1192 int row = ( w * 3 + 3 ) & ~3; // OpenGL pads to dword boundaries
1194 for ( int y = 0 ; y < h ; y++ ) {
1195 memcpy( buffer + ( ( yo + y )* width + xo ) * 3,
1196 temp + y * row, w * 3 );
1201 r_useScissor.SetBool( true );
1203 tr.viewportOffset[0] = 0;
1204 tr.viewportOffset[1] = 0;
1205 tr.tiledViewport[0] = 0;
1206 tr.tiledViewport[1] = 0;
1208 R_StaticFree( temp );
1210 glConfig.vidWidth = oldWidth;
1211 glConfig.vidHeight = oldHeight;
1219 Move to tr_imagefiles.c...
1221 Will automatically tile render large screen shots if necessary
1222 Downsample is the number of steps to mipmap the image before saving it
1223 If ref == NULL, session->updateScreen will be used
1226 void idRenderSystemLocal::TakeScreenshot( int width, int height, const char *fileName, int blends, renderView_t *ref ) {
1230 takingScreenshot = true;
1232 int pix = width * height;
1234 buffer = (byte *)R_StaticAlloc(pix*3 + 18);
1235 memset (buffer, 0, 18);
1237 if ( blends <= 1 ) {
1238 R_ReadTiledPixels( width, height, buffer + 18, ref );
1240 unsigned short *shortBuffer = (unsigned short *)R_StaticAlloc(pix*2*3);
1241 memset (shortBuffer, 0, pix*2*3);
1243 // enable anti-aliasing jitter
1244 r_jitter.SetBool( true );
1246 for ( i = 0 ; i < blends ; i++ ) {
1247 R_ReadTiledPixels( width, height, buffer + 18, ref );
1249 for ( j = 0 ; j < pix*3 ; j++ ) {
1250 shortBuffer[j] += buffer[18+j];
1254 // divide back to bytes
1255 for ( i = 0 ; i < pix*3 ; i++ ) {
1256 buffer[18+i] = shortBuffer[i] / blends;
1259 R_StaticFree( shortBuffer );
1260 r_jitter.SetBool( false );
1263 // fill in the header (this is vertically flipped, which qglReadPixels emits)
1264 buffer[2] = 2; // uncompressed type
1265 buffer[12] = width & 255;
1266 buffer[13] = width >> 8;
1267 buffer[14] = height & 255;
1268 buffer[15] = height >> 8;
1269 buffer[16] = 24; // pixel size
1272 c = 18 + width * height * 3;
1273 for (i=18 ; i<c ; i+=3) {
1275 buffer[i] = buffer[i+2];
1279 // _D3XP adds viewnote screenie save to cdpath
1280 if ( strstr( fileName, "viewnote" ) ) {
1281 fileSystem->WriteFile( fileName, buffer, c, "fs_cdpath" );
1283 fileSystem->WriteFile( fileName, buffer, c );
1286 R_StaticFree( buffer );
1288 takingScreenshot = false;
1295 R_ScreenshotFilename
1297 Returns a filename with digits appended
1298 if we have saved a previous screenshot, don't scan
1299 from the beginning, because recording demo avis can involve
1303 void R_ScreenshotFilename( int &lastNumber, const char *base, idStr &fileName ) {
1306 bool restrict = cvarSystem->GetCVarBool( "fs_restrict" );
1307 cvarSystem->SetCVarBool( "fs_restrict", false );
1310 if ( lastNumber > 99999 ) {
1313 for ( ; lastNumber < 99999 ; lastNumber++ ) {
1314 int frac = lastNumber;
1326 sprintf( fileName, "%s%i%i%i%i%i.tga", base, a, b, c, d, e );
1327 if ( lastNumber == 99999 ) {
1330 int len = fileSystem->ReadFile( fileName, NULL, NULL );
1336 cvarSystem->SetCVarBool( "fs_restrict", restrict );
1344 screenshot [filename]
1345 screenshot [width] [height]
1346 screenshot [width] [height] [samples]
1349 #define MAX_BLENDS 256 // to keep the accumulation in shorts
1350 void R_ScreenShot_f( const idCmdArgs &args ) {
1351 static int lastNumber = 0;
1354 int width = glConfig.vidWidth;
1355 int height = glConfig.vidHeight;
1360 switch ( args.Argc() ) {
1362 width = glConfig.vidWidth;
1363 height = glConfig.vidHeight;
1365 R_ScreenshotFilename( lastNumber, "screenshots/shot", checkname );
1368 width = glConfig.vidWidth;
1369 height = glConfig.vidHeight;
1371 checkname = args.Argv( 1 );
1374 width = atoi( args.Argv( 1 ) );
1375 height = atoi( args.Argv( 2 ) );
1377 R_ScreenshotFilename( lastNumber, "screenshots/shot", checkname );
1380 width = atoi( args.Argv( 1 ) );
1381 height = atoi( args.Argv( 2 ) );
1382 blends = atoi( args.Argv( 3 ) );
1386 if ( blends > MAX_BLENDS ) {
1387 blends = MAX_BLENDS;
1389 R_ScreenshotFilename( lastNumber, "screenshots/shot", checkname );
1392 common->Printf( "usage: screenshot\n screenshot <filename>\n screenshot <width> <height>\n screenshot <width> <height> <blends>\n" );
1396 // put the console away
1399 tr.TakeScreenshot( width, height, checkname, blends, NULL );
1401 common->Printf( "Wrote %s\n", checkname.c_str() );
1407 Save out a screenshot showing the stencil buffer expanded by 16x range
1410 void R_StencilShot( void ) {
1414 int width = tr.GetScreenWidth();
1415 int height = tr.GetScreenHeight();
1417 int pix = width * height;
1420 buffer = (byte *)Mem_Alloc(c);
1421 memset (buffer, 0, 18);
1423 byte *byteBuffer = (byte *)Mem_Alloc(pix);
1425 qglReadPixels( 0, 0, width, height, GL_STENCIL_INDEX , GL_UNSIGNED_BYTE, byteBuffer );
1427 for ( i = 0 ; i < pix ; i++ ) {
1430 // buffer[18+i*3+2] = ( byteBuffer[i] & 15 ) * 16;
1431 buffer[18+i*3+2] = byteBuffer[i];
1434 // fill in the header (this is vertically flipped, which qglReadPixels emits)
1435 buffer[2] = 2; // uncompressed type
1436 buffer[12] = width & 255;
1437 buffer[13] = width >> 8;
1438 buffer[14] = height & 255;
1439 buffer[15] = height >> 8;
1440 buffer[16] = 24; // pixel size
1442 fileSystem->WriteFile( "screenshots/stencilShot.tga", buffer, c, "fs_savepath" );
1445 Mem_Free( byteBuffer );
1454 Saves out env/<basename>_ft.tga, etc
1457 void R_EnvShot_f( const idCmdArgs &args ) {
1459 const char *baseName;
1465 char *extensions[6] = { "_px.tga", "_nx.tga", "_py.tga", "_ny.tga",
1466 "_pz.tga", "_nz.tga" };
1469 if ( args.Argc() != 2 && args.Argc() != 3 && args.Argc() != 4 ) {
1470 common->Printf( "USAGE: envshot <basename> [size] [blends]\n" );
1473 baseName = args.Argv( 1 );
1476 if ( args.Argc() == 4 ) {
1477 size = atoi( args.Argv( 2 ) );
1478 blends = atoi( args.Argv( 3 ) );
1479 } else if ( args.Argc() == 3 ) {
1480 size = atoi( args.Argv( 2 ) );
1487 if ( !tr.primaryView ) {
1488 common->Printf( "No primary view.\n" );
1492 primary = *tr.primaryView;
1494 memset( &axis, 0, sizeof( axis ) );
1519 for ( i = 0 ; i < 6 ; i++ ) {
1520 ref = primary.renderView;
1522 ref.fov_x = ref.fov_y = 90;
1523 ref.width = glConfig.vidWidth;
1524 ref.height = glConfig.vidHeight;
1525 ref.viewaxis = axis[i];
1526 sprintf( fullname, "env/%s%s", baseName, extensions[i] );
1527 tr.TakeScreenshot( size, size, fullname, blends, &ref );
1530 common->Printf( "Wrote %s, etc\n", fullname.c_str() );
1533 //============================================================================
1535 static idMat3 cubeAxis[6];
1543 void R_SampleCubeMap( const idVec3 &dir, int size, byte *buffers[6], byte result[4] ) {
1547 adir[0] = fabs(dir[0]);
1548 adir[1] = fabs(dir[1]);
1549 adir[2] = fabs(dir[2]);
1551 if ( dir[0] >= adir[1] && dir[0] >= adir[2] ) {
1553 } else if ( -dir[0] >= adir[1] && -dir[0] >= adir[2] ) {
1555 } else if ( dir[1] >= adir[0] && dir[1] >= adir[2] ) {
1557 } else if ( -dir[1] >= adir[0] && -dir[1] >= adir[2] ) {
1559 } else if ( dir[2] >= adir[1] && dir[2] >= adir[2] ) {
1565 float fx = (dir * cubeAxis[axis][1]) / (dir * cubeAxis[axis][0]);
1566 float fy = (dir * cubeAxis[axis][2]) / (dir * cubeAxis[axis][0]);
1570 x = size * 0.5 * (fx + 1);
1571 y = size * 0.5 * (fy + 1);
1574 } else if ( x >= size ) {
1579 } else if ( y >= size ) {
1583 result[0] = buffers[axis][(y*size+x)*4+0];
1584 result[1] = buffers[axis][(y*size+x)*4+1];
1585 result[2] = buffers[axis][(y*size+x)*4+2];
1586 result[3] = buffers[axis][(y*size+x)*4+3];
1593 R_MakeAmbientMap_f <basename> [size]
1595 Saves out env/<basename>_amb_ft.tga, etc
1598 void R_MakeAmbientMap_f( const idCmdArgs &args ) {
1600 const char *baseName;
1605 char *extensions[6] = { "_px.tga", "_nx.tga", "_py.tga", "_ny.tga",
1606 "_pz.tga", "_nz.tga" };
1611 if ( args.Argc() != 2 && args.Argc() != 3 ) {
1612 common->Printf( "USAGE: ambientshot <basename> [size]\n" );
1615 baseName = args.Argv( 1 );
1618 if ( args.Argc() == 3 ) {
1619 outSize = atoi( args.Argv( 2 ) );
1624 memset( &cubeAxis, 0, sizeof( cubeAxis ) );
1625 cubeAxis[0][0][0] = 1;
1626 cubeAxis[0][1][2] = 1;
1627 cubeAxis[0][2][1] = 1;
1629 cubeAxis[1][0][0] = -1;
1630 cubeAxis[1][1][2] = -1;
1631 cubeAxis[1][2][1] = 1;
1633 cubeAxis[2][0][1] = 1;
1634 cubeAxis[2][1][0] = -1;
1635 cubeAxis[2][2][2] = -1;
1637 cubeAxis[3][0][1] = -1;
1638 cubeAxis[3][1][0] = -1;
1639 cubeAxis[3][2][2] = 1;
1641 cubeAxis[4][0][2] = 1;
1642 cubeAxis[4][1][0] = -1;
1643 cubeAxis[4][2][1] = 1;
1645 cubeAxis[5][0][2] = -1;
1646 cubeAxis[5][1][0] = 1;
1647 cubeAxis[5][2][1] = 1;
1649 // read all of the images
1650 for ( i = 0 ; i < 6 ; i++ ) {
1651 sprintf( fullname, "env/%s%s", baseName, extensions[i] );
1652 common->Printf( "loading %s\n", fullname.c_str() );
1653 session->UpdateScreen();
1654 R_LoadImage( fullname, &buffers[i], &width, &height, NULL, true );
1655 if ( !buffers[i] ) {
1656 common->Printf( "failed.\n" );
1657 for ( i-- ; i >= 0 ; i-- ) {
1658 Mem_Free( buffers[i] );
1664 // resample with hemispherical blending
1667 byte *outBuffer = (byte *)_alloca( outSize * outSize * 4 );
1669 for ( int map = 0 ; map < 2 ; map++ ) {
1670 for ( i = 0 ; i < 6 ; i++ ) {
1671 for ( int x = 0 ; x < outSize ; x++ ) {
1672 for ( int y = 0 ; y < outSize ; y++ ) {
1676 dir = cubeAxis[i][0] + -( -1 + 2.0*x/(outSize-1) ) * cubeAxis[i][1] + -( -1 + 2.0*y/(outSize-1) ) * cubeAxis[i][2];
1678 total[0] = total[1] = total[2] = 0;
1680 float limit = map ? 0.95 : 0.25; // small for specular, almost hemisphere for ambient
1682 for ( int s = 0 ; s < samples ; s++ ) {
1683 // pick a random direction vector that is inside the unit sphere but not behind dir,
1684 // which is a robust way to evenly sample a hemisphere
1687 for ( int j = 0 ; j < 3 ; j++ ) {
1688 test[j] = -1 + 2 * (rand()&0x7fff)/(float)0x7fff;
1690 if ( test.Length() > 1.0 ) {
1694 if ( test * dir > limit ) { // don't do a complete hemisphere
1700 R_SampleCubeMap( test, width, buffers, result );
1701 total[0] += result[0];
1702 total[1] += result[1];
1703 total[2] += result[2];
1705 outBuffer[(y*outSize+x)*4+0] = total[0] / samples;
1706 outBuffer[(y*outSize+x)*4+1] = total[1] / samples;
1707 outBuffer[(y*outSize+x)*4+2] = total[2] / samples;
1708 outBuffer[(y*outSize+x)*4+3] = 255;
1713 sprintf( fullname, "env/%s_amb%s", baseName, extensions[i] );
1715 sprintf( fullname, "env/%s_spec%s", baseName, extensions[i] );
1717 common->Printf( "writing %s\n", fullname.c_str() );
1718 session->UpdateScreen();
1719 R_WriteTGA( fullname, outBuffer, outSize, outSize );
1723 for ( i = 0 ; i < 6 ; i++ ) {
1725 Mem_Free( buffers[i] );
1730 //============================================================================
1738 void R_SetColorMappings( void ) {
1743 b = r_brightness.GetFloat();
1744 g = r_gamma.GetFloat();
1746 for ( i = 0; i < 256; i++ ) {
1755 inf = 0xffff * pow ( j/255.0f, 1.0f / g ) + 0.5f;
1764 tr.gammaTable[i] = inf;
1767 GLimp_SetGamma( tr.gammaTable, tr.gammaTable, tr.gammaTable );
1776 void GfxInfo_f( const idCmdArgs &args ) {
1777 const char *fsstrings[] =
1783 common->Printf( "\nGL_VENDOR: %s\n", glConfig.vendor_string );
1784 common->Printf( "GL_RENDERER: %s\n", glConfig.renderer_string );
1785 common->Printf( "GL_VERSION: %s\n", glConfig.version_string );
1786 common->Printf( "GL_EXTENSIONS: %s\n", glConfig.extensions_string );
1787 if ( glConfig.wgl_extensions_string ) {
1788 common->Printf( "WGL_EXTENSIONS: %s\n", glConfig.wgl_extensions_string );
1790 common->Printf( "GL_MAX_TEXTURE_SIZE: %d\n", glConfig.maxTextureSize );
1791 common->Printf( "GL_MAX_TEXTURE_UNITS_ARB: %d\n", glConfig.maxTextureUnits );
1792 common->Printf( "GL_MAX_TEXTURE_COORDS_ARB: %d\n", glConfig.maxTextureCoords );
1793 common->Printf( "GL_MAX_TEXTURE_IMAGE_UNITS_ARB: %d\n", glConfig.maxTextureImageUnits );
1794 common->Printf( "\nPIXELFORMAT: color(%d-bits) Z(%d-bit) stencil(%d-bits)\n", glConfig.colorBits, glConfig.depthBits, glConfig.stencilBits );
1795 common->Printf( "MODE: %d, %d x %d %s hz:", r_mode.GetInteger(), glConfig.vidWidth, glConfig.vidHeight, fsstrings[r_fullscreen.GetBool()] );
1797 if ( glConfig.displayFrequency ) {
1798 common->Printf( "%d\n", glConfig.displayFrequency );
1800 common->Printf( "N/A\n" );
1802 common->Printf( "CPU: %s\n", Sys_GetProcessorString() );
1804 const char *active[2] = { "", " (ACTIVE)" };
1805 common->Printf( "ARB path ENABLED%s\n", active[tr.backEndRenderer == BE_ARB] );
1807 if ( glConfig.allowNV10Path ) {
1808 common->Printf( "NV10 path ENABLED%s\n", active[tr.backEndRenderer == BE_NV10] );
1810 common->Printf( "NV10 path disabled\n" );
1813 if ( glConfig.allowNV20Path ) {
1814 common->Printf( "NV20 path ENABLED%s\n", active[tr.backEndRenderer == BE_NV20] );
1816 common->Printf( "NV20 path disabled\n" );
1819 if ( glConfig.allowR200Path ) {
1820 common->Printf( "R200 path ENABLED%s\n", active[tr.backEndRenderer == BE_R200] );
1822 common->Printf( "R200 path disabled\n" );
1825 if ( glConfig.allowARB2Path ) {
1826 common->Printf( "ARB2 path ENABLED%s\n", active[tr.backEndRenderer == BE_ARB2] );
1828 common->Printf( "ARB2 path disabled\n" );
1831 //=============================
1833 common->Printf( "-------\n" );
1835 if ( r_finish.GetBool() ) {
1836 common->Printf( "Forcing glFinish\n" );
1838 common->Printf( "glFinish not forced\n" );
1842 // WGL_EXT_swap_interval
1843 typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval);
1844 extern PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT;
1846 if ( r_swapInterval.GetInteger() && wglSwapIntervalEXT ) {
1847 common->Printf( "Forcing swapInterval %i\n", r_swapInterval.GetInteger() );
1849 common->Printf( "swapInterval not forced\n" );
1853 bool tss = glConfig.twoSidedStencilAvailable || glConfig.atiTwoSidedStencilAvailable;
1855 if ( !r_useTwoSidedStencil.GetBool() && tss ) {
1856 common->Printf( "Two sided stencil available but disabled\n" );
1857 } else if ( !tss ) {
1858 common->Printf( "Two sided stencil not available\n" );
1860 common->Printf( "Using two sided stencil\n" );
1863 if ( vertexCache.IsFast() ) {
1864 common->Printf( "Vertex cache is fast\n" );
1866 common->Printf( "Vertex cache is SLOW\n" );
1875 void R_VidRestart_f( const idCmdArgs &args ) {
1878 // if OpenGL isn't started, do nothing
1879 if ( !glConfig.isInitialized ) {
1884 bool forceWindow = false;
1885 for ( int i = 1 ; i < args.Argc() ; i++ ) {
1886 if ( idStr::Icmp( args.Argv( i ), "partial" ) == 0 ) {
1890 if ( idStr::Icmp( args.Argv( i ), "windowed" ) == 0 ) {
1896 // this could take a while, so give them the cursor back ASAP
1897 Sys_GrabMouseCursor( false );
1899 // dump ambient caches
1900 renderModelManager->FreeModelVertexCaches();
1902 // free any current world interaction surfaces and vertex caches
1903 R_FreeDerivedData();
1905 // make sure the defered frees are actually freed
1909 // free the vertex caches so they will be regenerated again
1910 vertexCache.PurgeAll();
1912 // sound and input are tied to the window we are about to destroy
1915 // free all of our texture numbers
1916 soundSystem->ShutdownHW();
1917 Sys_ShutdownInput();
1918 globalImages->PurgeAllImages();
1919 // free the context and close the window
1921 glConfig.isInitialized = false;
1923 // create the new context and vertex cache
1924 bool latch = cvarSystem->GetCVarBool( "r_fullscreen" );
1925 if ( forceWindow ) {
1926 cvarSystem->SetCVarBool( "r_fullscreen", false );
1929 cvarSystem->SetCVarBool( "r_fullscreen", latch );
1931 // regenerate all images
1932 globalImages->ReloadAllImages();
1935 parms.width = glConfig.vidWidth;
1936 parms.height = glConfig.vidHeight;
1937 parms.fullScreen = ( forceWindow ) ? false : r_fullscreen.GetBool();
1938 parms.displayHz = r_displayRefresh.GetInteger();
1939 parms.multiSamples = r_multiSamples.GetInteger();
1940 parms.stereo = false;
1941 GLimp_SetScreenParms( parms );
1946 // make sure the regeneration doesn't use anything no longer valid
1950 // regenerate all necessary interactions
1951 R_RegenerateWorld_f( idCmdArgs() );
1953 // check for problems
1954 err = qglGetError();
1955 if ( err != GL_NO_ERROR ) {
1956 common->Printf( "glGetError() = 0x%x\n", err );
1959 // start sound playing again
1960 soundSystem->SetMute( false );
1969 void R_InitMaterials( void ) {
1970 tr.defaultMaterial = declManager->FindMaterial( "_default", false );
1971 if ( !tr.defaultMaterial ) {
1972 common->FatalError( "_default material not found" );
1974 declManager->FindMaterial( "_default", false );
1976 // needed by R_DeriveLightData
1977 declManager->FindMaterial( "lights/defaultPointLight" );
1978 declManager->FindMaterial( "lights/defaultProjectedLight" );
1989 static void R_SizeUp_f( const idCmdArgs &args ) {
1990 if ( r_screenFraction.GetInteger() + 10 > 100 ) {
1991 r_screenFraction.SetInteger( 100 );
1993 r_screenFraction.SetInteger( r_screenFraction.GetInteger() + 10 );
2005 static void R_SizeDown_f( const idCmdArgs &args ) {
2006 if ( r_screenFraction.GetInteger() - 10 < 10 ) {
2007 r_screenFraction.SetInteger( 10 );
2009 r_screenFraction.SetInteger( r_screenFraction.GetInteger() - 10 );
2018 this is called from the main thread
2021 void R_TouchGui_f( const idCmdArgs &args ) {
2022 const char *gui = args.Argv( 1 );
2025 common->Printf( "USAGE: touchGui <guiName>\n" );
2029 common->Printf( "touchGui %s\n", gui );
2030 session->UpdateScreen();
2031 uiManager->Touch( gui );
2039 void R_InitCvars( void ) {
2040 // update latched cvars here
2048 void R_InitCommands( void ) {
2049 cmdSystem->AddCommand( "MakeMegaTexture", idMegaTexture::MakeMegaTexture_f, CMD_FL_RENDERER|CMD_FL_CHEAT, "processes giant images" );
2050 cmdSystem->AddCommand( "sizeUp", R_SizeUp_f, CMD_FL_RENDERER, "makes the rendered view larger" );
2051 cmdSystem->AddCommand( "sizeDown", R_SizeDown_f, CMD_FL_RENDERER, "makes the rendered view smaller" );
2052 cmdSystem->AddCommand( "reloadGuis", R_ReloadGuis_f, CMD_FL_RENDERER, "reloads guis" );
2053 cmdSystem->AddCommand( "listGuis", R_ListGuis_f, CMD_FL_RENDERER, "lists guis" );
2054 cmdSystem->AddCommand( "touchGui", R_TouchGui_f, CMD_FL_RENDERER, "touches a gui" );
2055 cmdSystem->AddCommand( "screenshot", R_ScreenShot_f, CMD_FL_RENDERER, "takes a screenshot" );
2056 cmdSystem->AddCommand( "envshot", R_EnvShot_f, CMD_FL_RENDERER, "takes an environment shot" );
2057 cmdSystem->AddCommand( "makeAmbientMap", R_MakeAmbientMap_f, CMD_FL_RENDERER|CMD_FL_CHEAT, "makes an ambient map" );
2058 cmdSystem->AddCommand( "benchmark", R_Benchmark_f, CMD_FL_RENDERER, "benchmark" );
2059 cmdSystem->AddCommand( "gfxInfo", GfxInfo_f, CMD_FL_RENDERER, "show graphics info" );
2060 cmdSystem->AddCommand( "modulateLights", R_ModulateLights_f, CMD_FL_RENDERER | CMD_FL_CHEAT, "modifies shader parms on all lights" );
2061 cmdSystem->AddCommand( "testImage", R_TestImage_f, CMD_FL_RENDERER | CMD_FL_CHEAT, "displays the given image centered on screen", idCmdSystem::ArgCompletion_ImageName );
2062 cmdSystem->AddCommand( "testVideo", R_TestVideo_f, CMD_FL_RENDERER | CMD_FL_CHEAT, "displays the given cinematic", idCmdSystem::ArgCompletion_VideoName );
2063 cmdSystem->AddCommand( "reportSurfaceAreas", R_ReportSurfaceAreas_f, CMD_FL_RENDERER, "lists all used materials sorted by surface area" );
2064 cmdSystem->AddCommand( "reportImageDuplication", R_ReportImageDuplication_f, CMD_FL_RENDERER, "checks all referenced images for duplications" );
2065 cmdSystem->AddCommand( "regenerateWorld", R_RegenerateWorld_f, CMD_FL_RENDERER, "regenerates all interactions" );
2066 cmdSystem->AddCommand( "showInteractionMemory", R_ShowInteractionMemory_f, CMD_FL_RENDERER, "shows memory used by interactions" );
2067 cmdSystem->AddCommand( "showTriSurfMemory", R_ShowTriSurfMemory_f, CMD_FL_RENDERER, "shows memory used by triangle surfaces" );
2068 cmdSystem->AddCommand( "vid_restart", R_VidRestart_f, CMD_FL_RENDERER, "restarts renderSystem" );
2069 cmdSystem->AddCommand( "listRenderEntityDefs", R_ListRenderEntityDefs_f, CMD_FL_RENDERER, "lists the entity defs" );
2070 cmdSystem->AddCommand( "listRenderLightDefs", R_ListRenderLightDefs_f, CMD_FL_RENDERER, "lists the light defs" );
2071 cmdSystem->AddCommand( "listModes", R_ListModes_f, CMD_FL_RENDERER, "lists all video modes" );
2072 cmdSystem->AddCommand( "reloadSurface", R_ReloadSurface_f, CMD_FL_RENDERER, "reloads the decl and images for selected surface" );
2077 idRenderSystemLocal::Clear
2080 void idRenderSystemLocal::Clear( void ) {
2084 staticAllocCount = 0;
2085 frameShaderTime = 0.0f;
2086 viewportOffset[0] = 0;
2087 viewportOffset[1] = 0;
2088 tiledViewport[0] = 0;
2089 tiledViewport[1] = 0;
2090 backEndRenderer = BE_BAD;
2091 backEndRendererHasVertexPrograms = false;
2092 backEndRendererMaxLight = 1.0f;
2093 ambientLightVector.Zero();
2096 primaryWorld = NULL;
2097 memset( &primaryRenderView, 0, sizeof( primaryRenderView ) );
2099 defaultMaterial = NULL;
2101 ambientCubeImage = NULL;
2103 memset( &pc, 0, sizeof( pc ) );
2104 memset( &lockSurfacesCmd, 0, sizeof( lockSurfacesCmd ) );
2105 memset( &identitySpace, 0, sizeof( identitySpace ) );
2109 memset( renderCrops, 0, sizeof( renderCrops ) );
2110 currentRenderCrop = 0;
2111 guiRecursionLevel = 0;
2113 demoGuiModel = NULL;
2114 memset( gammaTable, 0, sizeof( gammaTable ) );
2115 takingScreenshot = false;
2120 idRenderSystemLocal::Init
2123 void idRenderSystemLocal::Init( void ) {
2125 common->Printf( "------- Initializing renderSystem --------\n" );
2127 // clear all our internal state
2128 viewCount = 1; // so cleared structures never match viewCount
2129 // we used to memset tr, but now that it is a class, we can't, so
2130 // there may be other state we need to reset
2132 ambientLightVector[0] = 0.5f;
2133 ambientLightVector[1] = 0.5f - 0.385f;
2134 ambientLightVector[2] = 0.8925f;
2135 ambientLightVector[3] = 1.0f;
2137 memset( &backEnd, 0, sizeof( backEnd ) );
2143 guiModel = new idGuiModel;
2146 demoGuiModel = new idGuiModel;
2147 demoGuiModel->Clear();
2149 R_InitTriSurfData();
2151 globalImages->Init();
2153 idCinematic::InitCinematic( );
2155 // build brightness translation tables
2156 R_SetColorMappings();
2160 renderModelManager->Init();
2162 // set the identity space
2163 identitySpace.modelMatrix[0*4+0] = 1.0f;
2164 identitySpace.modelMatrix[1*4+1] = 1.0f;
2165 identitySpace.modelMatrix[2*4+2] = 1.0f;
2167 // determine which back end we will use
2168 // ??? this is invalid here as there is not enough information to set it up correctly
2169 SetBackEndRenderer();
2171 common->Printf( "renderSystem initialized.\n" );
2172 common->Printf( "--------------------------------------\n" );
2177 idRenderSystemLocal::Shutdown
2180 void idRenderSystemLocal::Shutdown( void ) {
2181 common->Printf( "idRenderSystem::Shutdown()\n" );
2185 if ( glConfig.isInitialized ) {
2186 globalImages->PurgeAllImages();
2189 renderModelManager->Shutdown();
2191 idCinematic::ShutdownCinematic( );
2193 globalImages->Shutdown();
2195 // close the r_logFile
2197 fprintf( logFile, "*** CLOSING LOG ***\n" );
2202 // free frame memory
2203 R_ShutdownFrameData();
2205 // free the vertex cache, which should have nothing allocated now
2206 vertexCache.Shutdown();
2208 R_ShutdownTriSurfData();
2210 RB_ShutdownDebugTools();
2213 delete demoGuiModel;
2221 ========================
2222 idRenderSystemLocal::BeginLevelLoad
2223 ========================
2225 void idRenderSystemLocal::BeginLevelLoad( void ) {
2226 renderModelManager->BeginLevelLoad();
2227 globalImages->BeginLevelLoad();
2231 ========================
2232 idRenderSystemLocal::EndLevelLoad
2233 ========================
2235 void idRenderSystemLocal::EndLevelLoad( void ) {
2236 renderModelManager->EndLevelLoad();
2237 globalImages->EndLevelLoad();
2238 if ( r_forceLoadImages.GetBool() ) {
2244 ========================
2245 idRenderSystemLocal::InitOpenGL
2246 ========================
2248 void idRenderSystemLocal::InitOpenGL( void ) {
2249 // if OpenGL isn't started, start it now
2250 if ( !glConfig.isInitialized ) {
2255 globalImages->ReloadAllImages();
2257 err = qglGetError();
2258 if ( err != GL_NO_ERROR ) {
2259 common->Printf( "glGetError() = 0x%x\n", err );
2265 ========================
2266 idRenderSystemLocal::ShutdownOpenGL
2267 ========================
2269 void idRenderSystemLocal::ShutdownOpenGL( void ) {
2270 // free the context and close the window
2271 R_ShutdownFrameData();
2273 glConfig.isInitialized = false;
2277 ========================
2278 idRenderSystemLocal::IsOpenGLRunning
2279 ========================
2281 bool idRenderSystemLocal::IsOpenGLRunning( void ) const {
2282 if ( !glConfig.isInitialized ) {
2289 ========================
2290 idRenderSystemLocal::IsFullScreen
2291 ========================
2293 bool idRenderSystemLocal::IsFullScreen( void ) const {
2294 return glConfig.isFullscreen;
2298 ========================
2299 idRenderSystemLocal::GetScreenWidth
2300 ========================
2302 int idRenderSystemLocal::GetScreenWidth( void ) const {
2303 return glConfig.vidWidth;
2307 ========================
2308 idRenderSystemLocal::GetScreenHeight
2309 ========================
2311 int idRenderSystemLocal::GetScreenHeight( void ) const {
2312 return glConfig.vidHeight;
2316 ========================
2317 idRenderSystemLocal::GetCardCaps
2318 ========================
2320 void idRenderSystemLocal::GetCardCaps( bool &oldCard, bool &nv10or20 ) {
2321 nv10or20 = ( tr.backEndRenderer == BE_NV10 || tr.backEndRenderer == BE_NV20 );
2322 oldCard = ( tr.backEndRenderer == BE_ARB || tr.backEndRenderer == BE_R200 || tr.backEndRenderer == BE_NV10 || tr.backEndRenderer == BE_NV20 );