implemented r_transparent_alphatocoverage 2 which promotes alphablend if
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 8 Jun 2011 17:36:16 +0000 (17:36 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 8 Jun 2011 17:36:16 +0000 (17:36 +0000)
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
gl_backend.h
gl_rmain.c
vid.h
vid_shared.c

index cdc4df6..0a08f16 100644 (file)
@@ -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;
                }
index 1f41660..44418d9 100644 (file)
@@ -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);
index 9158696..35b11c2 100644 (file)
@@ -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 1bc6e0c..4840ae4 100644 (file)
--- 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;
index 05f17f5..873d432 100644 (file)
@@ -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