From 57d7496c097df506f385c4a301173e7576c987c7 Mon Sep 17 00:00:00 2001 From: havoc Date: Wed, 8 Jun 2011 17:36:16 +0000 Subject: [PATCH] implemented r_transparent_alphatocoverage 2 which promotes alphablend if desired to ATC, the default is 1 (only promotes alphatest) enable GL_MULTISAMPLE during extension detection to make things work git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@11188 d7cf8633-e32d-0410-b094-e92efae38249 --- gl_backend.c | 50 +++++++--------------------------- gl_backend.h | 1 - gl_rmain.c | 76 +++++++++++++++++++++++++++++++++++++++++++--------- vid.h | 1 + vid_shared.c | 13 +++++---- 5 files changed, 82 insertions(+), 59 deletions(-) diff --git a/gl_backend.c b/gl_backend.c index cdc4df60..0a08f161 100644 --- a/gl_backend.c +++ b/gl_backend.c @@ -2113,35 +2113,6 @@ void GL_CullFace(int state) } } -void GL_MultiSampling(qboolean state) -{ - switch(vid.renderpath) - { - case RENDERPATH_GL11: - case RENDERPATH_GL13: - case RENDERPATH_GLES1: - case RENDERPATH_GL20: - case RENDERPATH_GLES2: - if (vid.support.arb_multisample && vid.mode.samples > 1) - { - if (state) - qglEnable(GL_MULTISAMPLE_ARB); - else - qglDisable(GL_MULTISAMPLE_ARB); - CHECKGLERROR - } - break; - case RENDERPATH_D3D9: - break; - case RENDERPATH_D3D10: - break; - case RENDERPATH_D3D11: - break; - case RENDERPATH_SOFT: - break; - } -} - void GL_AlphaTest(int state) { if (gl_state.alphatest != state) @@ -2192,19 +2163,16 @@ void GL_AlphaToCoverage(qboolean state) break; case RENDERPATH_GL20: // alpha to coverage turns the alpha value of the pixel into 0%, 25%, 50%, 75% or 100% by masking the multisample fragments accordingly - if (vid.support.arb_multisample && vid.mode.samples > 1) + CHECKGLERROR + if (gl_state.alphatocoverage) { - CHECKGLERROR - if (gl_state.alphatocoverage) - { - qglEnable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);CHECKGLERROR - qglEnable(GL_MULTISAMPLE_ARB);CHECKGLERROR - } - else - { - qglDisable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);CHECKGLERROR - qglDisable(GL_MULTISAMPLE_ARB);CHECKGLERROR - } + qglEnable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);CHECKGLERROR +// qglEnable(GL_MULTISAMPLE_ARB);CHECKGLERROR + } + else + { + qglDisable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);CHECKGLERROR +// qglDisable(GL_MULTISAMPLE_ARB);CHECKGLERROR } break; } diff --git a/gl_backend.h b/gl_backend.h index 1f416609..44418d97 100644 --- a/gl_backend.h +++ b/gl_backend.h @@ -41,7 +41,6 @@ void GL_PolygonOffset(float planeoffset, float depthoffset); void GL_CullFace(int state); void GL_AlphaTest(int state); void GL_AlphaToCoverage(qboolean state); -void GL_MultiSampling(qboolean state); void GL_ColorMask(int r, int g, int b, int a); void GL_Color(float cr, float cg, float cb, float ca); void GL_ActiveTexture(unsigned int num); diff --git a/gl_rmain.c b/gl_rmain.c index 91586963..35b11c2a 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -72,7 +72,7 @@ cvar_t r_farclip_world = {0, "r_farclip_world", "2", "adds map size to farclip m cvar_t r_nearclip = {0, "r_nearclip", "1", "distance from camera of nearclip plane" }; cvar_t r_deformvertexes = {0, "r_deformvertexes", "1", "allows use of deformvertexes in shader files (can be turned off to check performance impact)"}; cvar_t r_transparent = {0, "r_transparent", "1", "allows use of transparent surfaces (can be turned off to check performance impact)"}; -cvar_t r_transparent_alphatocoverage = {0, "r_transparent_alphatocoverage", "0", "enables alpha-to-coverage antialiasing technique on alphatest surfaces when using vid_samples 2 or higher"}; +cvar_t r_transparent_alphatocoverage = {0, "r_transparent_alphatocoverage", "1", "enables GL_ALPHA_TO_COVERAGE antialiasing technique on alphablend and alphatest surfaces when using vid_samples 2 or higher"}; cvar_t r_showoverdraw = {0, "r_showoverdraw", "0", "shows overlapping geometry"}; cvar_t r_showbboxes = {0, "r_showbboxes", "0", "shows bounding boxes of server entities, value controls opacity scaling (1 = 10%, 10 = 100%)"}; cvar_t r_showsurfaces = {0, "r_showsurfaces", "0", "1 shows surfaces as different colors, or a value of 2 shows triangle draw order (for analyzing whether meshes are optimized for vertex cache)"}; @@ -1911,7 +1911,8 @@ void R_SetupShader_Generic(rtexture_t *first, rtexture_t *second, int texturemod permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND; if (!second) texturemode = GL_MODULATE; - GL_AlphaToCoverage(false); + if (vid.allowalphatocoverage) + GL_AlphaToCoverage(false); switch (vid.renderpath) { case RENDERPATH_D3D9: @@ -1957,7 +1958,8 @@ void R_SetupShader_DepthOrShadow(qboolean notrippy) unsigned int permutation = 0; if (r_trippy.integer && !notrippy) permutation |= SHADERPERMUTATION_TRIPPY; - GL_AlphaToCoverage(false); + if (vid.allowalphatocoverage) + GL_AlphaToCoverage(false); switch (vid.renderpath) { case RENDERPATH_D3D9: @@ -1996,7 +1998,8 @@ void R_SetupShader_ShowDepth(qboolean notrippy) permutation |= SHADERPERMUTATION_TRIPPY; if (r_trippy.integer) permutation |= SHADERPERMUTATION_TRIPPY; - GL_AlphaToCoverage(false); + if (vid.allowalphatocoverage) + GL_AlphaToCoverage(false); switch (vid.renderpath) { case RENDERPATH_D3D9: @@ -2148,7 +2151,8 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, GL_BlendFunc(GL_ONE, GL_ZERO); blendfuncflags = R_BlendFuncFlags(GL_ONE, GL_ZERO); } - GL_AlphaToCoverage(false); + if (vid.allowalphatocoverage) + GL_AlphaToCoverage(false); } else if (rsurfacepass == RSURFPASS_DEFERREDGEOMETRY) { @@ -2168,7 +2172,8 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, mode = SHADERMODE_DEFERREDGEOMETRY; GL_BlendFunc(GL_ONE, GL_ZERO); blendfuncflags = R_BlendFuncFlags(GL_ONE, GL_ZERO); - GL_AlphaToCoverage(false); + if (vid.allowalphatocoverage) + GL_AlphaToCoverage(false); } else if (rsurfacepass == RSURFPASS_RTLIGHT) { @@ -2213,7 +2218,8 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, permutation |= SHADERPERMUTATION_REFLECTCUBE; GL_BlendFunc(GL_SRC_ALPHA, GL_ONE); blendfuncflags = R_BlendFuncFlags(GL_SRC_ALPHA, GL_ONE); - GL_AlphaToCoverage(false); + if (vid.allowalphatocoverage) + GL_AlphaToCoverage(false); } else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT) { @@ -2256,7 +2262,17 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, permutation |= SHADERPERMUTATION_REFLECTCUBE; GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2); blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2); - GL_AlphaToCoverage(r_transparent_alphatocoverage.integer && (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)); + // when using alphatocoverage, we don't need alphakill + if (vid.allowalphatocoverage) + { + if (r_transparent_alphatocoverage.integer) + { + GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0); + permutation &= ~SHADERPERMUTATION_ALPHAKILL; + } + else + GL_AlphaToCoverage(false); + } } else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT_DIRECTIONAL) { @@ -2309,7 +2325,17 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, } GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2); blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2); - GL_AlphaToCoverage(r_transparent_alphatocoverage.integer && (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)); + // when using alphatocoverage, we don't need alphakill + if (vid.allowalphatocoverage) + { + if (r_transparent_alphatocoverage.integer) + { + GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0); + permutation &= ~SHADERPERMUTATION_ALPHAKILL; + } + else + GL_AlphaToCoverage(false); + } } else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) { @@ -2359,7 +2385,17 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, } GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2); blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2); - GL_AlphaToCoverage(r_transparent_alphatocoverage.integer && (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)); + // when using alphatocoverage, we don't need alphakill + if (vid.allowalphatocoverage) + { + if (r_transparent_alphatocoverage.integer) + { + GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0); + permutation &= ~SHADERPERMUTATION_ALPHAKILL; + } + else + GL_AlphaToCoverage(false); + } } else { @@ -2445,7 +2481,17 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, } GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2); blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2); - GL_AlphaToCoverage(r_transparent_alphatocoverage.integer && (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)); + // when using alphatocoverage, we don't need alphakill + if (vid.allowalphatocoverage) + { + if (r_transparent_alphatocoverage.integer) + { + GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0); + permutation &= ~SHADERPERMUTATION_ALPHAKILL; + } + else + GL_AlphaToCoverage(false); + } } if(!(blendfuncflags & BLENDFUNC_ALLOWS_COLORMOD)) colormod = dummy_colormod; @@ -2946,7 +2992,8 @@ void R_SetupShader_DeferredLight(const rtlight_t *rtlight) else if (r_shadow_shadowmappcf) permutation |= SHADERPERMUTATION_SHADOWMAPPCF; } - GL_AlphaToCoverage(false); + if (vid.allowalphatocoverage) + GL_AlphaToCoverage(false); Matrix4x4_Transform(&r_refdef.view.viewport.viewmatrix, rtlight->shadoworigin, viewlightorigin); Matrix4x4_Concat(&lighttoview, &r_refdef.view.viewport.viewmatrix, &rtlight->matrix_lighttoworld); Matrix4x4_Invert_Simple(&viewtolight, &lighttoview); @@ -7653,6 +7700,11 @@ texture_t *R_GetCurrentTexture(texture_t *t) } else t->currentmaterialflags &= ~(MATERIALFLAG_REFRACTION | MATERIALFLAG_WATERSHADER | MATERIALFLAG_CAMERA); + if (vid.allowalphatocoverage && r_transparent_alphatocoverage.integer >= 2 && ((t->currentmaterialflags & (MATERIALFLAG_BLENDED | MATERIALFLAG_ALPHA | MATERIALFLAG_ADD | MATERIALFLAG_CUSTOMBLEND)) == (MATERIALFLAG_BLENDED | MATERIALFLAG_ALPHA))) + { + // promote alphablend to alphatocoverage (a type of alphatest) if antialiasing is on + t->currentmaterialflags = (t->currentmaterialflags & ~(MATERIALFLAG_BLENDED | MATERIALFLAG_ALPHA)) | MATERIALFLAG_ALPHATEST; + } if ((t->currentmaterialflags & (MATERIALFLAG_BLENDED | MATERIALFLAG_NODEPTHTEST)) == MATERIALFLAG_BLENDED && r_transparentdepthmasking.integer && !(t->basematerialflags & MATERIALFLAG_BLENDED)) t->currentmaterialflags |= MATERIALFLAG_TRANSDEPTH; diff --git a/vid.h b/vid.h index 1bc6e0cb..4840ae4a 100644 --- a/vid.h +++ b/vid.h @@ -108,6 +108,7 @@ typedef struct viddef_s renderpath_t renderpath; qboolean forcevbo; // some renderpaths can not operate without it qboolean useinterleavedarrays; // required by some renderpaths + qboolean allowalphatocoverage; // indicates the GL_AlphaToCoverage function works on this renderpath and framebuffer unsigned int texunits; unsigned int teximageunits; diff --git a/vid_shared.c b/vid_shared.c index 05f17f53..873d4328 100644 --- a/vid_shared.c +++ b/vid_shared.c @@ -1006,6 +1006,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) @@ -1081,6 +1082,10 @@ 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.mode.samples %i\n", vid.mode.samples); + Con_Printf("vid.support.gl20shaders %i\n", vid.support.gl20shaders); + vid.allowalphatocoverage = vid.support.arb_multisample && vid_samples.integer > 1 && vid.support.gl20shaders; } else if (vid.support.arb_texture_env_combine && vid.texunits >= 2 && vid_gl13.integer) { @@ -1105,6 +1110,9 @@ void VID_CheckExtensions(void) vid.sRGBcapable3D = false; vid.useinterleavedarrays = false; } + // enable multisample antialiasing if possible + if (vid_samples.integer > 1 && vid.support.arb_multisample) + qglEnable(GL_MULTISAMPLE_ARB); // VorteX: set other info (maybe place them in VID_InitMode?) Cvar_SetQuick(&gl_info_vendor, gl_vendor); @@ -1751,11 +1759,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); - // LordHavoc: disabled this code because multisampling is on by default if the framebuffer is multisampled -// // activate multisampling -// if (vid.mode.samples > 1) -// GL_MultiSampling(true); - return true; } else -- 2.39.2