+ DrawQ_Finish();
+
+ // GL is weird because it's bottom to top, r_view.y is top to bottom
+ qglViewport(r_view.x, vid.height - (r_view.y + r_view.height), r_view.width, r_view.height);CHECKGLERROR
+ R_SetupView(&r_view.matrix);
+ GL_Scissor(r_view.x, r_view.y, r_view.width, r_view.height);
+ GL_Color(1, 1, 1, 1);
+ GL_ColorMask(r_view.colormask[0], r_view.colormask[1], r_view.colormask[2], 1);
+ GL_BlendFunc(GL_ONE, GL_ZERO);
+ GL_AlphaTest(false);
+ GL_ScissorTest(true);
+ GL_DepthMask(true);
+ GL_DepthTest(true);
+ R_Mesh_Matrix(&identitymatrix);
+ R_Mesh_ResetTextureState();
+ qglPolygonOffset(r_refdef.polygonfactor, r_refdef.polygonoffset);CHECKGLERROR
+ qglEnable(GL_POLYGON_OFFSET_FILL);CHECKGLERROR
+ qglDepthFunc(GL_LEQUAL);CHECKGLERROR
+ qglDisable(GL_STENCIL_TEST);CHECKGLERROR
+ qglStencilMask(~0);CHECKGLERROR
+ qglStencilFunc(GL_ALWAYS, 128, ~0);CHECKGLERROR
+ qglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);CHECKGLERROR
+ GL_CullFace(GL_FRONT); // quake is backwards, this culls back faces
+}
+
+/*
+ R_Bloom_SetupShader(
+"// bloom shader\n"
+"// written by Forest 'LordHavoc' Hale\n"
+"\n"
+"// common definitions between vertex shader and fragment shader:\n"
+"\n"
+"#ifdef __GLSL_CG_DATA_TYPES\n"
+"#define myhalf half\n"
+"#define myhvec2 hvec2\n"
+"#define myhvec3 hvec3\n"
+"#define myhvec4 hvec4\n"
+"#else\n"
+"#define myhalf float\n"
+"#define myhvec2 vec2\n"
+"#define myhvec3 vec3\n"
+"#define myhvec4 vec4\n"
+"#endif\n"
+"\n"
+"varying vec2 ScreenTexCoord;\n"
+"varying vec2 BloomTexCoord;\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"// vertex shader specific:\n"
+"#ifdef VERTEX_SHADER\n"
+"\n"
+"void main(void)\n"
+"{\n"
+" ScreenTexCoord = vec2(gl_MultiTexCoord0);\n"
+" BloomTexCoord = vec2(gl_MultiTexCoord1);\n"
+" // transform vertex to camera space, using ftransform to match non-VS\n"
+" // rendering\n"
+" gl_Position = ftransform();\n"
+"}\n"
+"\n"
+"#endif // VERTEX_SHADER\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"// fragment shader specific:\n"
+"#ifdef FRAGMENT_SHADER\n"
+"\n"
+"void main(void)\n"
+"{\n"
+" int x, y;
+" myhvec3 color = myhvec3(texture2D(Texture_Screen, ScreenTexCoord));\n"
+" for (x = -BLUR_X;x <= BLUR_X;x++)
+" color.rgb += myhvec3(texture2D(Texture_Bloom, BloomTexCoord));\n"
+" color.rgb += myhvec3(texture2D(Texture_Bloom, BloomTexCoord));\n"
+" color.rgb += myhvec3(texture2D(Texture_Bloom, BloomTexCoord));\n"
+" color.rgb += myhvec3(texture2D(Texture_Bloom, BloomTexCoord));\n"
+
+" gl_FragColor = vec4(color);\n"
+"}\n"
+"\n"
+"#endif // FRAGMENT_SHADER\n"
+*/
+
+void R_RenderScene(void);
+
+void R_Bloom_StartFrame(void)
+{
+ int bloomtexturewidth, bloomtextureheight, screentexturewidth, screentextureheight;
+
+ // set bloomwidth and bloomheight to the bloom resolution that will be
+ // used (often less than the screen resolution for faster rendering)
+ r_bloomstate.bloomwidth = bound(1, r_bloom_resolution.integer, r_view.width);
+ r_bloomstate.bloomheight = r_bloomstate.bloomwidth * r_view.height / r_view.width;
+ r_bloomstate.bloomheight = bound(1, r_bloomstate.bloomheight, r_view.height);
+
+ // calculate desired texture sizes
+ if (gl_support_arb_texture_non_power_of_two)
+ {
+ screentexturewidth = r_view.width;
+ screentextureheight = r_view.height;
+ bloomtexturewidth = r_bloomstate.bloomwidth;
+ bloomtextureheight = r_bloomstate.bloomheight;
+ }
+ else
+ {
+ for (screentexturewidth = 1;screentexturewidth < vid.width ;screentexturewidth *= 2);
+ for (screentextureheight = 1;screentextureheight < vid.height ;screentextureheight *= 2);
+ for (bloomtexturewidth = 1;bloomtexturewidth < r_bloomstate.bloomwidth ;bloomtexturewidth *= 2);
+ for (bloomtextureheight = 1;bloomtextureheight < r_bloomstate.bloomheight;bloomtextureheight *= 2);
+ }
+
+ if (r_hdr.integer)
+ {
+ screentexturewidth = screentextureheight = 0;
+ }
+ else if (r_bloom.integer)
+ {
+ }
+ else
+ {
+ screentexturewidth = screentextureheight = 0;
+ bloomtexturewidth = bloomtextureheight = 0;
+ }
+
+ if ((!bloomtexturewidth && !bloomtextureheight) || r_bloom_resolution.integer < 4 || r_bloom_blur.value < 1 || r_bloom_blur.value >= 512 || screentexturewidth > gl_max_texture_size || screentextureheight > gl_max_texture_size || bloomtexturewidth > gl_max_texture_size || bloomtextureheight > gl_max_texture_size)
+ {
+ // can't use bloom if the parameters are too weird
+ // can't use bloom if the card does not support the texture size
+ if (r_bloomstate.texture_screen)
+ R_FreeTexture(r_bloomstate.texture_screen);
+ if (r_bloomstate.texture_bloom)
+ R_FreeTexture(r_bloomstate.texture_bloom);
+ memset(&r_bloomstate, 0, sizeof(r_bloomstate));
+ return;
+ }
+
+ r_bloomstate.enabled = true;
+ r_bloomstate.hdr = r_hdr.integer != 0;
+
+ // allocate textures as needed
+ if (r_bloomstate.screentexturewidth != screentexturewidth || r_bloomstate.screentextureheight != screentextureheight)
+ {
+ if (r_bloomstate.texture_screen)
+ R_FreeTexture(r_bloomstate.texture_screen);
+ r_bloomstate.texture_screen = NULL;
+ r_bloomstate.screentexturewidth = screentexturewidth;
+ r_bloomstate.screentextureheight = screentextureheight;
+ if (r_bloomstate.screentexturewidth && r_bloomstate.screentextureheight)
+ r_bloomstate.texture_screen = R_LoadTexture2D(r_main_texturepool, "screen", r_bloomstate.screentexturewidth, r_bloomstate.screentextureheight, NULL, TEXTYPE_RGBA, TEXF_FORCENEAREST | TEXF_CLAMP | TEXF_ALWAYSPRECACHE, NULL);
+ }
+ if (r_bloomstate.bloomtexturewidth != bloomtexturewidth || r_bloomstate.bloomtextureheight != bloomtextureheight)
+ {
+ if (r_bloomstate.texture_bloom)
+ R_FreeTexture(r_bloomstate.texture_bloom);
+ r_bloomstate.texture_bloom = NULL;
+ r_bloomstate.bloomtexturewidth = bloomtexturewidth;
+ r_bloomstate.bloomtextureheight = bloomtextureheight;
+ if (r_bloomstate.bloomtexturewidth && r_bloomstate.bloomtextureheight)
+ r_bloomstate.texture_bloom = R_LoadTexture2D(r_main_texturepool, "bloom", r_bloomstate.bloomtexturewidth, r_bloomstate.bloomtextureheight, NULL, TEXTYPE_RGBA, TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_ALWAYSPRECACHE, NULL);
+ }
+
+ // set up a texcoord array for the full resolution screen image
+ // (we have to keep this around to copy back during final render)
+ r_bloomstate.screentexcoord2f[0] = 0;
+ r_bloomstate.screentexcoord2f[1] = (float)r_view.height / (float)r_bloomstate.screentextureheight;
+ r_bloomstate.screentexcoord2f[2] = (float)r_view.width / (float)r_bloomstate.screentexturewidth;
+ r_bloomstate.screentexcoord2f[3] = (float)r_view.height / (float)r_bloomstate.screentextureheight;
+ r_bloomstate.screentexcoord2f[4] = (float)r_view.width / (float)r_bloomstate.screentexturewidth;
+ r_bloomstate.screentexcoord2f[5] = 0;
+ r_bloomstate.screentexcoord2f[6] = 0;
+ r_bloomstate.screentexcoord2f[7] = 0;
+
+ // set up a texcoord array for the reduced resolution bloom image
+ // (which will be additive blended over the screen image)
+ r_bloomstate.bloomtexcoord2f[0] = 0;
+ r_bloomstate.bloomtexcoord2f[1] = (float)r_bloomstate.bloomheight / (float)r_bloomstate.bloomtextureheight;
+ r_bloomstate.bloomtexcoord2f[2] = (float)r_bloomstate.bloomwidth / (float)r_bloomstate.bloomtexturewidth;
+ r_bloomstate.bloomtexcoord2f[3] = (float)r_bloomstate.bloomheight / (float)r_bloomstate.bloomtextureheight;
+ r_bloomstate.bloomtexcoord2f[4] = (float)r_bloomstate.bloomwidth / (float)r_bloomstate.bloomtexturewidth;
+ r_bloomstate.bloomtexcoord2f[5] = 0;
+ r_bloomstate.bloomtexcoord2f[6] = 0;
+ r_bloomstate.bloomtexcoord2f[7] = 0;
+}
+
+void R_Bloom_CopyScreenTexture(float colorscale)
+{
+ r_refdef.stats.bloom++;
+
+ R_ResetViewRendering2D();
+ R_Mesh_VertexPointer(r_screenvertex3f);
+ R_Mesh_ColorPointer(NULL);
+ R_Mesh_TexCoordPointer(0, 2, r_bloomstate.screentexcoord2f);
+ R_Mesh_TexBind(0, R_GetTexture(r_bloomstate.texture_screen));
+
+ // copy view into the screen texture
+ GL_ActiveTexture(0);
+ CHECKGLERROR
+ qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view.x, vid.height - (r_view.y + r_view.height), r_view.width, r_view.height);CHECKGLERROR
+ r_refdef.stats.bloom_copypixels += r_view.width * r_view.height;
+
+ // now scale it down to the bloom texture size
+ CHECKGLERROR
+ qglViewport(r_view.x, vid.height - (r_view.y + r_bloomstate.bloomheight), r_bloomstate.bloomwidth, r_bloomstate.bloomheight);CHECKGLERROR
+ GL_BlendFunc(GL_ONE, GL_ZERO);
+ GL_Color(colorscale, colorscale, colorscale, 1);
+ // TODO: optimize with multitexture or GLSL
+ R_Mesh_Draw(0, 4, 2, polygonelements);
+ r_refdef.stats.bloom_drawpixels += r_bloomstate.bloomwidth * r_bloomstate.bloomheight;
+
+ // we now have a bloom image in the framebuffer
+ // copy it into the bloom image texture for later processing
+ R_Mesh_TexBind(0, R_GetTexture(r_bloomstate.texture_bloom));
+ GL_ActiveTexture(0);
+ CHECKGLERROR
+ qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view.x, vid.height - (r_view.y + r_bloomstate.bloomheight), r_bloomstate.bloomwidth, r_bloomstate.bloomheight);CHECKGLERROR
+ r_refdef.stats.bloom_copypixels += r_bloomstate.bloomwidth * r_bloomstate.bloomheight;
+}
+
+void R_Bloom_CopyHDRTexture(void)
+{
+ R_Mesh_TexBind(0, R_GetTexture(r_bloomstate.texture_bloom));
+ GL_ActiveTexture(0);
+ CHECKGLERROR
+ qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view.x, vid.height - (r_view.y + r_view.height), r_view.width, r_view.height);CHECKGLERROR
+ r_refdef.stats.bloom_copypixels += r_view.width * r_view.height;
+}
+
+void R_Bloom_MakeTexture(void)
+{
+ int x, range, dir;
+ float xoffset, yoffset, r, brighten;
+
+ r_refdef.stats.bloom++;
+
+ R_ResetViewRendering2D();
+ R_Mesh_VertexPointer(r_screenvertex3f);
+ R_Mesh_ColorPointer(NULL);
+
+ // we have a bloom image in the framebuffer
+ CHECKGLERROR
+ qglViewport(r_view.x, vid.height - (r_view.y + r_bloomstate.bloomheight), r_bloomstate.bloomwidth, r_bloomstate.bloomheight);CHECKGLERROR
+
+ for (x = 1;x < r_bloom_colorexponent.value;)
+ {
+ x *= 2;
+ r = bound(0, r_bloom_colorexponent.value / x, 1);
+ GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
+ GL_Color(r, r, r, 1);
+ R_Mesh_TexBind(0, R_GetTexture(r_bloomstate.texture_bloom));
+ R_Mesh_TexCoordPointer(0, 2, r_bloomstate.bloomtexcoord2f);
+ R_Mesh_Draw(0, 4, 2, polygonelements);
+ r_refdef.stats.bloom_drawpixels += r_bloomstate.bloomwidth * r_bloomstate.bloomheight;
+
+ // copy the vertically blurred bloom view to a texture
+ GL_ActiveTexture(0);
+ CHECKGLERROR
+ qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view.x, vid.height - (r_view.y + r_bloomstate.bloomheight), r_bloomstate.bloomwidth, r_bloomstate.bloomheight);CHECKGLERROR
+ r_refdef.stats.bloom_copypixels += r_bloomstate.bloomwidth * r_bloomstate.bloomheight;
+ }
+
+ range = r_bloom_blur.integer * r_bloomstate.bloomwidth / 320;
+ brighten = r_bloom_brighten.value;
+ if (r_hdr.integer)
+ brighten *= r_hdr_range.value;
+ R_Mesh_TexBind(0, R_GetTexture(r_bloomstate.texture_bloom));
+ R_Mesh_TexCoordPointer(0, 2, r_bloomstate.offsettexcoord2f);
+
+ for (dir = 0;dir < 2;dir++)
+ {
+ // blend on at multiple vertical offsets to achieve a vertical blur
+ // TODO: do offset blends using GLSL
+ GL_BlendFunc(GL_ONE, GL_ZERO);
+ for (x = -range;x <= range;x++)
+ {
+ if (!dir){xoffset = 0;yoffset = x;}
+ else {xoffset = x;yoffset = 0;}
+ xoffset /= (float)r_bloomstate.bloomtexturewidth;
+ yoffset /= (float)r_bloomstate.bloomtextureheight;
+ // compute a texcoord array with the specified x and y offset
+ r_bloomstate.offsettexcoord2f[0] = xoffset+0;
+ r_bloomstate.offsettexcoord2f[1] = yoffset+(float)r_bloomstate.bloomheight / (float)r_bloomstate.bloomtextureheight;
+ r_bloomstate.offsettexcoord2f[2] = xoffset+(float)r_bloomstate.bloomwidth / (float)r_bloomstate.bloomtexturewidth;
+ r_bloomstate.offsettexcoord2f[3] = yoffset+(float)r_bloomstate.bloomheight / (float)r_bloomstate.bloomtextureheight;
+ r_bloomstate.offsettexcoord2f[4] = xoffset+(float)r_bloomstate.bloomwidth / (float)r_bloomstate.bloomtexturewidth;
+ r_bloomstate.offsettexcoord2f[5] = yoffset+0;
+ r_bloomstate.offsettexcoord2f[6] = xoffset+0;
+ r_bloomstate.offsettexcoord2f[7] = yoffset+0;
+ // this r value looks like a 'dot' particle, fading sharply to
+ // black at the edges
+ // (probably not realistic but looks good enough)
+ //r = ((range*range+1)/((float)(x*x+1)))/(range*2+1);
+ //r = (dir ? 1.0f : brighten)/(range*2+1);
+ r = (dir ? 1.0f : brighten)/(range*2+1)*(1 - x*x/(float)(range*range));
+ GL_Color(r, r, r, 1);
+ R_Mesh_Draw(0, 4, 2, polygonelements);
+ r_refdef.stats.bloom_drawpixels += r_bloomstate.bloomwidth * r_bloomstate.bloomheight;
+ GL_BlendFunc(GL_ONE, GL_ONE);
+ }
+
+ // copy the vertically blurred bloom view to a texture
+ GL_ActiveTexture(0);
+ CHECKGLERROR
+ qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view.x, vid.height - (r_view.y + r_bloomstate.bloomheight), r_bloomstate.bloomwidth, r_bloomstate.bloomheight);CHECKGLERROR
+ r_refdef.stats.bloom_copypixels += r_bloomstate.bloomwidth * r_bloomstate.bloomheight;
+ }
+
+ // apply subtract last
+ // (just like it would be in a GLSL shader)
+ if (r_bloom_colorsubtract.value > 0 && gl_support_ext_blend_subtract)
+ {
+ GL_BlendFunc(GL_ONE, GL_ZERO);
+ R_Mesh_TexBind(0, R_GetTexture(r_bloomstate.texture_bloom));
+ R_Mesh_TexCoordPointer(0, 2, r_bloomstate.bloomtexcoord2f);
+ GL_Color(1, 1, 1, 1);
+ R_Mesh_Draw(0, 4, 2, polygonelements);
+ r_refdef.stats.bloom_drawpixels += r_bloomstate.bloomwidth * r_bloomstate.bloomheight;
+
+ GL_BlendFunc(GL_ONE, GL_ONE);
+ qglBlendEquationEXT(GL_FUNC_REVERSE_SUBTRACT_EXT);
+ R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
+ R_Mesh_TexCoordPointer(0, 2, r_bloomstate.bloomtexcoord2f);
+ GL_Color(r_bloom_colorsubtract.value, r_bloom_colorsubtract.value, r_bloom_colorsubtract.value, 1);
+ R_Mesh_Draw(0, 4, 2, polygonelements);
+ r_refdef.stats.bloom_drawpixels += r_bloomstate.bloomwidth * r_bloomstate.bloomheight;
+ qglBlendEquationEXT(GL_FUNC_ADD_EXT);
+
+ // copy the darkened bloom view to a texture
+ R_Mesh_TexBind(0, R_GetTexture(r_bloomstate.texture_bloom));
+ GL_ActiveTexture(0);
+ CHECKGLERROR
+ qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view.x, vid.height - (r_view.y + r_bloomstate.bloomheight), r_bloomstate.bloomwidth, r_bloomstate.bloomheight);CHECKGLERROR
+ r_refdef.stats.bloom_copypixels += r_bloomstate.bloomwidth * r_bloomstate.bloomheight;
+ }
+}
+
+void R_HDR_RenderBloomTexture(void)
+{
+ int oldwidth, oldheight;
+
+ oldwidth = r_view.width;
+ oldheight = r_view.height;
+ r_view.width = r_bloomstate.bloomwidth;
+ r_view.height = r_bloomstate.bloomheight;
+
+ // TODO: support GL_EXT_framebuffer_object rather than reusing the framebuffer? it might improve SLI performance.
+ // TODO: add exposure compensation features
+ // TODO: add fp16 framebuffer support
+
+ r_view.colorscale = r_bloom_colorscale.value * r_hdr_scenebrightness.value;
+ if (r_hdr.integer)
+ r_view.colorscale /= r_hdr_range.value;
+ R_RenderScene();
+
+ R_ResetViewRendering2D();
+
+ R_Bloom_CopyHDRTexture();
+ R_Bloom_MakeTexture();
+
+ R_ResetViewRendering3D();
+
+ R_ClearScreen();
+ if (r_timereport_active)
+ R_TimeReport("clear");
+
+
+ // restore the view settings
+ r_view.width = oldwidth;
+ r_view.height = oldheight;
+}
+
+static void R_BlendView(void)
+{
+ if (r_bloomstate.enabled && r_bloomstate.hdr)
+ {
+ // render high dynamic range bloom effect
+ // the bloom texture was made earlier this render, so we just need to
+ // blend it onto the screen...
+ R_ResetViewRendering2D();
+ R_Mesh_VertexPointer(r_screenvertex3f);
+ R_Mesh_ColorPointer(NULL);
+ GL_Color(1, 1, 1, 1);
+ GL_BlendFunc(GL_ONE, GL_ONE);
+ R_Mesh_TexBind(0, R_GetTexture(r_bloomstate.texture_bloom));
+ R_Mesh_TexCoordPointer(0, 2, r_bloomstate.bloomtexcoord2f);
+ R_Mesh_Draw(0, 4, 2, polygonelements);
+ r_refdef.stats.bloom_drawpixels += r_view.width * r_view.height;
+ }
+ else if (r_bloomstate.enabled)
+ {
+ // render simple bloom effect
+ // copy the screen and shrink it and darken it for the bloom process
+ R_Bloom_CopyScreenTexture(r_bloom_colorscale.value);
+ // make the bloom texture
+ R_Bloom_MakeTexture();
+ // put the original screen image back in place and blend the bloom
+ // texture on it
+ R_ResetViewRendering2D();
+ R_Mesh_VertexPointer(r_screenvertex3f);
+ R_Mesh_ColorPointer(NULL);
+ GL_Color(1, 1, 1, 1);
+ GL_BlendFunc(GL_ONE, GL_ZERO);
+ // do both in one pass if possible
+ R_Mesh_TexBind(0, R_GetTexture(r_bloomstate.texture_bloom));
+ R_Mesh_TexCoordPointer(0, 2, r_bloomstate.bloomtexcoord2f);
+ if (r_textureunits.integer >= 2 && gl_combine.integer)
+ {
+ R_Mesh_TexCombine(1, GL_ADD, GL_ADD, 1, 1);
+ R_Mesh_TexBind(1, R_GetTexture(r_bloomstate.texture_screen));
+ R_Mesh_TexCoordPointer(1, 2, r_bloomstate.screentexcoord2f);
+ }
+ else
+ {
+ R_Mesh_Draw(0, 4, 2, polygonelements);
+ r_refdef.stats.bloom_drawpixels += r_view.width * r_view.height;
+ // now blend on the bloom texture
+ GL_BlendFunc(GL_ONE, GL_ONE);
+ R_Mesh_TexBind(0, R_GetTexture(r_bloomstate.texture_screen));
+ R_Mesh_TexCoordPointer(0, 2, r_bloomstate.screentexcoord2f);
+ }
+ R_Mesh_Draw(0, 4, 2, polygonelements);
+ r_refdef.stats.bloom_drawpixels += r_view.width * r_view.height;
+ }
+ if (r_refdef.viewblend[3] >= (1.0f / 256.0f))
+ {
+ // apply a color tint to the whole view
+ R_ResetViewRendering2D();
+ R_Mesh_VertexPointer(r_screenvertex3f);
+ R_Mesh_ColorPointer(NULL);
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ GL_Color(r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]);
+ R_Mesh_Draw(0, 4, 2, polygonelements);
+ }
+}
+
+void R_RenderScene(void);
+
+matrix4x4_t r_waterscrollmatrix;
+
+void R_UpdateVariables(void)
+{
+ R_Textures_Frame();
+
+ r_refdef.farclip = 4096;
+ if (r_refdef.worldmodel)
+ r_refdef.farclip += VectorDistance(r_refdef.worldmodel->normalmins, r_refdef.worldmodel->normalmaxs);
+ r_refdef.nearclip = bound (0.001f, r_nearclip.value, r_refdef.farclip - 1.0f);
+
+ r_refdef.polygonfactor = 0;
+ r_refdef.polygonoffset = 0;
+ r_refdef.shadowpolygonfactor = r_refdef.polygonfactor + r_shadow_shadow_polygonfactor.value;
+ r_refdef.shadowpolygonoffset = r_refdef.polygonoffset + r_shadow_shadow_polygonoffset.value;
+
+ r_refdef.rtworld = r_shadow_realtime_world.integer;
+ r_refdef.rtworldshadows = r_shadow_realtime_world_shadows.integer && gl_stencil;
+ r_refdef.rtdlight = (r_shadow_realtime_world.integer || r_shadow_realtime_dlight.integer) && !gl_flashblend.integer && r_dynamic.integer;
+ r_refdef.rtdlightshadows = r_refdef.rtdlight && (r_refdef.rtworld ? r_shadow_realtime_world_dlightshadows.integer : r_shadow_realtime_dlight_shadows.integer) && gl_stencil;
+ r_refdef.lightmapintensity = r_refdef.rtworld ? r_shadow_realtime_world_lightmaps.value : 1;
+ if (r_showsurfaces.integer)
+ {
+ r_refdef.rtworld = false;
+ r_refdef.rtworldshadows = false;
+ r_refdef.rtdlight = false;
+ r_refdef.rtdlightshadows = false;
+ r_refdef.lightmapintensity = 0;
+ }
+
+ if (gamemode == GAME_NEHAHRA)
+ {
+ if (gl_fogenable.integer)
+ {
+ r_refdef.oldgl_fogenable = true;
+ r_refdef.fog_density = gl_fogdensity.value;
+ r_refdef.fog_red = gl_fogred.value;