]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - gl_rmain.c
add missing TEXF_ALPHA when loading the glossmap
[xonotic/darkplaces.git] / gl_rmain.c
index b5faeb344e6cddfbffba8d1e0d484d05af13c6fa..43559bca02c29588cebfd144b1d0ff9c9eb4db27 100644 (file)
@@ -99,6 +99,7 @@ cvar_t r_cullentities_trace_samples = {0, "r_cullentities_trace_samples", "2", "
 cvar_t r_cullentities_trace_tempentitysamples = {0, "r_cullentities_trace_tempentitysamples", "-1", "number of samples to test for entity culling of temp entities (including all CSQC entities), -1 disables trace culling on these entities to prevent flicker (pvs still applies)"};
 cvar_t r_cullentities_trace_enlarge = {0, "r_cullentities_trace_enlarge", "0", "box enlargement for entity culling"};
 cvar_t r_cullentities_trace_delay = {0, "r_cullentities_trace_delay", "1", "number of seconds until the entity gets actually culled"};
+cvar_t r_sortentities = {0, "r_sortentities", "0", "sort entities before drawing (might be faster)"};
 cvar_t r_speeds = {0, "r_speeds","0", "displays rendering statistics and per-subsystem timings"};
 cvar_t r_fullbright = {0, "r_fullbright","0", "makes map very bright and renders faster"};
 
@@ -220,6 +221,7 @@ cvar_t r_glsl_vertextextureblend_usebothalphas = {CVAR_SAVE, "r_glsl_vertextextu
 cvar_t r_framedatasize = {CVAR_SAVE, "r_framedatasize", "0.5", "size of renderer data cache used during one frame (for skeletal animation caching, light processing, etc)"};
 
 extern cvar_t v_glslgamma;
+extern cvar_t v_glslgamma_2d;
 
 extern qboolean v_flipped_state;
 
@@ -683,13 +685,15 @@ shadermodeinfo_t glslshadermodeinfo[SHADERMODE_COUNT] =
 {
        {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_GENERIC\n", " generic"},
        {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_POSTPROCESS\n", " postprocess"},
-       {"glsl/default.glsl", NULL, NULL               , "#define MODE_DEPTH_OR_SHADOW\n", " depth/shadow"},
+       {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_DEPTH_OR_SHADOW\n", " depth/shadow"},
        {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_FLATCOLOR\n", " flatcolor"},
        {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_VERTEXCOLOR\n", " vertexcolor"},
        {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTMAP\n", " lightmap"},
        {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_FAKELIGHT\n", " fakelight"},
        {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " lightdirectionmap_modelspace"},
        {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n", " lightdirectionmap_tangentspace"},
+       {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_FORCED_LIGHTMAP\n", " lightdirectionmap_forced_lightmap"},
+       {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_FORCED_VERTEXCOLOR\n", " lightdirectionmap_forced_vertexcolor"},
        {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTDIRECTION\n", " lightdirection"},
        {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTSOURCE\n", " lightsource"},
        {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_REFRACTION\n", " refraction"},
@@ -710,6 +714,8 @@ shadermodeinfo_t hlslshadermodeinfo[SHADERMODE_COUNT] =
        {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_FAKELIGHT\n", " fakelight"},
        {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " lightdirectionmap_modelspace"},
        {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n", " lightdirectionmap_tangentspace"},
+       {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_LIGHTDIRECTIONMAP_FORCED_LIGHTMAP\n", " lightdirectionmap_forced_lightmap"},
+       {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_LIGHTDIRECTIONMAP_FORCED_VERTEXCOLOR\n", " lightdirectionmap_forced_vertexcolor"},
        {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_LIGHTDIRECTION\n", " lightdirection"},
        {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_LIGHTSOURCE\n", " lightsource"},
        {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_REFRACTION\n", " refraction"},
@@ -1910,13 +1916,12 @@ void R_SetupShader_Generic(rtexture_t *first, rtexture_t *second, int texturemod
                permutation |= SHADERPERMUTATION_SPECULAR;
        if (texturemode == GL_MODULATE)
                permutation |= SHADERPERMUTATION_COLORMAPPING;
-// LordHavoc: VorteX broke the game by doing this, and did not cvar it properly, and did not add the proper checks (r_texture_sRGB_2d.integer would need to be checked), and it breaks with vid_sRGB where the gamma ramps are altered...
-//     if (usegamma && r_texture_gammaramps && v_glslgamma.integer && !vid_gammatables_trivial)
-//             permutation |= SHADERPERMUTATION_GAMMARAMPS;
        else if (texturemode == GL_ADD)
                permutation |= SHADERPERMUTATION_GLOW;
        else if (texturemode == GL_DECAL)
                permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
+       if (usegamma && v_glslgamma.integer && v_glslgamma_2d.integer && !vid.sRGB2D && r_texture_gammaramps && !vid_gammatables_trivial)
+               permutation |= SHADERPERMUTATION_GAMMARAMPS;
        if (!second)
                texturemode = GL_MODULATE;
        if (vid.allowalphatocoverage)
@@ -2327,7 +2332,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                        permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
                if (rsurface.texture->reflectmasktexture)
                        permutation |= SHADERPERMUTATION_REFLECTCUBE;
-               if (r_shadow_bouncegridtexture)
+               if (r_shadow_bouncegridtexture && cl.csqc_vidvars.drawworld)
                {
                        permutation |= SHADERPERMUTATION_BOUNCEGRID;
                        if (r_shadow_bouncegriddirectional)
@@ -2387,7 +2392,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                        permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
                if (rsurface.texture->reflectmasktexture)
                        permutation |= SHADERPERMUTATION_REFLECTCUBE;
-               if (r_shadow_bouncegridtexture)
+               if (r_shadow_bouncegridtexture && cl.csqc_vidvars.drawworld)
                {
                        permutation |= SHADERPERMUTATION_BOUNCEGRID;
                        if (r_shadow_bouncegriddirectional)
@@ -2465,10 +2470,13 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                        if (specularscale > 0)
                                permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
                }
-               else if (r_glsl_deluxemapping.integer >= 2 && rsurface.uselightmaptexture)
+               else if (r_glsl_deluxemapping.integer >= 2)
                {
                        // fake deluxemapping (uniform light direction in tangentspace)
-                       mode = SHADERMODE_LIGHTDIRECTIONMAP_TANGENTSPACE;
+                       if (rsurface.uselightmaptexture)
+                               mode = SHADERMODE_LIGHTDIRECTIONMAP_FORCED_LIGHTMAP;
+                       else
+                               mode = SHADERMODE_LIGHTDIRECTIONMAP_FORCED_VERTEXCOLOR;
                        permutation |= SHADERPERMUTATION_DIFFUSE;
                        if (specularscale > 0)
                                permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
@@ -2483,7 +2491,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                        // ordinary vertex coloring (q3bsp)
                        mode = SHADERMODE_VERTEXCOLOR;
                }
-               if (r_shadow_bouncegridtexture)
+               if (r_shadow_bouncegridtexture && cl.csqc_vidvars.drawworld)
                {
                        permutation |= SHADERPERMUTATION_BOUNCEGRID;
                        if (r_shadow_bouncegriddirectional)
@@ -2545,7 +2553,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
 
                        // additive passes are only darkened by fog, not tinted
                        hlslPSSetParameter3f(D3DPSREGISTER_FogColor, 0, 0, 0);
-                       hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
+                       hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
                }
                else
                {
@@ -2583,7 +2591,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                        hlslPSSetParameter4f(D3DPSREGISTER_ReflectColor, rsurface.texture->reflectcolor4f[0], rsurface.texture->reflectcolor4f[1], rsurface.texture->reflectcolor4f[2], rsurface.texture->reflectcolor4f[3] * rsurface.texture->lightmapcolor[3]);
                        hlslPSSetParameter1f(D3DPSREGISTER_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
                        hlslPSSetParameter1f(D3DPSREGISTER_ReflectOffset, rsurface.texture->reflectmin);
-                       hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
+                       hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, (rsurface.texture->specularpower - 1.0f) * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
                        if (mode == SHADERMODE_WATER)
                                hlslPSSetParameter2f(D3DPSREGISTER_NormalmapScrollBlend, rsurface.texture->r_water_waterscroll[0], rsurface.texture->r_water_waterscroll[1]);
                }
@@ -2693,7 +2701,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                        // additive passes are only darkened by fog, not tinted
                        if (r_glsl_permutation->loc_FogColor >= 0)
                                qglUniform3f(r_glsl_permutation->loc_FogColor, 0, 0, 0);
-                       if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1f(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
+                       if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1f(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
                }
                else
                {
@@ -2734,7 +2742,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                        if (r_glsl_permutation->loc_ReflectColor >= 0) qglUniform4f(r_glsl_permutation->loc_ReflectColor, rsurface.texture->reflectcolor4f[0], rsurface.texture->reflectcolor4f[1], rsurface.texture->reflectcolor4f[2], rsurface.texture->reflectcolor4f[3] * rsurface.texture->lightmapcolor[3]);
                        if (r_glsl_permutation->loc_ReflectFactor >= 0) qglUniform1f(r_glsl_permutation->loc_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
                        if (r_glsl_permutation->loc_ReflectOffset >= 0) qglUniform1f(r_glsl_permutation->loc_ReflectOffset, rsurface.texture->reflectmin);
-                       if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1f(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
+                       if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1f(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
                        if (r_glsl_permutation->loc_NormalmapScrollBlend >= 0) qglUniform2f(r_glsl_permutation->loc_NormalmapScrollBlend, rsurface.texture->r_water_waterscroll[0], rsurface.texture->r_water_waterscroll[1]);
                }
                if (r_glsl_permutation->loc_TexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_TexMatrix, 1, false, m16f);}
@@ -2841,7 +2849,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
        
                        // additive passes are only darkened by fog, not tinted
                        DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_FogColor, 0, 0, 0);
-                       DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
+                       DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
                }
                else
                {
@@ -2879,7 +2887,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                        DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ReflectColor, rsurface.texture->reflectcolor4f[0], rsurface.texture->reflectcolor4f[1], rsurface.texture->reflectcolor4f[2], rsurface.texture->reflectcolor4f[3] * rsurface.texture->lightmapcolor[3]);
                        DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
                        DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ReflectOffset, rsurface.texture->reflectmin);
-                       DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
+                       DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
                        DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_NormalmapScrollBlend, rsurface.texture->r_water_waterscroll[0], rsurface.texture->r_water_waterscroll[1]);
                }
                {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_TexMatrixM1, 1, false, m16f);}
@@ -3020,7 +3028,7 @@ void R_SetupShader_DeferredLight(const rtlight_t *rtlight)
                hlslPSSetParameter3f(D3DPSREGISTER_DeferredColor_Specular, lightcolorbase[0] * specularscale * range, lightcolorbase[1] * specularscale * range, lightcolorbase[2] * specularscale * range);
                hlslPSSetParameter2f(D3DPSREGISTER_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
                hlslPSSetParameter4f(D3DPSREGISTER_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
-               hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, (r_shadow_gloss.integer == 2 ? r_shadow_gloss2exponent.value : r_shadow_glossexponent.value) * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
+               hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, (r_shadow_gloss.integer == 2 ? r_shadow_gloss2exponent.value : r_shadow_glossexponent.value) * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
                hlslPSSetParameter2f(D3DPSREGISTER_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
                hlslPSSetParameter2f(D3DPSREGISTER_PixelToScreenTexCoord, 1.0f/vid.width, 1.0/vid.height);
 
@@ -3048,7 +3056,7 @@ void R_SetupShader_DeferredLight(const rtlight_t *rtlight)
                if (r_glsl_permutation->loc_DeferredColor_Specular    >= 0) qglUniform3f(       r_glsl_permutation->loc_DeferredColor_Specular   , lightcolorbase[0] * specularscale * range, lightcolorbase[1] * specularscale * range, lightcolorbase[2] * specularscale * range);
                if (r_glsl_permutation->loc_ShadowMap_TextureScale    >= 0) qglUniform2f(       r_glsl_permutation->loc_ShadowMap_TextureScale   , r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
                if (r_glsl_permutation->loc_ShadowMap_Parameters      >= 0) qglUniform4f(       r_glsl_permutation->loc_ShadowMap_Parameters     , r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
-               if (r_glsl_permutation->loc_SpecularPower             >= 0) qglUniform1f(       r_glsl_permutation->loc_SpecularPower            , (r_shadow_gloss.integer == 2 ? r_shadow_gloss2exponent.value : r_shadow_glossexponent.value) * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
+               if (r_glsl_permutation->loc_SpecularPower             >= 0) qglUniform1f(       r_glsl_permutation->loc_SpecularPower            , (r_shadow_gloss.integer == 2 ? r_shadow_gloss2exponent.value : r_shadow_glossexponent.value) * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
                if (r_glsl_permutation->loc_ScreenToDepth             >= 0) qglUniform2f(       r_glsl_permutation->loc_ScreenToDepth            , r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
                if (r_glsl_permutation->loc_PixelToScreenTexCoord     >= 0) qglUniform2f(       r_glsl_permutation->loc_PixelToScreenTexCoord    , 1.0f/vid.width, 1.0f/vid.height);
 
@@ -3072,7 +3080,7 @@ void R_SetupShader_DeferredLight(const rtlight_t *rtlight)
                DPSOFTRAST_Uniform3f(       DPSOFTRAST_UNIFORM_DeferredColor_Specular   , lightcolorbase[0] * specularscale * range, lightcolorbase[1] * specularscale * range, lightcolorbase[2] * specularscale * range);
                DPSOFTRAST_Uniform2f(       DPSOFTRAST_UNIFORM_ShadowMap_TextureScale   , r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
                DPSOFTRAST_Uniform4f(       DPSOFTRAST_UNIFORM_ShadowMap_Parameters     , r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
-               DPSOFTRAST_Uniform1f(       DPSOFTRAST_UNIFORM_SpecularPower            , (r_shadow_gloss.integer == 2 ? r_shadow_gloss2exponent.value : r_shadow_glossexponent.value) * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
+               DPSOFTRAST_Uniform1f(       DPSOFTRAST_UNIFORM_SpecularPower            , (r_shadow_gloss.integer == 2 ? r_shadow_gloss2exponent.value : r_shadow_glossexponent.value) * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
                DPSOFTRAST_Uniform2f(       DPSOFTRAST_UNIFORM_ScreenToDepth            , r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
                DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height);
 
@@ -3341,11 +3349,13 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole
                        }
                }
                R_SKINFRAME_LOAD_AVERAGE_COLORS(basepixels_width * basepixels_height, basepixels[4 * pix + comp]);
+#ifndef USE_GLES2
                //Con_Printf("Texture %s has average colors %f %f %f alpha %f\n", name, skinframe->avgcolor[0], skinframe->avgcolor[1], skinframe->avgcolor[2], skinframe->avgcolor[3]);
                if (r_savedds && qglGetCompressedTexImageARB && skinframe->base)
                        R_SaveTextureDDSFile(skinframe->base, va("dds/%s.dds", skinframe->basename), r_texture_dds_save.integer < 2, skinframe->hasalpha);
                if (r_savedds && qglGetCompressedTexImageARB && skinframe->fog)
                        R_SaveTextureDDSFile(skinframe->fog, va("dds/%s_mask.dds", skinframe->basename), r_texture_dds_save.integer < 2, true);
+#endif
        }
 
        if (r_loaddds)
@@ -3386,8 +3396,10 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole
                        skinframe->nmap = R_LoadTexture2D (r_main_texturepool, va("%s_nmap", skinframe->basename), basepixels_width, basepixels_height, pixels, TEXTYPE_BGRA, (TEXF_ALPHA | textureflags) & (r_mipnormalmaps.integer ? ~0 : ~TEXF_MIPMAP) & (gl_texturecompression_normal.integer && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
                        Mem_Free(pixels);
                }
+#ifndef USE_GLES2
                if (r_savedds && qglGetCompressedTexImageARB && skinframe->nmap)
                        R_SaveTextureDDSFile(skinframe->nmap, va("dds/%s_norm.dds", skinframe->basename), r_texture_dds_save.integer < 2, true);
+#endif
        }
 
        // _luma is supported only for tenebrae compatibility
@@ -3396,17 +3408,21 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole
        if (skinframe->glow == NULL && ((pixels = loadimagepixelsbgra(va("%s_glow",  skinframe->basename), false, false, false, &mymiplevel)) || (pixels = loadimagepixelsbgra(va("%s_luma", skinframe->basename), false, false, false, &mymiplevel))))
        {
                skinframe->glow = R_LoadTexture2D (r_main_texturepool, va("%s_glow", skinframe->basename), image_width, image_height, pixels, vid.sRGB3D ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, textureflags & (gl_texturecompression_glow.integer && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
+#ifndef USE_GLES2
                if (r_savedds && qglGetCompressedTexImageARB && skinframe->glow)
                        R_SaveTextureDDSFile(skinframe->glow, va("dds/%s_glow.dds", skinframe->basename), r_texture_dds_save.integer < 2, true);
+#endif
                Mem_Free(pixels);pixels = NULL;
        }
 
        mymiplevel = savemiplevel;
        if (skinframe->gloss == NULL && r_loadgloss && (pixels = loadimagepixelsbgra(va("%s_gloss", skinframe->basename), false, false, false, &mymiplevel)))
        {
-               skinframe->gloss = R_LoadTexture2D (r_main_texturepool, va("%s_gloss", skinframe->basename), image_width, image_height, pixels, vid.sRGB3D ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, textureflags & (gl_texturecompression_gloss.integer && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
+               skinframe->gloss = R_LoadTexture2D (r_main_texturepool, va("%s_gloss", skinframe->basename), image_width, image_height, pixels, vid.sRGB3D ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, (TEXF_ALPHA | textureflags) & (gl_texturecompression_gloss.integer && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
+#ifndef USE_GLES2
                if (r_savedds && qglGetCompressedTexImageARB && skinframe->gloss)
                        R_SaveTextureDDSFile(skinframe->gloss, va("dds/%s_gloss.dds", skinframe->basename), r_texture_dds_save.integer < 2, true);
+#endif
                Mem_Free(pixels);
                pixels = NULL;
        }
@@ -3415,8 +3431,10 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole
        if (skinframe->pants == NULL && (pixels = loadimagepixelsbgra(va("%s_pants", skinframe->basename), false, false, false, &mymiplevel)))
        {
                skinframe->pants = R_LoadTexture2D (r_main_texturepool, va("%s_pants", skinframe->basename), image_width, image_height, pixels, vid.sRGB3D ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, textureflags & (gl_texturecompression_color.integer && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
+#ifndef USE_GLES2
                if (r_savedds && qglGetCompressedTexImageARB && skinframe->pants)
                        R_SaveTextureDDSFile(skinframe->pants, va("dds/%s_pants.dds", skinframe->basename), r_texture_dds_save.integer < 2, false);
+#endif
                Mem_Free(pixels);
                pixels = NULL;
        }
@@ -3425,8 +3443,10 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole
        if (skinframe->shirt == NULL && (pixels = loadimagepixelsbgra(va("%s_shirt", skinframe->basename), false, false, false, &mymiplevel)))
        {
                skinframe->shirt = R_LoadTexture2D (r_main_texturepool, va("%s_shirt", skinframe->basename), image_width, image_height, pixels, vid.sRGB3D ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, textureflags & (gl_texturecompression_color.integer && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
+#ifndef USE_GLES2
                if (r_savedds && qglGetCompressedTexImageARB && skinframe->shirt)
                        R_SaveTextureDDSFile(skinframe->shirt, va("dds/%s_shirt.dds", skinframe->basename), r_texture_dds_save.integer < 2, false);
+#endif
                Mem_Free(pixels);
                pixels = NULL;
        }
@@ -3435,8 +3455,10 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole
        if (skinframe->reflect == NULL && (pixels = loadimagepixelsbgra(va("%s_reflect", skinframe->basename), false, false, false, &mymiplevel)))
        {
                skinframe->reflect = R_LoadTexture2D (r_main_texturepool, va("%s_reflect", skinframe->basename), image_width, image_height, pixels, vid.sRGB3D ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, textureflags & (gl_texturecompression_reflectmask.integer && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
+#ifndef USE_GLES2
                if (r_savedds && qglGetCompressedTexImageARB && skinframe->reflect)
                        R_SaveTextureDDSFile(skinframe->reflect, va("dds/%s_reflect.dds", skinframe->basename), r_texture_dds_save.integer < 2, true);
+#endif
                Mem_Free(pixels);
                pixels = NULL;
        }
@@ -4043,8 +4065,10 @@ void gl_main_shutdown(void)
        case RENDERPATH_GL20:
        case RENDERPATH_GLES1:
        case RENDERPATH_GLES2:
+#ifdef GL_SAMPLES_PASSED_ARB
                if (r_maxqueries)
                        qglDeleteQueriesARB(r_maxqueries, r_queries);
+#endif
                break;
        case RENDERPATH_D3D9:
                //Con_DPrintf("FIXME D3D9 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
@@ -4190,6 +4214,7 @@ void GL_Main_Init(void)
        Cvar_RegisterVariable(&r_cullentities_trace_tempentitysamples);
        Cvar_RegisterVariable(&r_cullentities_trace_enlarge);
        Cvar_RegisterVariable(&r_cullentities_trace_delay);
+       Cvar_RegisterVariable(&r_sortentities);
        Cvar_RegisterVariable(&r_drawviewmodel);
        Cvar_RegisterVariable(&r_drawexteriormodel);
        Cvar_RegisterVariable(&r_speeds);
@@ -4327,6 +4352,7 @@ void Render_Init(void)
 GL_Init
 ===============
 */
+#ifndef USE_GLES2
 extern char *ENGINE_EXTENSIONS;
 void GL_Init (void)
 {
@@ -4354,6 +4380,7 @@ void GL_Init (void)
        // clear to black (loading plaque will be seen over this)
        GL_Clear(GL_COLOR_BUFFER_BIT, NULL, 1.0f, 128);
 }
+#endif
 
 int R_CullBox(const vec3_t mins, const vec3_t maxs)
 {
@@ -6006,16 +6033,18 @@ void R_Bloom_StartFrame(void)
                        r_bloomstate.texture_framebuffercolor = R_LoadTexture2D(r_main_texturepool, "framebuffercolor", r_bloomstate.screentexturewidth, r_bloomstate.screentextureheight, NULL, textype, TEXF_RENDERTARGET | TEXF_FORCELINEAR | TEXF_CLAMP, -1, NULL);
                        r_bloomstate.fbo_framebuffer = R_Mesh_CreateFramebufferObject(r_bloomstate.texture_framebufferdepth, r_bloomstate.texture_framebuffercolor, NULL, NULL, NULL);
                        R_Mesh_SetRenderTargets(r_bloomstate.fbo_framebuffer, r_bloomstate.texture_framebufferdepth, r_bloomstate.texture_framebuffercolor, NULL, NULL, NULL);
+#ifndef USE_GLES2
                        // render depth into one texture and normalmap into the other
                        if (qglDrawBuffer)
                        {
                                int status;
-                               qglDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);CHECKGLERROR
-                               qglReadBuffer(GL_COLOR_ATTACHMENT0_EXT);CHECKGLERROR
-                               status = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);CHECKGLERROR
-                               if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
+                               qglDrawBuffer(GL_COLOR_ATTACHMENT0);CHECKGLERROR
+                               qglReadBuffer(GL_COLOR_ATTACHMENT0);CHECKGLERROR
+                               status = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER);CHECKGLERROR
+                               if (status != GL_FRAMEBUFFER_COMPLETE)
                                        Con_Printf("R_Bloom_StartFrame: glCheckFramebufferStatusEXT returned %i\n", status);
                        }
+#endif
                }
                r_bloomstate.bloomtexturewidth = bloomtexturewidth;
                r_bloomstate.bloomtextureheight = bloomtextureheight;
@@ -6707,6 +6736,37 @@ r_refdef_scene_t * R_GetScenePointer( r_refdef_scene_type_t scenetype )
        }
 }
 
+int R_SortEntities_Compare(const void *ap, const void *bp)
+{
+       const entity_render_t *a = *(const entity_render_t **)ap;
+       const entity_render_t *b = *(const entity_render_t **)bp;
+
+       // 1. compare model
+       if(a->model < b->model)
+               return -1;
+       if(a->model > b->model)
+               return +1;
+
+       // 2. compare skin
+       // TODO possibly calculate the REAL skinnum here first using
+       // skinscenes?
+       if(a->skinnum < b->skinnum)
+               return -1;
+       if(a->skinnum > b->skinnum)
+               return +1;
+
+       // everything we compared is equal
+       return 0;
+}
+void R_SortEntities(void)
+{
+       // below or equal 2 ents, sorting never gains anything
+       if(r_refdef.scene.numentities <= 2)
+               return;
+       // sort
+       qsort(r_refdef.scene.entities, r_refdef.scene.numentities, sizeof(*r_refdef.scene.entities), R_SortEntities_Compare);
+}
+
 /*
 ================
 R_RenderView
@@ -6731,6 +6791,8 @@ void R_RenderView(void)
 
        if (!r_drawentities.integer)
                r_refdef.scene.numentities = 0;
+       else if (r_sortentities.integer)
+               R_SortEntities();
 
        R_AnimCache_ClearCache();
        R_FrameData_NewFrame();
@@ -7497,7 +7559,7 @@ static qboolean R_TestQ3WaveFunc(q3wavefunc_t func, const float *parms)
        if(parms[0] == 0 && parms[1] == 0)
                return false;
        if(func >> Q3WAVEFUNC_USER_SHIFT) // assumes rsurface to be set!
-               if(rsurface.userwavefunc_param[bound(0, (func >> Q3WAVEFUNC_USER_SHIFT) - 1, Q3WAVEFUNC_USER_COUNT)] == 0)
+               if(rsurface.userwavefunc_param[bound(0, (func >> Q3WAVEFUNC_USER_SHIFT) - 1, Q3WAVEFUNC_USER_COUNT - 1)] == 0)
                        return false;
        return true;
 }
@@ -7536,7 +7598,7 @@ static float R_EvaluateQ3WaveFunc(q3wavefunc_t func, const float *parms)
        }
        f = parms[0] + parms[1] * f;
        if(func >> Q3WAVEFUNC_USER_SHIFT) // assumes rsurface to be set!
-               f *= rsurface.userwavefunc_param[bound(0, (func >> Q3WAVEFUNC_USER_SHIFT) - 1, Q3WAVEFUNC_USER_COUNT)];
+               f *= rsurface.userwavefunc_param[bound(0, (func >> Q3WAVEFUNC_USER_SHIFT) - 1, Q3WAVEFUNC_USER_COUNT - 1)];
        return (float) f;
 }
 
@@ -7815,6 +7877,7 @@ texture_t *R_GetCurrentTexture(texture_t *t)
        }
        t->specularscale *= t->specularscalemod;
        t->specularpower *= t->specularpowermod;
+       t->rtlightambient = 0;
 
        // lightmaps mode looks bad with dlights using actual texturing, so turn
        // off the colormap and glossmap, but leave the normalmap on as it still
@@ -11343,6 +11406,7 @@ void R_DrawDebugModel(void)
 
        GL_PolygonOffset(r_refdef.polygonfactor, r_refdef.polygonoffset);
 
+#ifndef USE_GLES2
        if (r_showtris.integer && qglPolygonMode)
        {
                if (r_showdisabledepthtest.integer)
@@ -11453,6 +11517,7 @@ void R_DrawDebugModel(void)
                }
                rsurface.texture = NULL;
        }
+#endif
 }
 
 extern void R_BuildLightMap(const entity_render_t *ent, msurface_t *surface);