]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - gl_rmain.c
Don't enable moncontrol if non-glibc on Linux. Fixes linking against musl
[xonotic/darkplaces.git] / gl_rmain.c
index ad0e5f5be5c5a73e12ca1c59aeae5c2b1f52ff52..522cea20c8f9d6fca6eb4ec71d2608ff3ec667bc 100644 (file)
@@ -141,7 +141,7 @@ cvar_t r_shadows_throwdirection = {CVAR_SAVE, "r_shadows_throwdirection", "0 0 -
 cvar_t r_shadows_drawafterrtlighting = {CVAR_SAVE, "r_shadows_drawafterrtlighting", "0", "draw fake shadows AFTER realtime lightning is drawn. May be useful for simulating fast sunlight on large outdoor maps with only one noshadow rtlight. The price is less realistic appearance of dynamic light shadows."};
 cvar_t r_shadows_castfrombmodels = {CVAR_SAVE, "r_shadows_castfrombmodels", "0", "do cast shadows from bmodels"};
 cvar_t r_shadows_focus = {CVAR_SAVE, "r_shadows_focus", "0 0 0", "offset the shadowed area focus"};
-cvar_t r_shadows_shadowmapscale = {CVAR_SAVE, "r_shadows_shadowmapscale", "1", "increases shadowmap quality (multiply global shadowmap precision) for fake shadows. Needs shadowmapping ON."};
+cvar_t r_shadows_shadowmapscale = {CVAR_SAVE, "r_shadows_shadowmapscale", "0.25", "higher values increase shadowmap quality at a cost of area covered (multiply global shadowmap precision) for fake shadows. Needs shadowmapping ON."};
 cvar_t r_shadows_shadowmapbias = {CVAR_SAVE, "r_shadows_shadowmapbias", "-1", "sets shadowmap bias for fake shadows. -1 sets the value of r_shadow_shadowmapping_bias. Needs shadowmapping ON."};
 cvar_t r_q1bsp_skymasking = {0, "r_q1bsp_skymasking", "1", "allows sky polygons in quake1 maps to obscure other geometry"};
 cvar_t r_polygonoffset_submodel_factor = {0, "r_polygonoffset_submodel_factor", "0", "biases depth values of world submodels such as doors, to prevent z-fighting artifacts in Quake maps"};
@@ -268,7 +268,6 @@ cvar_t r_buffermegs[R_BUFFERDATA_COUNT] =
        {CVAR_SAVE, "r_buffermegs_uniform", "0.25", "uniform buffer size for one frame"},
 };
 
-extern cvar_t v_glslgamma;
 extern cvar_t v_glslgamma_2d;
 
 extern qboolean v_flipped_state;
@@ -2034,7 +2033,7 @@ void R_SetupShader_Generic(rtexture_t *first, rtexture_t *second, int texturemod
                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)
+       if (usegamma && v_glslgamma_2d.integer && !vid.sRGB2D && r_texture_gammaramps && !vid_gammatables_trivial)
                permutation |= SHADERPERMUTATION_GAMMARAMPS;
        if (suppresstexalpha)
                permutation |= SHADERPERMUTATION_REFLECTCUBE;
@@ -2050,7 +2049,7 @@ void R_SetupShader_Generic(rtexture_t *first, rtexture_t *second, int texturemod
                R_Mesh_TexBind(GL20TU_FIRST , first );
                R_Mesh_TexBind(GL20TU_SECOND, second);
                if (permutation & SHADERPERMUTATION_GAMMARAMPS)
-                       R_Mesh_TexBind(r_glsl_permutation->tex_Texture_GammaRamps, r_texture_gammaramps);
+                       R_Mesh_TexBind(GL20TU_GAMMARAMPS, r_texture_gammaramps);
 #endif
                break;
        case RENDERPATH_D3D10:
@@ -3129,6 +3128,23 @@ void R_SkinFrame_MarkUsed(skinframe_t *skinframe)
        skinframe->loadsequence = r_skinframe.loadsequence;
 }
 
+void R_SkinFrame_PurgeSkinFrame(skinframe_t *s)
+{
+       if (s->merged == s->base)
+               s->merged = NULL;
+       R_PurgeTexture(s->stain); s->stain = NULL;
+       R_PurgeTexture(s->merged); s->merged = NULL;
+       R_PurgeTexture(s->base); s->base = NULL;
+       R_PurgeTexture(s->pants); s->pants = NULL;
+       R_PurgeTexture(s->shirt); s->shirt = NULL;
+       R_PurgeTexture(s->nmap); s->nmap = NULL;
+       R_PurgeTexture(s->gloss); s->gloss = NULL;
+       R_PurgeTexture(s->glow); s->glow = NULL;
+       R_PurgeTexture(s->fog); s->fog = NULL;
+       R_PurgeTexture(s->reflect); s->reflect = NULL;
+       s->loadsequence = 0;
+}
+
 void R_SkinFrame_Purge(void)
 {
        int i;
@@ -3138,22 +3154,7 @@ void R_SkinFrame_Purge(void)
                for (s = r_skinframe.hash[i];s;s = s->next)
                {
                        if (s->loadsequence && s->loadsequence != r_skinframe.loadsequence)
-                       {
-                               if (s->merged == s->base)
-                                       s->merged = NULL;
-                               // FIXME: maybe pass a pointer to the pointer to R_PurgeTexture and reset it to NULL inside? [11/29/2007 Black]
-                               R_PurgeTexture(s->stain );s->stain  = NULL;
-                               R_PurgeTexture(s->merged);s->merged = NULL;
-                               R_PurgeTexture(s->base  );s->base   = NULL;
-                               R_PurgeTexture(s->pants );s->pants  = NULL;
-                               R_PurgeTexture(s->shirt );s->shirt  = NULL;
-                               R_PurgeTexture(s->nmap  );s->nmap   = NULL;
-                               R_PurgeTexture(s->gloss );s->gloss  = NULL;
-                               R_PurgeTexture(s->glow  );s->glow   = NULL;
-                               R_PurgeTexture(s->fog   );s->fog    = NULL;
-                               R_PurgeTexture(s->reflect);s->reflect = NULL;
-                               s->loadsequence = 0;
-                       }
+                               R_SkinFrame_PurgeSkinFrame(s);
                }
        }
 }
@@ -3218,20 +3219,7 @@ skinframe_t *R_SkinFrame_Find(const char *name, int textureflags, int comparewid
                dyntexture = CL_GetDynTexture( basename );
                if (!add && !dyntexture)
                        return NULL;
-               if (item->merged == item->base)
-                       item->merged = NULL;
-               // FIXME: maybe pass a pointer to the pointer to R_PurgeTexture and reset it to NULL inside? [11/29/2007 Black]
-               R_PurgeTexture(item->stain );item->stain  = NULL;
-               R_PurgeTexture(item->merged);item->merged = NULL;
-               R_PurgeTexture(item->base  );item->base   = NULL;
-               R_PurgeTexture(item->pants );item->pants  = NULL;
-               R_PurgeTexture(item->shirt );item->shirt  = NULL;
-               R_PurgeTexture(item->nmap  );item->nmap   = NULL;
-               R_PurgeTexture(item->gloss );item->gloss  = NULL;
-               R_PurgeTexture(item->glow  );item->glow   = NULL;
-               R_PurgeTexture(item->fog   );item->fog    = NULL;
-       R_PurgeTexture(item->reflect);item->reflect = NULL;
-               item->loadsequence = 0;
+               R_SkinFrame_PurgeSkinFrame(item);
        }
        else if( item->base == NULL )
        {
@@ -6237,6 +6225,7 @@ static void R_Bloom_StartFrame(void)
        case RENDERPATH_GL11:
        case RENDERPATH_GL13:
        case RENDERPATH_GLES1:
+               return; // don't bother
        case RENDERPATH_GLES2:
        case RENDERPATH_D3D9:
        case RENDERPATH_D3D10:
@@ -6313,7 +6302,7 @@ static void R_Bloom_StartFrame(void)
                Cvar_SetValueQuick(&r_damageblur, 0);
        }
 
-       if (!((r_glsl_postprocess.integer || r_fxaa.integer) || (!R_Stereo_ColorMasking() && r_glsl_saturation.value != 1) || (v_glslgamma.integer && !vid_gammatables_trivial))
+       if (!((r_glsl_postprocess.integer || r_fxaa.integer) || (!R_Stereo_ColorMasking() && r_glsl_saturation.value != 1) || !vid_gammatables_trivial)
         && !r_bloom.integer
         && (R_Stereo_Active() || (r_motionblur.value <= 0 && r_damageblur.value <= 0))
         && !useviewfbo
@@ -6617,7 +6606,7 @@ static void R_BlendView(int fbo, rtexture_t *depthtexture, rtexture_t *colortext
                permutation =
                          (r_fb.bloomtexture[r_fb.bloomindex] ? SHADERPERMUTATION_BLOOM : 0)
                        | (r_refdef.viewblend[3] > 0 ? SHADERPERMUTATION_VIEWTINT : 0)
-                       | ((v_glslgamma.value && !vid_gammatables_trivial) ? SHADERPERMUTATION_GAMMARAMPS : 0)
+                       | (!vid_gammatables_trivial ? SHADERPERMUTATION_GAMMARAMPS : 0)
                        | (r_glsl_postprocess.integer ? SHADERPERMUTATION_POSTPROCESSING : 0)
                        | ((!R_Stereo_ColorMasking() && r_glsl_saturation.value != 1) ? SHADERPERMUTATION_SATURATION : 0);
 
@@ -6966,7 +6955,7 @@ void R_UpdateVariables(void)
        case RENDERPATH_D3D11:
        case RENDERPATH_SOFT:
        case RENDERPATH_GLES2:
-               if(v_glslgamma.integer && !vid_gammatables_trivial)
+               if(!vid_gammatables_trivial)
                {
                        if(!r_texture_gammaramps || vid_gammatables_serial != r_texture_gammaramps_serial)
                        {
@@ -8687,6 +8676,24 @@ void RSurf_ActiveModelEntity(const entity_render_t *ent, qboolean wantnormals, q
 void RSurf_ActiveCustomEntity(const matrix4x4_t *matrix, const matrix4x4_t *inversematrix, int entflags, double shadertime, float r, float g, float b, float a, int numvertices, const float *vertex3f, const float *texcoord2f, const float *normal3f, const float *svector3f, const float *tvector3f, const float *color4f, int numtriangles, const int *element3i, const unsigned short *element3s, qboolean wantnormals, qboolean wanttangents)
 {
        rsurface.entity = r_refdef.scene.worldentity;
+       if (r != 1.0f || g != 1.0f || b != 1.0f || a != 1.0f) {
+               // HACK to provide a valid entity with modded colors to R_GetCurrentTexture.
+               // A better approach could be making this copy only once per frame.
+               static entity_render_t custom_entity;
+               int q;
+               custom_entity = *rsurface.entity;
+               for (q = 0; q < 3; ++q) {
+                       float colormod = q == 0 ? r : q == 1 ? g : b;
+                       custom_entity.render_fullbright[q] *= colormod;
+                       custom_entity.render_modellight_ambient[q] *= colormod;
+                       custom_entity.render_modellight_diffuse[q] *= colormod;
+                       custom_entity.render_lightmap_ambient[q] *= colormod;
+                       custom_entity.render_lightmap_diffuse[q] *= colormod;
+                       custom_entity.render_rtlight_diffuse[q] *= colormod;
+               }
+               custom_entity.alpha *= a;
+               rsurface.entity = &custom_entity;
+       }
        rsurface.skeleton = NULL;
        rsurface.ent_skinnum = 0;
        rsurface.ent_qwskin = -1;
@@ -10522,6 +10529,7 @@ void RSurf_SetupDepthAndCulling(void)
 
 static void R_DrawTextureSurfaceList_Sky(int texturenumsurfaces, const msurface_t **texturesurfacelist)
 {
+       int i, j;
        // transparent sky would be ridiculous
        if (rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED)
                return;
@@ -10529,20 +10537,75 @@ static void R_DrawTextureSurfaceList_Sky(int texturenumsurfaces, const msurface_
        skyrenderlater = true;
        RSurf_SetupDepthAndCulling();
        GL_DepthMask(true);
-       // LordHavoc: HalfLife maps have freaky skypolys so don't use
+
+       // add the vertices of the surfaces to a world bounding box so we can scissor the sky render later
+       if (r_sky_scissor.integer)
+       {
+               RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ALLOWMULTIDRAW, texturenumsurfaces, texturesurfacelist);
+               for (i = 0; i < texturenumsurfaces; i++)
+               {
+                       const msurface_t *surf = texturesurfacelist[i];
+                       const float *v;
+                       float p[3];
+                       float mins[3], maxs[3];
+                       int scissor[4];
+                       for (j = 0, v = rsurface.batchvertex3f + 3 * surf->num_firstvertex; j < surf->num_vertices; j++, v += 3)
+                       {
+                               Matrix4x4_Transform(&rsurface.matrix, v, p);
+                               if (j > 0)
+                               {
+                                       if (mins[0] > p[0]) mins[0] = p[0];
+                                       if (mins[1] > p[1]) mins[1] = p[1];
+                                       if (mins[2] > p[2]) mins[2] = p[2];
+                                       if (maxs[0] < p[0]) maxs[0] = p[0];
+                                       if (maxs[1] < p[1]) maxs[1] = p[1];
+                                       if (maxs[2] < p[2]) maxs[2] = p[2];
+                               }
+                               else
+                               {
+                                       VectorCopy(p, mins);
+                                       VectorCopy(p, maxs);
+                               }
+                       }
+                       if (!R_ScissorForBBox(mins, maxs, scissor))
+                       {
+                               if (skyscissor[2])
+                               {
+                                       if (skyscissor[0] > scissor[0])
+                                       {
+                                               skyscissor[2] += skyscissor[0] - scissor[0];
+                                               skyscissor[0] = scissor[0];
+                                       }
+                                       if (skyscissor[1] > scissor[1])
+                                       {
+                                               skyscissor[3] += skyscissor[1] - scissor[1];
+                                               skyscissor[1] = scissor[1];
+                                       }
+                                       if (skyscissor[0] + skyscissor[2] < scissor[0] + scissor[2])
+                                               skyscissor[2] = scissor[0] + scissor[2] - skyscissor[0];
+                                       if (skyscissor[1] + skyscissor[3] < scissor[1] + scissor[3])
+                                               skyscissor[3] = scissor[1] + scissor[3] - skyscissor[1];
+                               }
+                               else
+                                       Vector4Copy(scissor, skyscissor);
+                       }
+               }
+       }
+
+       // LadyHavoc: HalfLife maps have freaky skypolys so don't use
        // skymasking on them, and Quake3 never did sky masking (unlike
        // software Quake and software Quake2), so disable the sky masking
        // in Quake3 maps as it causes problems with q3map2 sky tricks,
        // and skymasking also looks very bad when noclipping outside the
        // level, so don't use it then either.
-       if (r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.skymasking && r_q1bsp_skymasking.integer && !r_refdef.viewcache.world_novis && !r_trippy.integer)
+       if (r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.skymasking && (r_refdef.scene.worldmodel->brush.isq3bsp ? r_q3bsp_renderskydepth.integer : r_q1bsp_skymasking.integer) && !r_refdef.viewcache.world_novis && !r_trippy.integer)
        {
                R_Mesh_ResetTextureState();
                if (skyrendermasked)
                {
                        R_SetupShader_DepthOrShadow(false, false, false);
                        // depth-only (masking)
-                       GL_ColorMask(0,0,0,0);
+                       GL_ColorMask(0, 0, 0, 0);
                        // just to make sure that braindead drivers don't draw
                        // anything despite that colormask...
                        GL_BlendFunc(GL_ZERO, GL_ONE);
@@ -12391,36 +12454,8 @@ void R_DrawCustomSurface(skinframe_t *skinframe, const matrix4x4_t *texmatrix, i
        texture.specularscalemod = 1;
        texture.specularpowermod = 1;
        texture.transparentsort = TRANSPARENTSORT_DISTANCE;
-       // WHEN ADDING DEFAULTS HERE, REMEMBER TO PUT DEFAULTS IN ALL LOADERS
-       // JUST GREP FOR "specularscalemod = 1".
-
-       for (q = 0; q < 3; q++)
-       {
-               texture.render_glowmod[q] = r_refdef.view.colorscale * r_hdr_glowintensity.value;
-               texture.render_modellight_lightdir[q] = q == 2;
-               texture.render_modellight_ambient[q] = r_refdef.view.colorscale * r_refdef.scene.ambientintensity;
-               texture.render_modellight_diffuse[q] = r_refdef.view.colorscale;
-               texture.render_modellight_specular[q] = r_refdef.view.colorscale;
-               texture.render_lightmap_ambient[q] = r_refdef.view.colorscale * r_refdef.scene.ambientintensity;
-               texture.render_lightmap_diffuse[q] = r_refdef.view.colorscale * r_refdef.scene.lightmapintensity;
-               texture.render_lightmap_specular[q] = r_refdef.view.colorscale;
-               texture.render_rtlight_diffuse[q] = r_refdef.view.colorscale;
-               texture.render_rtlight_specular[q] = r_refdef.view.colorscale;
-       }
-       texture.currentalpha = 1.0f;
 
-       surface.texture = &texture;
-       surface.num_triangles = numtriangles;
-       surface.num_firsttriangle = firsttriangle;
-       surface.num_vertices = numvertices;
-       surface.num_firstvertex = firstvertex;
-
-       // now render it
-       rsurface.texture = R_GetCurrentTexture(surface.texture);
-       rsurface.lightmaptexture = NULL;
-       rsurface.deluxemaptexture = NULL;
-       rsurface.uselightmaptexture = false;
-       R_DrawModelTextureSurfaceList(1, &surfacelist, writedepth, prepass);
+       R_DrawCustomSurface_Texture(&texture, texmatrix, materialflags, firstvertex, numvertices, firsttriangle, numtriangles, writedepth, prepass);
 }
 
 void R_DrawCustomSurface_Texture(texture_t *texture, const matrix4x4_t *texmatrix, int materialflags, int firstvertex, int numvertices, int firsttriangle, int numtriangles, qboolean writedepth, qboolean prepass)