}
}
-extern int c_rt_lights, c_rt_clears, c_rt_scissored;
-extern int c_rt_shadowmeshes, c_rt_shadowtris, c_rt_lightmeshes, c_rt_lighttris;
-extern int c_rtcached_shadowmeshes, c_rtcached_shadowtris;
void R_TimeReport_Start(void)
{
r_timereport_active = r_speeds.integer && cls.signon == SIGNONS && cls.state == ca_connected;
if (r_timereport_active)
{
speedstringcount = 0;
- sprintf(r_speeds_string,
- "org:'%+8.2f %+8.2f %+8.2f' dir:'%+2.3f %+2.3f %+2.3f'\n"
- "world:%6i faces%6i nodes%6i leafs%6i dlitwalls\n"
- "%5i models%5i bmodels%5i sprites%6i particles%4i dlights\n"
- "%6i modeltris%6i meshs%6i meshtris\n",
- r_vieworigin[0], r_vieworigin[1], r_vieworigin[2], r_viewforward[0], r_viewforward[1], r_viewforward[2],
- c_faces, c_nodes, c_leafs, c_light_polys,
- c_models, c_bmodels, c_sprites, c_particles, c_dlights,
- c_alias_polys, c_meshs, c_meshelements / 3);
-
- sprintf(r_speeds_string + strlen(r_speeds_string),
- "realtime lighting:%4i lights%4i clears%4i scissored\n"
- "dynamic: %6i shadowmeshes%6i shadowtris%6i lightmeshes%6i lighttris\n"
- "precomputed: %6i shadowmeshes%6i shadowtris\n",
- c_rt_lights, c_rt_clears, c_rt_scissored,
- c_rt_shadowmeshes, c_rt_shadowtris, c_rt_lightmeshes, c_rt_lighttris,
- c_rtcached_shadowmeshes, c_rtcached_shadowtris);
+ sprintf(r_speeds_string + strlen(r_speeds_string), "org:'%+8.2f %+8.2f %+8.2f' dir:'%+2.3f %+2.3f %+2.3f'\n", r_vieworigin[0], r_vieworigin[1], r_vieworigin[2], r_viewforward[0], r_viewforward[1], r_viewforward[2]);
+ sprintf(r_speeds_string + strlen(r_speeds_string), "world:%6i faces%6i nodes%6i leafs%6i dlitwalls\n", c_faces, c_nodes, c_leafs, c_light_polys);
+ sprintf(r_speeds_string + strlen(r_speeds_string), "%5i models%5i bmodels%5i sprites%6i particles%4i dlights\n", c_models, c_bmodels, c_sprites, c_particles, c_dlights);
+ sprintf(r_speeds_string + strlen(r_speeds_string), "%6i modeltris%6i meshs%6i meshtris\n", c_alias_polys, c_meshs, c_meshelements / 3);
+ sprintf(r_speeds_string + strlen(r_speeds_string), "bloom %s: %i copies (%i pixels) %i draws (%i pixels)\n", c_bloom ? "active" : "inactive", c_bloomcopies, c_bloomcopypixels, c_bloomdraws, c_bloomdrawpixels);
+ sprintf(r_speeds_string + strlen(r_speeds_string), "realtime lighting:%4i lights%4i clears%4i scissored\n", c_rt_lights, c_rt_clears, c_rt_scissored);
+ sprintf(r_speeds_string + strlen(r_speeds_string), "dynamic: %6i shadowmeshes%6i shadowtris%6i lightmeshes%6i lighttris\n", c_rt_shadowmeshes, c_rt_shadowtris, c_rt_lightmeshes, c_rt_lighttris);
+ sprintf(r_speeds_string + strlen(r_speeds_string), "precomputed: %6i shadowmeshes%6i shadowtris\n", c_rtcached_shadowmeshes, c_rtcached_shadowtris);
c_alias_polys = 0;
c_light_polys = 0;
c_bmodels = 0;
c_sprites = 0;
c_particles = 0;
+ c_dlights = 0;
c_meshs = 0;
c_meshelements = 0;
+ c_rt_lights = 0;
+ c_rt_clears = 0;
+ c_rt_scissored = 0;
+ c_rt_shadowmeshes = 0;
+ c_rt_shadowtris = 0;
+ c_rt_lightmeshes = 0;
+ c_rt_lighttris = 0;
+ c_rtcached_shadowmeshes = 0;
+ c_rtcached_shadowtris = 0;
+ c_bloom = 0;
+ c_bloomcopies = 0;
+ c_bloomcopypixels = 0;
+ c_bloomdraws = 0;
+ c_bloomdrawpixels = 0;
r_timereport_start = Sys_DoubleTime();
}
matrix4x4_t r_identitymatrix;
-int c_alias_polys, c_light_polys, c_faces, c_nodes, c_leafs, c_models, c_bmodels, c_sprites, c_particles, c_dlights;
+int c_alias_polys, c_light_polys, c_faces, c_nodes, c_leafs, c_models, c_bmodels, c_sprites, c_particles, c_dlights, c_meshs, c_meshelements, c_rt_lights, c_rt_clears, c_rt_scissored, c_rt_shadowmeshes, c_rt_shadowtris, c_rt_lightmeshes, c_rt_lighttris, c_rtcached_shadowmeshes, c_rtcached_shadowtris, c_bloom, c_bloomcopies, c_bloomcopypixels, c_bloomdraws, c_bloomdrawpixels;
// true during envmap command capture
qboolean envmap;
cvar_t r_waterscroll = {CVAR_SAVE, "r_waterscroll", "1"};
cvar_t r_watershader = {CVAR_SAVE, "r_watershader", "1"};
+cvar_t r_bloom = {CVAR_SAVE, "r_bloom", "0"};
+cvar_t r_bloom_intensity = {CVAR_SAVE, "r_bloom_intensity", "2"};
+cvar_t r_bloom_blur = {CVAR_SAVE, "r_bloom_blur", "8"};
+cvar_t r_bloom_resolution = {CVAR_SAVE, "r_bloom_resolution", "256"};
+cvar_t r_bloom_power = {CVAR_SAVE, "r_bloom_power", "4"};
+rtexturepool_t *r_main_texturepool;
+rtexture_t *r_bloom_texture_screen;
+rtexture_t *r_bloom_texture_bloom;
void R_ModulateColors(float *in, float *out, int verts, float r, float g, float b)
{
void gl_main_start(void)
{
+ r_main_texturepool = R_AllocTexturePool();
+ r_bloom_texture_screen = NULL;
+ r_bloom_texture_bloom = NULL;
}
void gl_main_shutdown(void)
{
+ // this seems to cause a already freed crash after a couple vid_restarts...
+ //R_FreeTexturePool(&r_main_texturepool);
+ r_main_texturepool = NULL;
+ r_bloom_texture_screen = NULL;
+ r_bloom_texture_bloom = NULL;
}
extern void CL_ParseEntityLump(char *entitystring);
Cvar_RegisterVariable(&r_waterscroll);
Cvar_RegisterVariable(&r_watershader);
Cvar_RegisterVariable(&r_drawcollisionbrushes);
+ Cvar_RegisterVariable(&r_bloom);
+ Cvar_RegisterVariable(&r_bloom_intensity);
+ Cvar_RegisterVariable(&r_bloom_blur);
+ Cvar_RegisterVariable(&r_bloom_resolution);
+ Cvar_RegisterVariable(&r_bloom_power);
if (gamemode == GAME_NEHAHRA || gamemode == GAME_NEXUIZ || gamemode == GAME_TENEBRAE)
Cvar_SetValue("r_fullbrights", 0);
R_RegisterModule("GL_Main", gl_main_start, gl_main_shutdown, gl_main_newmap);
static void R_BlendView(void)
{
rmeshstate_t m;
- float r;
- float vertex3f[3*3];
- if (r_refdef.viewblend[3] < 0.01f)
+ if (r_refdef.viewblend[3] < 0.01f && !r_bloom.integer)
return;
- R_Mesh_Matrix(&r_identitymatrix);
-
- memset(&m, 0, sizeof(m));
- m.pointer_vertex = vertex3f;
- R_Mesh_State(&m);
-
- GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ GL_SetupView_Mode_Ortho(0, 0, 1, 1, -10, 100);
GL_DepthMask(true);
- GL_DepthTest(false); // magic
- GL_Color(r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]);
- r = 64;
- vertex3f[0] = r_vieworigin[0] + r_viewforward[0] * 1.5 + r_viewleft[0] * r - r_viewup[0] * r;
- vertex3f[1] = r_vieworigin[1] + r_viewforward[1] * 1.5 + r_viewleft[1] * r - r_viewup[1] * r;
- vertex3f[2] = r_vieworigin[2] + r_viewforward[2] * 1.5 + r_viewleft[2] * r - r_viewup[2] * r;
- vertex3f[3] = r_vieworigin[0] + r_viewforward[0] * 1.5 + r_viewleft[0] * r + r_viewup[0] * r * 3;
- vertex3f[4] = r_vieworigin[1] + r_viewforward[1] * 1.5 + r_viewleft[1] * r + r_viewup[1] * r * 3;
- vertex3f[5] = r_vieworigin[2] + r_viewforward[2] * 1.5 + r_viewleft[2] * r + r_viewup[2] * r * 3;
- vertex3f[6] = r_vieworigin[0] + r_viewforward[0] * 1.5 - r_viewleft[0] * r * 3 - r_viewup[0] * r;
- vertex3f[7] = r_vieworigin[1] + r_viewforward[1] * 1.5 - r_viewleft[1] * r * 3 - r_viewup[1] * r;
- vertex3f[8] = r_vieworigin[2] + r_viewforward[2] * 1.5 - r_viewleft[2] * r * 3 - r_viewup[2] * r;
- R_Mesh_Draw(3, 1, polygonelements);
+ GL_DepthTest(false);
+ R_Mesh_Matrix(&r_identitymatrix);
+ varray_vertex3f[0] = 0;varray_vertex3f[1] = 0;varray_vertex3f[2] = 0;
+ varray_vertex3f[3] = 1;varray_vertex3f[4] = 0;varray_vertex3f[5] = 0;
+ varray_vertex3f[6] = 1;varray_vertex3f[7] = 1;varray_vertex3f[8] = 0;
+ varray_vertex3f[9] = 0;varray_vertex3f[10] = 1;varray_vertex3f[11] = 0;
+ if (r_bloom.integer && r_bloom_resolution.value >= 32 && r_bloom_power.integer >= 1 && r_bloom_power.integer < 100 && r_bloom_blur.value >= 0 && r_bloom_blur.value < 512)
+ {
+ int screenwidth, screenheight, bloomwidth, bloomheight, x, dobloomblend, range;
+ float xoffset, yoffset, r;
+ c_bloom++;
+ for (screenwidth = 1;screenwidth < vid.realwidth;screenwidth *= 2);
+ for (screenheight = 1;screenheight < vid.realheight;screenheight *= 2);
+ bloomwidth = min(r_view_width, r_bloom_resolution.integer);
+ bloomheight = min(r_view_height, r_bloom_resolution.integer);
+ varray_texcoord2f[0][0] = 0;
+ varray_texcoord2f[0][1] = (float)r_view_height / (float)screenheight;
+ varray_texcoord2f[0][2] = (float)r_view_width / (float)screenwidth;
+ varray_texcoord2f[0][3] = (float)r_view_height / (float)screenheight;
+ varray_texcoord2f[0][4] = (float)r_view_width / (float)screenwidth;
+ varray_texcoord2f[0][5] = 0;
+ varray_texcoord2f[0][6] = 0;
+ varray_texcoord2f[0][7] = 0;
+ varray_texcoord2f[1][0] = 0;
+ varray_texcoord2f[1][1] = (float)bloomheight / (float)screenheight;
+ varray_texcoord2f[1][2] = (float)bloomwidth / (float)screenwidth;
+ varray_texcoord2f[1][3] = (float)bloomheight / (float)screenheight;
+ varray_texcoord2f[1][4] = (float)bloomwidth / (float)screenwidth;
+ varray_texcoord2f[1][5] = 0;
+ varray_texcoord2f[1][6] = 0;
+ varray_texcoord2f[1][7] = 0;
+ if (!r_bloom_texture_screen)
+ r_bloom_texture_screen = R_LoadTexture2D(r_main_texturepool, "screen", screenwidth, screenheight, NULL, TEXTYPE_RGBA, TEXF_FORCENEAREST | TEXF_CLAMP | TEXF_ALWAYSPRECACHE, NULL);
+ if (!r_bloom_texture_bloom)
+ r_bloom_texture_bloom = R_LoadTexture2D(r_main_texturepool, "bloom", screenwidth, screenheight, NULL, TEXTYPE_RGBA, TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_ALWAYSPRECACHE, NULL);
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = varray_vertex3f;
+ m.pointer_texcoord[0] = varray_texcoord2f[0];
+ m.tex[0] = R_GetTexture(r_bloom_texture_screen);
+ R_Mesh_State(&m);
+ // copy view to a texture
+ GL_ActiveTexture(0);
+ qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.realheight - (r_view_y + r_view_height), r_view_width, r_view_height);
+ c_bloomcopies++;
+ c_bloomcopypixels += r_view_width * r_view_height;
+ // now scale it down to the bloom size and raise to a power of itself
+ qglViewport(r_view_x, vid.realheight - (r_view_y + bloomheight), bloomwidth, bloomheight);
+ // TODO: optimize with multitexture or GLSL
+ GL_BlendFunc(GL_ONE, GL_ZERO);
+ GL_Color(1, 1, 1, 1);
+ R_Mesh_Draw(4, 2, polygonelements);
+ c_bloomdraws++;
+ c_bloomdrawpixels += bloomwidth * bloomheight;
+ GL_BlendFunc(GL_DST_COLOR, GL_ZERO);
+ for (x = 1;x < r_bloom_power.integer;x++)
+ {
+ R_Mesh_Draw(4, 2, polygonelements);
+ c_bloomdraws++;
+ c_bloomdrawpixels += bloomwidth * bloomheight;
+ }
+ // copy the bloom view to a texture
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = varray_vertex3f;
+ m.tex[0] = R_GetTexture(r_bloom_texture_bloom);
+ m.pointer_texcoord[0] = varray_texcoord2f[2];
+ R_Mesh_State(&m);
+ GL_ActiveTexture(0);
+ qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.realheight - (r_view_y + bloomheight), bloomwidth, bloomheight);
+ c_bloomcopies++;
+ c_bloomcopypixels += bloomwidth * bloomheight;
+ // blend on at multiple offsets vertically
+ // TODO: do offset blends using GLSL
+ range = r_bloom_blur.integer;//(int)(r_bloom_blur.value * bloomwidth / 320);
+ GL_BlendFunc(GL_ONE, GL_ZERO);
+ for (x = -range;x <= range;x++)
+ {
+ xoffset = 0 / (float)bloomwidth * (float)bloomwidth / (float)screenwidth;
+ yoffset = x / (float)bloomheight * (float)bloomheight / (float)screenheight;
+ varray_texcoord2f[2][0] = xoffset+0;
+ varray_texcoord2f[2][1] = yoffset+(float)bloomheight / (float)screenheight;
+ varray_texcoord2f[2][2] = xoffset+(float)bloomwidth / (float)screenwidth;
+ varray_texcoord2f[2][3] = yoffset+(float)bloomheight / (float)screenheight;
+ varray_texcoord2f[2][4] = xoffset+(float)bloomwidth / (float)screenwidth;
+ varray_texcoord2f[2][5] = yoffset+0;
+ varray_texcoord2f[2][6] = xoffset+0;
+ varray_texcoord2f[2][7] = yoffset+0;
+ r = r_bloom_intensity.value/(range*2+1)*(1 - fabs(x*x)/(float)(range*range));
+ if (r < 0.01f)
+ continue;
+ GL_Color(r, r, r, 1);
+ R_Mesh_Draw(4, 2, polygonelements);
+ c_bloomdraws++;
+ c_bloomdrawpixels += bloomwidth * bloomheight;
+ GL_BlendFunc(GL_ONE, GL_ONE);
+ }
+ // copy the blurred bloom view to a texture
+ GL_ActiveTexture(0);
+ qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.realheight - (r_view_y + bloomheight), bloomwidth, bloomheight);
+ c_bloomcopies++;
+ c_bloomcopypixels += bloomwidth * bloomheight;
+ // blend on at multiple offsets horizontally
+ // TODO: do offset blends using GLSL
+ range = r_bloom_blur.integer * bloomheight / r_view_height;//(int)(r_bloom_blur.value * bloomwidth / 320);
+ GL_BlendFunc(GL_ONE, GL_ZERO);
+ for (x = -range;x <= range;x++)
+ {
+ xoffset = x / (float)bloomwidth * (float)bloomwidth / (float)screenwidth;
+ yoffset = 0 / (float)bloomheight * (float)bloomheight / (float)screenheight;
+ varray_texcoord2f[2][0] = xoffset+0;
+ varray_texcoord2f[2][1] = yoffset+(float)bloomheight / (float)screenheight;
+ varray_texcoord2f[2][2] = xoffset+(float)bloomwidth / (float)screenwidth;
+ varray_texcoord2f[2][3] = yoffset+(float)bloomheight / (float)screenheight;
+ varray_texcoord2f[2][4] = xoffset+(float)bloomwidth / (float)screenwidth;
+ varray_texcoord2f[2][5] = yoffset+0;
+ varray_texcoord2f[2][6] = xoffset+0;
+ varray_texcoord2f[2][7] = yoffset+0;
+ r = r_bloom_intensity.value/(range*2+1)*(1 - fabs(x*x)/(float)(range*range));
+ if (r < 0.01f)
+ continue;
+ GL_Color(r, r, r, 1);
+ R_Mesh_Draw(4, 2, polygonelements);
+ c_bloomdraws++;
+ c_bloomdrawpixels += bloomwidth * bloomheight;
+ GL_BlendFunc(GL_ONE, GL_ONE);
+ }
+ // copy the blurred bloom view to a texture
+ GL_ActiveTexture(0);
+ qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.realheight - (r_view_y + bloomheight), bloomwidth, bloomheight);
+ c_bloomcopies++;
+ c_bloomcopypixels += bloomwidth * bloomheight;
+ // go back to full view area
+ qglViewport(r_view_x, vid.realheight - (r_view_y + r_view_height), r_view_width, r_view_height);
+ // put the original view back in place
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = varray_vertex3f;
+ m.tex[0] = R_GetTexture(r_bloom_texture_screen);
+ m.pointer_texcoord[0] = varray_texcoord2f[0];
+#if 0
+ dobloomblend = false;
+#else
+ // do both in one pass if possible
+ if (r_textureunits.integer >= 2 && gl_combine.integer)
+ {
+ dobloomblend = false;
+ m.texcombinergb[1] = GL_ADD;
+ m.tex[1] = R_GetTexture(r_bloom_texture_bloom);
+ m.pointer_texcoord[1] = varray_texcoord2f[1];
+ }
+ else
+ dobloomblend = true;
+#endif
+ R_Mesh_State(&m);
+ GL_BlendFunc(GL_ONE, GL_ZERO);
+ GL_Color(1,1,1,1);
+ R_Mesh_Draw(4, 2, polygonelements);
+ c_bloomdraws++;
+ c_bloomdrawpixels += r_view_width * r_view_height;
+ // now blend on the bloom texture if multipass
+ if (dobloomblend)
+ {
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = varray_vertex3f;
+ m.tex[0] = R_GetTexture(r_bloom_texture_bloom);
+ m.pointer_texcoord[0] = varray_texcoord2f[1];
+ R_Mesh_State(&m);
+ GL_BlendFunc(GL_ONE, GL_ONE);
+ GL_Color(1,1,1,1);
+ R_Mesh_Draw(4, 2, polygonelements);
+ c_bloomdraws++;
+ c_bloomdrawpixels += r_view_width * r_view_height;
+ }
+ }
+ if (r_refdef.viewblend[3] >= 0.01f)
+ {
+ // apply a color tint to the whole view
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = varray_vertex3f;
+ R_Mesh_State(&m);
+ 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(4, 2, polygonelements);
+ }
}
void R_RenderScene(void);
void M_Background(int width, int height)
{
- menu_width = width;
- menu_height = height;
+ menu_width = bound(1, width, vid.conwidth);
+ menu_height = bound(1, height, vid.conheight);
menu_x = (vid.conwidth - menu_width) * 0.5;
menu_y = (vid.conheight - menu_height) * 0.5;
//DrawQ_Fill(menu_x, menu_y, menu_width, menu_height, 0, 0, 0, 0.5, 0);
int visible;
cachepic_t *p;
- M_Background(320, 240);
+ M_Background(320, bound(200, 32 + OPTIONS_ITEMS * 8, vid.conheight));
M_DrawPic(16, 4, "gfx/qplaque.lmp");
p = Draw_CachePic("gfx/p_option.lmp");
optnum = 0;
optcursor = options_cursor;
- visible = (vid.conheight - 32) / 8;
+ visible = (menu_height - 32) / 8;
opty = 32 - bound(0, optcursor - (visible >> 1), max(0, OPTIONS_ITEMS - visible)) * 8;
M_Options_PrintCommand( "Customize controls", true);
int visible;
cachepic_t *p;
- M_Background(320, 200);
+ M_Background(320, bound(200, 32 + OPTIONS_EFFECTS_ITEMS * 8, vid.conheight));
M_DrawPic(16, 4, "gfx/qplaque.lmp");
p = Draw_CachePic("gfx/p_option.lmp");
optcursor = options_effects_cursor;
optnum = 0;
- visible = (vid.conheight - 32) / 8;
+ visible = (menu_height - 32) / 8;
opty = 32 - bound(0, optcursor - (visible >> 1), max(0, OPTIONS_EFFECTS_ITEMS - visible)) * 8;
M_Options_PrintSlider( " Lights Per Model", true, r_modellights.value, 0, 8);
}
-#define OPTIONS_GRAPHICS_ITEMS 7
+#define OPTIONS_GRAPHICS_ITEMS 12
int options_graphics_cursor;
extern cvar_t r_shadow_realtime_world_dlightshadows;
extern cvar_t r_shadow_realtime_world_lightmaps;
extern cvar_t r_shadow_realtime_world_shadows;
+extern cvar_t r_bloom;
+extern cvar_t r_bloom_intensity;
+extern cvar_t r_bloom_power;
+extern cvar_t r_bloom_blur;
+extern cvar_t r_bloom_resolution;
void M_Menu_Options_Graphics_AdjustSliders (int dir)
{
else if (options_graphics_cursor == optnum++) Cvar_SetValueQuick (&r_shadow_realtime_world_dlightshadows, !r_shadow_realtime_world_dlightshadows.integer);
else if (options_graphics_cursor == optnum++) Cvar_SetValueQuick (&r_shadow_realtime_world_lightmaps, bound(0, r_shadow_realtime_world_lightmaps.value + dir * 0.1, 1));
else if (options_graphics_cursor == optnum++) Cvar_SetValueQuick (&r_shadow_realtime_world_shadows, !r_shadow_realtime_world_shadows.integer);
+ else if (options_graphics_cursor == optnum++) Cvar_SetValueQuick (&r_bloom, !r_bloom.integer);
+ else if (options_graphics_cursor == optnum++) Cvar_SetValueQuick (&r_bloom_intensity, bound(1, r_bloom_intensity.value + dir * 1, 16));
+ else if (options_graphics_cursor == optnum++) Cvar_SetValueQuick (&r_bloom_power, bound(1, r_bloom_power.value + dir * 1, 16));
+ else if (options_graphics_cursor == optnum++) Cvar_SetValueQuick (&r_bloom_blur, bound(1, r_bloom_blur.value + dir * 1, 16));
+ else if (options_graphics_cursor == optnum++) Cvar_SetValueQuick (&r_bloom_resolution, bound(64, r_bloom_resolution.value + dir * 64, 2048));
}
int visible;
cachepic_t *p;
- M_Background(320, 200);
+ M_Background(320, bound(200, 32 + OPTIONS_GRAPHICS_ITEMS * 8, vid.conheight));
M_DrawPic(16, 4, "gfx/qplaque.lmp");
p = Draw_CachePic("gfx/p_option.lmp");
optcursor = options_graphics_cursor;
optnum = 0;
- visible = (vid.conheight - 32) / 8;
+ visible = (menu_height - 32) / 8;
opty = 32 - bound(0, optcursor - (visible >> 1), max(0, OPTIONS_GRAPHICS_ITEMS - visible)) * 8;
M_Options_PrintSlider( " Gloss Mode", true, r_shadow_gloss.integer, 0, 2);
M_Options_PrintCheckbox("RT World DLight Shadows", true, r_shadow_realtime_world_dlightshadows.integer);
M_Options_PrintSlider( " RT World Lightmaps", true, r_shadow_realtime_world_lightmaps.value, 0, 1);
M_Options_PrintCheckbox(" RT World Shadow", true, r_shadow_realtime_world_shadows.integer);
+ M_Options_PrintCheckbox(" Bloom Effect", true, r_bloom.integer);
+ M_Options_PrintSlider( " Bloom Intensity", true, r_bloom_intensity.value, 1, 16);
+ M_Options_PrintSlider( " Bloom Power", true, r_bloom_power.value, 1, 16);
+ M_Options_PrintSlider( " Bloom Blur", true, r_bloom_blur.value, 1, 16);
+ M_Options_PrintSlider( " Bloom Resolution", true, r_bloom_resolution.value, 64, 2048);
}
optcursor = options_colorcontrol_cursor;
optnum = 0;
- visible = (vid.conheight - 32) / 8;
+ visible = (menu_height - 32) / 8;
opty = 32 - bound(0, optcursor - (visible >> 1), max(0, OPTIONS_COLORCONTROL_ITEMS - visible)) * 8;
M_Options_PrintCommand( " Reset to defaults", true);
s = va("%i/%i masters %i/%i servers", masterreplycount, masterquerycount, serverreplycount, serverquerycount);
M_PrintRed((640 - strlen(s) * 8) / 2, 32, s);
if (*m_return_reason)
- M_Print(16, vid.conheight - 8, m_return_reason);
+ M_Print(16, menu_height - 8, m_return_reason);
y = 48;
- visible = (vid.conheight - 16 - y) / 8;
+ visible = (menu_height - 16 - y) / 8;
start = bound(0, slist_cursor - (visible >> 1), hostCacheCount - visible);
end = min(start + visible, hostCacheCount);