]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - gl_rmain.c
Implemented r_sky_scissor feature (on by default) - this limits rendering of sky...
[xonotic/darkplaces.git] / gl_rmain.c
index cd3d41ee4c64281e5111ec0092f396c51b1921f2..a51d300f7b29d179c85922face966f0aef22f9b0 100644 (file)
@@ -3129,6 +3129,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 +3155,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 +3220,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 )
        {
@@ -10522,6 +10511,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 +10519,52 @@ 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];
+                       for (j = 0, v = rsurface.batchvertex3f + 3 * surf->num_firstvertex; j < surf->num_vertices; j++, v += 3)
+                       {
+                               Matrix4x4_Transform(&rsurface.matrix, v, p);
+                               if (skyscissor)
+                               {
+                                       if (skyscissormins[0] > p[0]) skyscissormins[0] = p[0];
+                                       if (skyscissormins[1] > p[1]) skyscissormins[1] = p[1];
+                                       if (skyscissormins[2] > p[2]) skyscissormins[2] = p[2];
+                                       if (skyscissormaxs[0] < p[0]) skyscissormaxs[0] = p[0];
+                                       if (skyscissormaxs[1] < p[1]) skyscissormaxs[1] = p[1];
+                                       if (skyscissormaxs[2] < p[2]) skyscissormaxs[2] = p[2];
+                               }
+                               else
+                               {
+                                       VectorCopy(p, skyscissormins);
+                                       VectorCopy(p, skyscissormaxs);
+                                       skyscissor = true;
+                               }
+                       }
+               }
+       }
+
+       // 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);