X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=vid_shared.c;h=85d3ec372091a986ddc3a655de0d39d54a441541;hb=9615163fe2a5dfa13ef832d0d0e10b9cda619840;hp=fd5cbc71bc5365d7a64769bea3f90ec851107141;hpb=5737591d891d69836735abb645a1b173baaabe96;p=xonotic%2Fdarkplaces.git diff --git a/vid_shared.c b/vid_shared.c index fd5cbc71..85d3ec37 100644 --- a/vid_shared.c +++ b/vid_shared.c @@ -1,6 +1,7 @@ #include "quakedef.h" #include "cdaudio.h" +#include "image.h" #ifdef SUPPORTD3D #include @@ -71,10 +72,6 @@ int vid_xinputindex = -1; // global video state viddef_t vid; -// LordHavoc: these are only set in wgl -qboolean isG200 = false; // LordHavoc: the Matrox G200 can't do per pixel alpha, and it uses a D3D driver for GL... ugh... -qboolean isRagePro = false; // LordHavoc: the ATI Rage Pro has limitations with per pixel alpha (the color scaler does not apply to per pixel alpha images...), although not as bad as a G200. - // AK FIXME -> input_dest qboolean in_client_mouse = true; @@ -138,7 +135,7 @@ cvar_t joy_x360_sensitivityroll = {0, "joy_x360_sensitivityroll", "1", "movement // cvars for DPSOFTRAST cvar_t vid_soft = {CVAR_SAVE, "vid_soft", "0", "enables use of the DarkPlaces Software Rasterizer rather than OpenGL or Direct3D"}; -cvar_t vid_soft_threads = {CVAR_SAVE, "vid_soft_threads", "2", "the number of threads the DarkPlaces Software Rasterizer should use"}; +cvar_t vid_soft_threads = {CVAR_SAVE, "vid_soft_threads", "8", "the number of threads the DarkPlaces Software Rasterizer should use"}; cvar_t vid_soft_interlace = {CVAR_SAVE, "vid_soft_interlace", "1", "whether the DarkPlaces Software Rasterizer should interlace the screen bands occupied by each thread"}; // we don't know until we try it! @@ -164,7 +161,6 @@ cvar_t vid_width = {CVAR_SAVE, "vid_width", "640", "resolution"}; cvar_t vid_height = {CVAR_SAVE, "vid_height", "480", "resolution"}; cvar_t vid_bitsperpixel = {CVAR_SAVE, "vid_bitsperpixel", "32", "how many bits per pixel to render at (32 or 16, 32 is recommended)"}; cvar_t vid_samples = {CVAR_SAVE, "vid_samples", "1", "how many anti-aliasing samples per pixel to request from the graphics driver (4 is recommended, 1 is faster)"}; -cvar_t vid_multisampling = {CVAR_SAVE, "vid_multisampling", "0", "Make use of GL_AGB_MULTISAMPLING for advaced anti-aliasing techniques such as Alpha-To-Coverage, not yet finished"}; cvar_t vid_refreshrate = {CVAR_SAVE, "vid_refreshrate", "60", "refresh rate to use, in hz (higher values flicker less, if supported by your monitor)"}; cvar_t vid_userefreshrate = {CVAR_SAVE, "vid_userefreshrate", "0", "set this to 1 to make vid_refreshrate used, or to 0 to let the engine choose a sane default"}; cvar_t vid_stereobuffer = {CVAR_SAVE, "vid_stereobuffer", "0", "enables 'quad-buffered' stereo rendering for stereo shutterglasses, HMD (head mounted display) devices, or polarized stereo LCDs, if supported by your drivers"}; @@ -178,6 +174,7 @@ cvar_t vid_gl13 = {0, "vid_gl13", "1", "enables faster rendering using OpenGL 1. cvar_t vid_gl20 = {0, "vid_gl20", "1", "enables faster rendering using OpenGL 2.0 features (such as GL_ARB_fragment_shader extension)"}; cvar_t gl_finish = {0, "gl_finish", "0", "make the cpu wait for the graphics processor at the end of each rendered frame (can help with strange input or video lag problems on some machines)"}; cvar_t vid_sRGB = {CVAR_SAVE, "vid_sRGB", "0", "if hardware is capable, modify rendering to be gamma corrected for the sRGB color standard (computer monitors, TVs), recommended"}; +cvar_t vid_sRGB_fallback = {CVAR_SAVE, "vid_sRGB_fallback", "0", "do an approximate sRGB fallback if not properly supported by hardware (2: also use the fallback if framebuffer is 8bit, 3: always use the fallback even if sRGB is supported)"}; cvar_t vid_touchscreen = {0, "vid_touchscreen", "0", "Use touchscreen-style input (no mouse grab, track mouse motion only while button is down, screen areas for mimicing joystick axes and buttons"}; cvar_t vid_stick_mouse = {CVAR_SAVE, "vid_stick_mouse", "0", "have the mouse stuck in the center of the screen" }; @@ -199,6 +196,7 @@ cvar_t v_color_white_g = {CVAR_SAVE, "v_color_white_g", "1", "desired color of w cvar_t v_color_white_b = {CVAR_SAVE, "v_color_white_b", "1", "desired color of white"}; cvar_t v_hwgamma = {CVAR_SAVE, "v_hwgamma", "0", "enables use of hardware gamma correction ramps if available (note: does not work very well on Windows2000 and above), values are 0 = off, 1 = attempt to use hardware gamma, 2 = use hardware gamma whether it works or not"}; cvar_t v_glslgamma = {CVAR_SAVE, "v_glslgamma", "1", "enables use of GLSL to apply gamma correction ramps if available (note: overrides v_hwgamma)"}; +cvar_t v_glslgamma_2d = {CVAR_SAVE, "v_glslgamma_2d", "0", "applies GLSL gamma to 2d pictures (HUD, fonts)"}; cvar_t v_psycho = {0, "v_psycho", "0", "easter egg"}; // brand of graphics chip @@ -217,6 +215,7 @@ const char *gl_platformextensions; // name of driver library (opengl32.dll, libGL.so.1, or whatever) char gl_driver[256]; +#ifndef USE_GLES2 // GL_ARB_multitexture void (GLAPIENTRY *qglMultiTexCoord1f) (GLenum, GLfloat); void (GLAPIENTRY *qglMultiTexCoord2f) (GLenum, GLfloat, GLfloat); @@ -258,6 +257,7 @@ void (GLAPIENTRY *qglClearDepth)(GLclampd depth); void (GLAPIENTRY *qglDepthFunc)(GLenum func); void (GLAPIENTRY *qglDepthMask)(GLboolean flag); void (GLAPIENTRY *qglDepthRange)(GLclampd near_val, GLclampd far_val); +void (GLAPIENTRY *qglDepthRangef)(GLclampf near_val, GLclampf far_val); void (GLAPIENTRY *qglColorMask)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); void (GLAPIENTRY *qglDrawRangeElements)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); @@ -504,6 +504,7 @@ void (GLAPIENTRY *qglGetQueryObjectivARB)(GLuint qid, GLenum pname, GLint *param void (GLAPIENTRY *qglGetQueryObjectuivARB)(GLuint qid, GLenum pname, GLuint *params); void (GLAPIENTRY *qglSampleCoverageARB)(GLclampf value, GLboolean invert); +#endif #if _MSC_VER >= 1400 #define sscanf sscanf_s @@ -584,6 +585,7 @@ qboolean GL_CheckExtension(const char *minglver_or_ext, const dllfunction_t *fun return true; } +#ifndef USE_GLES2 static dllfunction_t opengl110funcs[] = { {"glClearColor", (void **) &qglClearColor}, @@ -918,6 +920,7 @@ static dllfunction_t multisamplefuncs[] = {"glSampleCoverageARB", (void **) &qglSampleCoverageARB}, {NULL, NULL} }; +#endif void VID_ClearExtensions(void) { @@ -940,6 +943,7 @@ void VID_ClearExtensions(void) vid.max_anisotropy = 1; vid.maxdrawbuffers = 1; +#ifndef USE_GLES2 // this is a complete list of all functions that are directly checked in the renderer qglDrawRangeElements = NULL; qglDrawBuffer = NULL; @@ -949,13 +953,15 @@ void VID_ClearExtensions(void) qglGetCompressedTexImageARB = NULL; qglFramebufferTexture2DEXT = NULL; qglDrawBuffersARB = NULL; +#endif } +#ifndef USE_GLES2 void VID_CheckExtensions(void) { if (!GL_CheckExtension("glbase", opengl110funcs, NULL, false)) Sys_Error("OpenGL 1.1.0 functions not found"); - vid.support.gl20shaders = GL_CheckExtension("GL_ARB_fragment_shader", gl20shaderfuncs, "-noshaders", true); + vid.support.gl20shaders = GL_CheckExtension("2.0", gl20shaderfuncs, "-noshaders", true); CHECKGLERROR @@ -1000,6 +1006,7 @@ void VID_CheckExtensions(void) vid.support.ext_blend_subtract = GL_CheckExtension("GL_EXT_blend_subtract", blendequationfuncs, "-noblendsubtract", false); vid.support.ext_draw_range_elements = GL_CheckExtension("drawrangeelements", drawrangeelementsfuncs, "-nodrawrangeelements", true) || GL_CheckExtension("GL_EXT_draw_range_elements", drawrangeelementsextfuncs, "-nodrawrangeelements", false); vid.support.ext_framebuffer_object = GL_CheckExtension("GL_EXT_framebuffer_object", fbofuncs, "-nofbo", false); + vid.support.ext_packed_depth_stencil = GL_CheckExtension("GL_EXT_packed_depth_stencil", NULL, "-nopackeddepthstencil", false); vid.support.ext_stencil_two_side = GL_CheckExtension("GL_EXT_stencil_two_side", stenciltwosidefuncs, "-nostenciltwoside", false); vid.support.ext_texture_3d = GL_CheckExtension("GL_EXT_texture3D", texture3dextfuncs, "-notexture3d", false); vid.support.ext_texture_compression_s3tc = GL_CheckExtension("GL_EXT_texture_compression_s3tc", NULL, "-nos3tc", false); @@ -1007,6 +1014,7 @@ void VID_CheckExtensions(void) vid.support.ext_texture_filter_anisotropic = GL_CheckExtension("GL_EXT_texture_filter_anisotropic", NULL, "-noanisotropy", false); vid.support.ext_texture_srgb = GL_CheckExtension("GL_EXT_texture_sRGB", NULL, "-nosrgb", false); vid.support.arb_multisample = GL_CheckExtension("GL_ARB_multisample", multisamplefuncs, "-nomultisample", false); + vid.allowalphatocoverage = false; // COMMANDLINEOPTION: GL: -noshaders disables use of OpenGL 2.0 shaders (which allow pixel shader effects, can improve per pixel lighting performance and capabilities) // COMMANDLINEOPTION: GL: -noanisotropy disables GL_EXT_texture_filter_anisotropic (allows higher quality texturing) @@ -1055,7 +1063,7 @@ void VID_CheckExtensions(void) if (vid.support.ext_texture_filter_anisotropic) qglGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, (GLint*)&vid.max_anisotropy); if (vid.support.arb_texture_cube_map) - qglGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB, (GLint*)&vid.maxtexturesize_cubemap); + qglGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, (GLint*)&vid.maxtexturesize_cubemap); if (vid.support.ext_texture_3d) qglGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, (GLint*)&vid.maxtexturesize_3d); @@ -1068,10 +1076,10 @@ void VID_CheckExtensions(void) vid.texunits = vid.teximageunits = vid.texarrayunits = 1; if (vid.support.arb_multitexture) - qglGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, (GLint*)&vid.texunits); + qglGetIntegerv(GL_MAX_TEXTURE_UNITS, (GLint*)&vid.texunits); if (vid_gl20.integer && vid.support.gl20shaders) { - qglGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, (GLint*)&vid.texunits); + qglGetIntegerv(GL_MAX_TEXTURE_UNITS, (GLint*)&vid.texunits); qglGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, (int *)&vid.teximageunits);CHECKGLERROR qglGetIntegerv(GL_MAX_TEXTURE_COORDS, (int *)&vid.texarrayunits);CHECKGLERROR vid.texunits = bound(4, vid.texunits, MAX_TEXTUREUNITS); @@ -1082,10 +1090,13 @@ void VID_CheckExtensions(void) vid.sRGBcapable2D = false; vid.sRGBcapable3D = true; vid.useinterleavedarrays = false; + Con_Printf("vid.support.arb_multisample %i\n", vid.support.arb_multisample); + Con_Printf("vid.support.gl20shaders %i\n", vid.support.gl20shaders); + vid.allowalphatocoverage = true; // but see below, it may get turned to false again if GL_SAMPLES_ARB is <= 1 } else if (vid.support.arb_texture_env_combine && vid.texunits >= 2 && vid_gl13.integer) { - qglGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, (GLint*)&vid.texunits); + qglGetIntegerv(GL_MAX_TEXTURE_UNITS, (GLint*)&vid.texunits); vid.texunits = bound(1, vid.texunits, MAX_TEXTUREUNITS); vid.teximageunits = vid.texunits; vid.texarrayunits = vid.texunits; @@ -1107,6 +1118,23 @@ void VID_CheckExtensions(void) vid.useinterleavedarrays = false; } + // enable multisample antialiasing if possible + if(vid.support.arb_multisample) + { + int samples = 0; + qglGetIntegerv(GL_SAMPLES_ARB, &samples); + vid.samples = samples; + if (samples > 1) + qglEnable(GL_MULTISAMPLE_ARB); + else + vid.allowalphatocoverage = false; + } + else + { + vid.allowalphatocoverage = false; + vid.samples = 1; + } + // VorteX: set other info (maybe place them in VID_InitMode?) Cvar_SetQuick(&gl_info_vendor, gl_vendor); Cvar_SetQuick(&gl_info_renderer, gl_renderer); @@ -1114,6 +1142,7 @@ void VID_CheckExtensions(void) Cvar_SetQuick(&gl_info_platform, gl_platform ? gl_platform : ""); Cvar_SetQuick(&gl_info_driver, gl_driver); } +#endif float VID_JoyState_GetAxis(const vid_joystate_t *joystate, int axis, float sensitivity, float deadzone) { @@ -1193,7 +1222,7 @@ void VID_Shared_BuildJoyState_Begin(vid_joystate_t *joystate) void VID_Shared_BuildJoyState_Finish(vid_joystate_t *joystate) { float f, r; - if (!joy_axiskeyevents.integer || joystate->is360) + if (joystate->is360) return; // emulate key events for thumbstick f = VID_JoyState_GetAxis(joystate, joy_axisforward.integer, 1, joy_axiskeyevents_deadzone.value) * joy_sensitivityforward.value; @@ -1205,10 +1234,9 @@ void VID_Shared_BuildJoyState_Finish(vid_joystate_t *joystate) joystate->button[33] = f < 0.0f; joystate->button[34] = r > 0.0f; joystate->button[35] = r < 0.0f; - } -void VID_KeyEventForButton(qboolean oldbutton, qboolean newbutton, int key, double *timer) +static void VID_KeyEventForButton(qboolean oldbutton, qboolean newbutton, int key, double *timer) { if (oldbutton) { @@ -1239,73 +1267,46 @@ void VID_KeyEventForButton(qboolean oldbutton, qboolean newbutton, int key, doub #if MAXJOYBUTTON != 36 #error this code must be updated if MAXJOYBUTTON changes! #endif -static int joybuttonkey[MAXJOYBUTTON] = +static int joybuttonkey[MAXJOYBUTTON][2] = { - K_JOY1, K_JOY2, K_JOY3, K_JOY4, K_JOY5, K_JOY6, K_JOY7, K_JOY8, K_JOY9, K_JOY10, K_JOY11, K_JOY12, K_JOY13, K_JOY14, K_JOY15, K_JOY16, - K_AUX1, K_AUX2, K_AUX3, K_AUX4, K_AUX5, K_AUX6, K_AUX7, K_AUX8, K_AUX9, K_AUX10, K_AUX11, K_AUX12, K_AUX13, K_AUX14, K_AUX15, K_AUX16, - K_UPARROW, K_DOWNARROW, K_RIGHTARROW, K_LEFTARROW + {K_JOY1, K_ENTER}, {K_JOY2, K_ESCAPE}, {K_JOY3, 0}, {K_JOY4, 0}, {K_JOY5, 0}, {K_JOY6, 0}, {K_JOY7, 0}, {K_JOY8, 0}, {K_JOY9, 0}, {K_JOY10, 0}, {K_JOY11, 0}, {K_JOY12, 0}, {K_JOY13, 0}, {K_JOY14, 0}, {K_JOY15, 0}, {K_JOY16, 0}, + {K_AUX1, 0}, {K_AUX2, 0}, {K_AUX3, 0}, {K_AUX4, 0}, {K_AUX5, 0}, {K_AUX6, 0}, {K_AUX7, 0}, {K_AUX8, 0}, {K_AUX9, 0}, {K_AUX10, 0}, {K_AUX11, 0}, {K_AUX12, 0}, {K_AUX13, 0}, {K_AUX14, 0}, {K_AUX15, 0}, {K_AUX16, 0}, + {K_JOY_UP, K_UPARROW}, {K_JOY_DOWN, K_DOWNARROW}, {K_JOY_RIGHT, K_RIGHTARROW}, {K_JOY_LEFT, K_LEFTARROW}, }; -static int joybuttonkey360[] = +static int joybuttonkey360[][2] = { - K_X360_DPAD_UP, - K_X360_DPAD_DOWN, - K_X360_DPAD_LEFT, - K_X360_DPAD_RIGHT, - K_X360_START, - K_X360_BACK, - K_X360_LEFT_THUMB, - K_X360_RIGHT_THUMB, - K_X360_LEFT_SHOULDER, - K_X360_RIGHT_SHOULDER, - K_X360_A, - K_X360_B, - K_X360_X, - K_X360_Y, - K_X360_LEFT_TRIGGER, - K_X360_RIGHT_TRIGGER, - K_X360_LEFT_THUMB_DOWN, - K_X360_LEFT_THUMB_UP, - K_X360_LEFT_THUMB_LEFT, - K_X360_LEFT_THUMB_RIGHT, - K_X360_RIGHT_THUMB_DOWN, - K_X360_RIGHT_THUMB_UP, - K_X360_RIGHT_THUMB_LEFT, - K_X360_RIGHT_THUMB_RIGHT, -}; - -static int joybuttonkey360menu[] = -{ - K_UPARROW, - K_DOWNARROW, - K_LEFTARROW, - K_RIGHTARROW, - K_PAUSE, - K_ESCAPE, - 0, - 0, - 0, - 0, - K_ENTER, - K_ESCAPE, - 0, - 0, - 0, - 0, - K_DOWNARROW, - K_UPARROW, - K_LEFTARROW, - K_RIGHTARROW, - 0, - 0, - 0, - 0, + {K_X360_DPAD_UP, K_UPARROW}, + {K_X360_DPAD_DOWN, K_DOWNARROW}, + {K_X360_DPAD_LEFT, K_LEFTARROW}, + {K_X360_DPAD_RIGHT, K_RIGHTARROW}, + {K_X360_START, K_ESCAPE}, + {K_X360_BACK, K_ESCAPE}, + {K_X360_LEFT_THUMB, 0}, + {K_X360_RIGHT_THUMB, 0}, + {K_X360_LEFT_SHOULDER, 0}, + {K_X360_RIGHT_SHOULDER, 0}, + {K_X360_A, K_ENTER}, + {K_X360_B, K_ESCAPE}, + {K_X360_X, 0}, + {K_X360_Y, 0}, + {K_X360_LEFT_TRIGGER, 0}, + {K_X360_RIGHT_TRIGGER, 0}, + {K_X360_LEFT_THUMB_DOWN, K_DOWNARROW}, + {K_X360_LEFT_THUMB_UP, K_UPARROW}, + {K_X360_LEFT_THUMB_LEFT, K_LEFTARROW}, + {K_X360_LEFT_THUMB_RIGHT, K_RIGHTARROW}, + {K_X360_RIGHT_THUMB_DOWN, 0}, + {K_X360_RIGHT_THUMB_UP, 0}, + {K_X360_RIGHT_THUMB_LEFT, 0}, + {K_X360_RIGHT_THUMB_RIGHT, 0}, }; double vid_joybuttontimer[MAXJOYBUTTON]; void VID_ApplyJoyState(vid_joystate_t *joystate) { int j; + int c = joy_axiskeyevents.integer != 0; if (joystate->is360) { #if 0 @@ -1318,7 +1319,7 @@ void VID_ApplyJoyState(vid_joystate_t *joystate) // emit key events for buttons for (j = 0;j < (int)(sizeof(joybuttonkey360)/sizeof(joybuttonkey360[0]));j++) - VID_KeyEventForButton(vid_joystate.button[j] != 0, joystate->button[j] != 0, key_dest == key_menu ? joybuttonkey360menu[j] : joybuttonkey360[j], &vid_joybuttontimer[j]); + VID_KeyEventForButton(vid_joystate.button[j] != 0, joystate->button[j] != 0, joybuttonkey360[j][c], &vid_joybuttontimer[j]); // axes cl.cmd.forwardmove += VID_JoyState_GetAxis(joystate, joy_x360_axisforward.integer, joy_x360_sensitivityforward.value, joy_x360_deadzoneforward.value) * cl_forwardspeed.value; @@ -1332,7 +1333,7 @@ void VID_ApplyJoyState(vid_joystate_t *joystate) { // emit key events for buttons for (j = 0;j < MAXJOYBUTTON;j++) - VID_KeyEventForButton(vid_joystate.button[j] != 0, joystate->button[j] != 0, joybuttonkey[j], &vid_joybuttontimer[j]); + VID_KeyEventForButton(vid_joystate.button[j] != 0, joystate->button[j] != 0, joybuttonkey[j][c], &vid_joybuttontimer[j]); // axes cl.cmd.forwardmove += VID_JoyState_GetAxis(joystate, joy_axisforward.integer, joy_sensitivityforward.value, joy_deadzoneforward.value) * cl_forwardspeed.value; @@ -1380,7 +1381,7 @@ int VID_Shared_SetJoystick(int index) } -void Force_CenterView_f (void) +static void Force_CenterView_f (void) { cl.viewangles[PITCH] = 0; } @@ -1393,18 +1394,24 @@ unsigned int vid_gammatables_serial = 0; // so other subsystems can poll if gamm qboolean vid_gammatables_trivial = true; void VID_BuildGammaTables(unsigned short *ramps, int rampsize) { - float srgbmul = (vid.sRGB2D || vid.sRGB3D) ? 2.2f : 1.0f; if (cachecolorenable) { - BuildGammaTable16(1.0f, invpow(0.5, 1 - cachegrey[0]) * srgbmul, cachewhite[0], cacheblack[0], cachecontrastboost, ramps, rampsize); - BuildGammaTable16(1.0f, invpow(0.5, 1 - cachegrey[1]) * srgbmul, cachewhite[1], cacheblack[1], cachecontrastboost, ramps + rampsize, rampsize); - BuildGammaTable16(1.0f, invpow(0.5, 1 - cachegrey[2]) * srgbmul, cachewhite[2], cacheblack[2], cachecontrastboost, ramps + rampsize*2, rampsize); + BuildGammaTable16(1.0f, invpow(0.5, 1 - cachegrey[0]), cachewhite[0], cacheblack[0], cachecontrastboost, ramps, rampsize); + BuildGammaTable16(1.0f, invpow(0.5, 1 - cachegrey[1]), cachewhite[1], cacheblack[1], cachecontrastboost, ramps + rampsize, rampsize); + BuildGammaTable16(1.0f, invpow(0.5, 1 - cachegrey[2]), cachewhite[2], cacheblack[2], cachecontrastboost, ramps + rampsize*2, rampsize); } else { - BuildGammaTable16(1.0f, cachegamma * srgbmul, cachecontrast, cachebrightness, cachecontrastboost, ramps, rampsize); - BuildGammaTable16(1.0f, cachegamma * srgbmul, cachecontrast, cachebrightness, cachecontrastboost, ramps + rampsize, rampsize); - BuildGammaTable16(1.0f, cachegamma * srgbmul, cachecontrast, cachebrightness, cachecontrastboost, ramps + rampsize*2, rampsize); + BuildGammaTable16(1.0f, cachegamma, cachecontrast, cachebrightness, cachecontrastboost, ramps, rampsize); + BuildGammaTable16(1.0f, cachegamma, cachecontrast, cachebrightness, cachecontrastboost, ramps + rampsize, rampsize); + BuildGammaTable16(1.0f, cachegamma, cachecontrast, cachebrightness, cachecontrastboost, ramps + rampsize*2, rampsize); + } + + if(vid.sRGB2D || vid.sRGB3D) + { + int i; + for(i = 0; i < 3*rampsize; ++i) + ramps[i] = (int)floor(bound(0.0f, Image_sRGBFloatFromLinearFloat(ramps[i] / 65535.0f), 1.0f) * 65535.0f + 0.5f); } // LordHavoc: this code came from Ben Winslow and Zinx Verituse, I have @@ -1479,8 +1486,8 @@ void VID_UpdateGamma(qboolean force, int rampsize) wantgamma = 0; #define BOUNDCVAR(cvar, m1, m2) c = &(cvar);f = bound(m1, c->value, m2);if (c->value != f) Cvar_SetValueQuick(c, f); BOUNDCVAR(v_gamma, 0.1, 5); - BOUNDCVAR(v_contrast, 1, 5); - BOUNDCVAR(v_brightness, 0, 0.8); + BOUNDCVAR(v_contrast, 0.2, 5); + BOUNDCVAR(v_brightness, -v_contrast.value * 0.8, 0.8); //BOUNDCVAR(v_contrastboost, 0.0625, 16); BOUNDCVAR(v_color_black_r, 0, 0.8); BOUNDCVAR(v_color_black_g, 0, 0.8); @@ -1660,6 +1667,7 @@ void VID_Shared_Init(void) Cvar_RegisterVariable(&v_hwgamma); Cvar_RegisterVariable(&v_glslgamma); + Cvar_RegisterVariable(&v_glslgamma_2d); Cvar_RegisterVariable(&v_psycho); @@ -1668,7 +1676,6 @@ void VID_Shared_Init(void) Cvar_RegisterVariable(&vid_height); Cvar_RegisterVariable(&vid_bitsperpixel); Cvar_RegisterVariable(&vid_samples); - Cvar_RegisterVariable(&vid_multisampling); Cvar_RegisterVariable(&vid_refreshrate); Cvar_RegisterVariable(&vid_userefreshrate); Cvar_RegisterVariable(&vid_stereobuffer); @@ -1684,6 +1691,7 @@ void VID_Shared_Init(void) Cvar_RegisterVariable(&vid_gl20); Cvar_RegisterVariable(&gl_finish); Cvar_RegisterVariable(&vid_sRGB); + Cvar_RegisterVariable(&vid_sRGB_fallback); Cvar_RegisterVariable(&joy_active); #ifdef WIN32 @@ -1739,17 +1747,10 @@ void VID_Shared_Init(void) Cmd_AddCommand("vid_restart", VID_Restart_f, "restarts video system (closes and reopens the window, restarts renderer)"); } -int VID_Mode(int fullscreen, int width, int height, int bpp, float refreshrate, int stereobuffer, int samples) +static int VID_Mode(int fullscreen, int width, int height, int bpp, float refreshrate, int stereobuffer, int samples) { viddef_mode_t mode; - - // multisampling should set at least 2 samples - if (vid.support.arb_multisample) - { - GL_MultiSampling(false); - if (vid_multisampling.integer) - samples = max(2, samples); - } + char vabuf[1024]; memset(&mode, 0, sizeof(mode)); mode.fullscreen = fullscreen != 0; @@ -1762,6 +1763,8 @@ int VID_Mode(int fullscreen, int width, int height, int bpp, float refreshrate, mode.samples = samples; cl_ignoremousemoves = 2; VID_ClearExtensions(); + + vid.samples = vid.mode.samples; if (VID_InitMode(&mode)) { // accept the (possibly modified) mode @@ -1773,12 +1776,22 @@ int VID_Mode(int fullscreen, int width, int height, int bpp, float refreshrate, vid.refreshrate = vid.mode.refreshrate; vid.userefreshrate = vid.mode.userefreshrate; vid.stereobuffer = vid.mode.stereobuffer; - vid.samples = vid.mode.samples; vid.stencil = vid.mode.bitsperpixel > 16; vid.sRGB2D = vid_sRGB.integer >= 1 && vid.sRGBcapable2D; vid.sRGB3D = vid_sRGB.integer >= 1 && vid.sRGBcapable3D; - Con_Printf("Video Mode: %s %dx%dx%dx%.2fhz%s%s\n", mode.fullscreen ? "fullscreen" : "window", mode.width, mode.height, mode.bitsperpixel, mode.refreshrate, mode.stereobuffer ? " stereo" : "", mode.samples > 1 ? va(" (%ix AA)", mode.samples) : ""); + if( + (vid_sRGB_fallback.integer >= 3) // force fallback + || + (vid_sRGB_fallback.integer >= 2 && // fallback if framebuffer is 8bit + !(r_viewfbo.integer >= 2 && vid.support.ext_framebuffer_object && vid.samples < 2)) + ) + vid.sRGB2D = vid.sRGB3D = false; + + if(vid.samples != vid.mode.samples) + Con_Printf("NOTE: requested %dx AA, got %dx AA\n", vid.mode.samples, vid.samples); + + Con_Printf("Video Mode: %s %dx%dx%dx%.2fhz%s%s\n", mode.fullscreen ? "fullscreen" : "window", mode.width, mode.height, mode.bitsperpixel, mode.refreshrate, mode.stereobuffer ? " stereo" : "", mode.samples > 1 ? va(vabuf, sizeof(vabuf), " (%ix AA)", mode.samples) : ""); Cvar_SetValueQuick(&vid_fullscreen, vid.mode.fullscreen); Cvar_SetValueQuick(&vid_width, vid.mode.width); @@ -1789,10 +1802,6 @@ int VID_Mode(int fullscreen, int width, int height, int bpp, float refreshrate, Cvar_SetValueQuick(&vid_refreshrate, vid.mode.refreshrate); Cvar_SetValueQuick(&vid_stereobuffer, vid.mode.stereobuffer); - // activate multisampling - if (vid_multisampling.integer) - GL_MultiSampling(true); - return true; } else @@ -1816,6 +1825,8 @@ extern qboolean vid_opened; void VID_Restart_f(void) { + char vabuf[1024]; + char vabuf2[1024]; // don't crash if video hasn't started yet if (vid_commandlinecheck) return; @@ -1827,8 +1838,8 @@ void VID_Restart_f(void) } Con_Printf("VID_Restart: changing from %s %dx%dx%dbpp%s%s, to %s %dx%dx%dbpp%s%s.\n", - vid.mode.fullscreen ? "fullscreen" : "window", vid.mode.width, vid.mode.height, vid.mode.bitsperpixel, vid.mode.fullscreen && vid.mode.userefreshrate ? va("x%.2fhz", vid.mode.refreshrate) : "", vid.mode.samples > 1 ? va(" (%ix AA)", vid.mode.samples) : "", - vid_fullscreen.integer ? "fullscreen" : "window", vid_width.integer, vid_height.integer, vid_bitsperpixel.integer, vid_fullscreen.integer && vid_userefreshrate.integer ? va("x%.2fhz", vid_refreshrate.value) : "", vid_samples.integer > 1 ? va(" (%ix AA)", vid_samples.integer) : ""); + vid.mode.fullscreen ? "fullscreen" : "window", vid.mode.width, vid.mode.height, vid.mode.bitsperpixel, vid.mode.fullscreen && vid.mode.userefreshrate ? va(vabuf, sizeof(vabuf), "x%.2fhz", vid.mode.refreshrate) : "", vid.mode.samples > 1 ? va(vabuf2, sizeof(vabuf2), " (%ix AA)", vid.mode.samples) : "", + vid_fullscreen.integer ? "fullscreen" : "window", vid_width.integer, vid_height.integer, vid_bitsperpixel.integer, vid_fullscreen.integer && vid_userefreshrate.integer ? va(vabuf, sizeof(vabuf), "x%.2fhz", vid_refreshrate.value) : "", vid_samples.integer > 1 ? va(vabuf2, sizeof(vabuf2), " (%ix AA)", vid_samples.integer) : ""); VID_CloseSystems(); VID_Shutdown(); if (!VID_Mode(vid_fullscreen.integer, vid_width.integer, vid_height.integer, vid_bitsperpixel.integer, vid_refreshrate.value, vid_stereobuffer.integer, vid_samples.integer)) @@ -1907,7 +1918,7 @@ void VID_Stop(void) VID_Shutdown(); } -int VID_SortModes_Compare(const void *a_, const void *b_) +static int VID_SortModes_Compare(const void *a_, const void *b_) { vid_mode_t *a = (vid_mode_t *) a_; vid_mode_t *b = (vid_mode_t *) b_;