]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - gl_rmain.c
q1bsp: Only warn once per "bad animating texture".
[xonotic/darkplaces.git] / gl_rmain.c
index 7b074b7e03515022f0285ec9f93365dcd29c351b..3d9686e0c7f851f0c5dada0cb014f14c935b7f81 100644 (file)
@@ -184,6 +184,7 @@ cvar_t r_glsl_postprocess_uservec3_enable = {CVAR_SAVE, "r_glsl_postprocess_user
 cvar_t r_glsl_postprocess_uservec4_enable = {CVAR_SAVE, "r_glsl_postprocess_uservec4_enable", "1", "enables postprocessing uservec4 usage, creates USERVEC1 define (only useful if default.glsl has been customized)"};
 
 cvar_t r_water = {CVAR_SAVE, "r_water", "0", "whether to use reflections and refraction on water surfaces (note: r_wateralpha must be set below 1)"};
+cvar_t r_water_cameraentitiesonly = {CVAR_SAVE, "r_water_cameraentitiesonly", "0", "whether to only show QC-defined reflections/refractions (typically used for camera- or portal-like effects)"};
 cvar_t r_water_clippingplanebias = {CVAR_SAVE, "r_water_clippingplanebias", "1", "a rather technical setting which avoids black pixels around water edges"};
 cvar_t r_water_resolutionmultiplier = {CVAR_SAVE, "r_water_resolutionmultiplier", "0.5", "multiplier for screen resolution when rendering refracted/reflected scenes, 1 is full quality, lower values are faster"};
 cvar_t r_water_refractdistort = {CVAR_SAVE, "r_water_refractdistort", "0.01", "how much water refractions shimmer"};
@@ -678,7 +679,8 @@ shaderpermutationinfo_t shaderpermutationinfo[SHADERPERMUTATION_COUNT] =
        {"#define USETRIPPY\n", " trippy"},
        {"#define USEDEPTHRGB\n", " depthrgb"},
        {"#define USEALPHAGENVERTEX\n", " alphagenvertex"},
-       {"#define USESKELETAL\n", " skeletal"}
+       {"#define USESKELETAL\n", " skeletal"},
+       {"#define USEOCCLUDE\n", " occlude"}
 };
 
 // NOTE: MUST MATCH ORDER OF SHADERMODE_* ENUMS!
@@ -2202,6 +2204,8 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                permutation |= SHADERPERMUTATION_TRIPPY;
        if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
                permutation |= SHADERPERMUTATION_ALPHAKILL;
+       if (rsurface.texture->currentmaterialflags & MATERIALFLAG_OCCLUDE)
+               permutation |= SHADERPERMUTATION_OCCLUDE;
        if (rsurface.texture->r_water_waterscroll[0] && rsurface.texture->r_water_waterscroll[1])
                permutation |= SHADERPERMUTATION_NORMALMAPSCROLLBLEND; // todo: make generic
        if (rsurfacepass == RSURFPASS_BACKGROUND)
@@ -3166,7 +3170,7 @@ void R_SetupShader_DeferredLight(const rtlight_t *rtlight)
 
 typedef struct
 {
-       int loadsequence; // incremented each level change
+       unsigned int loadsequence; // incremented each level change
        memexpandablearray_t array;
        skinframe_t *hash[SKINFRAME_HASH];
 }
@@ -4372,6 +4376,7 @@ void GL_Main_Init(void)
        Cvar_RegisterVariable(&r_celoutlines);
 
        Cvar_RegisterVariable(&r_water);
+       Cvar_RegisterVariable(&r_water_cameraentitiesonly);
        Cvar_RegisterVariable(&r_water_resolutionmultiplier);
        Cvar_RegisterVariable(&r_water_clippingplanebias);
        Cvar_RegisterVariable(&r_water_refractdistort);
@@ -5245,7 +5250,7 @@ static void R_View_UpdateEntityVisible (void)
                                r_refdef.viewcache.entityvisible[i] = true;
                }
        }
-       if(r_cullentities_trace.integer && r_refdef.scene.worldmodel->brush.TraceLineOfSight && !r_refdef.view.useclipplane && !r_trippy.integer)
+       if(r_cullentities_trace.integer && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.TraceLineOfSight && !r_refdef.view.useclipplane && !r_trippy.integer)
                // sorry, this check doesn't work for portal/reflection/refraction renders as the view origin is not useful for culling
        {
                for (i = 0;i < r_refdef.scene.numentities;i++)
@@ -5998,25 +6003,33 @@ void R_Water_AddWaterPlane(msurface_t *surface, int entno)
                }
        }
        planeindex = bestplaneindex;
-       p = r_fb.water.waterplanes + planeindex;
 
        // if this surface does not fit any known plane rendered this frame, add one
-       if ((planeindex < 0 || bestplanescore > 0.001f) && r_fb.water.numwaterplanes < r_fb.water.maxwaterplanes)
+       if (planeindex < 0 || bestplanescore > 0.001f)
        {
-               // store the new plane
-               planeindex = r_fb.water.numwaterplanes++;
-               p = r_fb.water.waterplanes + planeindex;
-               p->plane = plane;
-               // clear materialflags and pvs
-               p->materialflags = 0;
-               p->pvsvalid = false;
-               p->camera_entity = t->camera_entity;
-               VectorCopy(mins, p->mins);
-               VectorCopy(maxs, p->maxs);
+               if (r_fb.water.numwaterplanes < r_fb.water.maxwaterplanes)
+               {
+                       // store the new plane
+                       planeindex = r_fb.water.numwaterplanes++;
+                       p = r_fb.water.waterplanes + planeindex;
+                       p->plane = plane;
+                       // clear materialflags and pvs
+                       p->materialflags = 0;
+                       p->pvsvalid = false;
+                       p->camera_entity = t->camera_entity;
+                       VectorCopy(mins, p->mins);
+                       VectorCopy(maxs, p->maxs);
+               }
+               else
+               {
+                       // We're totally screwed.
+                       return;
+               }
        }
        else
        {
                // merge mins/maxs when we're adding this surface to the plane
+               p = r_fb.water.waterplanes + planeindex;
                p->mins[0] = min(p->mins[0], mins[0]);
                p->mins[1] = min(p->mins[1], mins[1]);
                p->mins[2] = min(p->mins[2], mins[2]);
@@ -6029,7 +6042,7 @@ void R_Water_AddWaterPlane(msurface_t *surface, int entno)
        if(!(p->materialflags & MATERIALFLAG_CAMERA))
        {
                // merge this surface's PVS into the waterplane
-               if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION | MATERIALFLAG_CAMERA) && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.FatPVS
+               if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION) && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.FatPVS
                 && r_refdef.scene.worldmodel->brush.PointInLeaf && r_refdef.scene.worldmodel->brush.PointInLeaf(r_refdef.scene.worldmodel, center)->clusterindex >= 0)
                {
                        r_refdef.scene.worldmodel->brush.FatPVS(r_refdef.scene.worldmodel, center, 2, p->pvsbits, sizeof(p->pvsbits), p->pvsvalid);
@@ -6081,6 +6094,8 @@ static void R_Water_ProcessPlanes(int fbo, rtexture_t *depthtexture, rtexture_t
        // make sure enough textures are allocated
        for (planeindex = 0, p = r_fb.water.waterplanes;planeindex < r_fb.water.numwaterplanes;planeindex++, p++)
        {
+               if (r_water_cameraentitiesonly.value != 0 && !p->camera_entity)
+                       continue;
                if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION))
                {
                        if (!p->texture_refraction)
@@ -6136,6 +6151,8 @@ static void R_Water_ProcessPlanes(int fbo, rtexture_t *depthtexture, rtexture_t
        r_fb.water.renderingscene = true;
        for (planeindex = 0, p = r_fb.water.waterplanes;planeindex < r_fb.water.numwaterplanes;planeindex++, p++)
        {
+               if (r_water_cameraentitiesonly.value != 0 && !p->camera_entity)
+                       continue;
                if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFLECTION))
                {
                        r_refdef.view = myview;
@@ -8420,7 +8437,7 @@ texture_t *R_GetCurrentTexture(texture_t *t)
                }
        }
 
-       return t->currentframe;
+       return t;
 }
 
 rsurfacestate_t rsurface;
@@ -11623,7 +11640,7 @@ void R_DecalSystem_Reset(decalsystem_t *decalsystem)
        memset(decalsystem, 0, sizeof(*decalsystem));
 }
 
-static void R_DecalSystem_SpawnTriangle(decalsystem_t *decalsystem, const float *v0, const float *v1, const float *v2, const float *t0, const float *t1, const float *t2, const float *c0, const float *c1, const float *c2, int triangleindex, int surfaceindex, int decalsequence)
+static void R_DecalSystem_SpawnTriangle(decalsystem_t *decalsystem, const float *v0, const float *v1, const float *v2, const float *t0, const float *t1, const float *t2, const float *c0, const float *c1, const float *c2, int triangleindex, int surfaceindex, unsigned int decalsequence)
 {
        tridecal_t *decal;
        tridecal_t *decals;
@@ -11703,7 +11720,7 @@ extern cvar_t cl_decals_bias;
 extern cvar_t cl_decals_models;
 extern cvar_t cl_decals_newsystem_intensitymultiplier;
 // baseparms, parms, temps
-static void R_DecalSystem_SplatTriangle(decalsystem_t *decalsystem, float r, float g, float b, float a, float s1, float t1, float s2, float t2, int decalsequence, qboolean dynamic, float (*planes)[4], matrix4x4_t *projection, int triangleindex, int surfaceindex)
+static void R_DecalSystem_SplatTriangle(decalsystem_t *decalsystem, float r, float g, float b, float a, float s1, float t1, float s2, float t2, unsigned int decalsequence, qboolean dynamic, float (*planes)[4], matrix4x4_t *projection, int triangleindex, int surfaceindex)
 {
        int cornerindex;
        int index;
@@ -11796,7 +11813,7 @@ static void R_DecalSystem_SplatTriangle(decalsystem_t *decalsystem, float r, flo
                for (cornerindex = 0;cornerindex < numpoints-2;cornerindex++)
                        R_DecalSystem_SpawnTriangle(decalsystem, v[0], v[cornerindex+1], v[cornerindex+2], tc[0], tc[cornerindex+1], tc[cornerindex+2], c[0], c[cornerindex+1], c[cornerindex+2], -1, surfaceindex, decalsequence);
 }
-static void R_DecalSystem_SplatEntity(entity_render_t *ent, const vec3_t worldorigin, const vec3_t worldnormal, float r, float g, float b, float a, float s1, float t1, float s2, float t2, float worldsize, int decalsequence)
+static void R_DecalSystem_SplatEntity(entity_render_t *ent, const vec3_t worldorigin, const vec3_t worldnormal, float r, float g, float b, float a, float s1, float t1, float s2, float t2, float worldsize, unsigned int decalsequence)
 {
        matrix4x4_t projection;
        decalsystem_t *decalsystem;
@@ -11957,7 +11974,7 @@ static void R_DecalSystem_SplatEntity(entity_render_t *ent, const vec3_t worldor
 }
 
 // do not call this outside of rendering code - use R_DecalSystem_SplatEntities instead
-static void R_DecalSystem_ApplySplatEntities(const vec3_t worldorigin, const vec3_t worldnormal, float r, float g, float b, float a, float s1, float t1, float s2, float t2, float worldsize, int decalsequence)
+static void R_DecalSystem_ApplySplatEntities(const vec3_t worldorigin, const vec3_t worldnormal, float r, float g, float b, float a, float s1, float t1, float s2, float t2, float worldsize, unsigned int decalsequence)
 {
        int renderentityindex;
        float worldmins[3];
@@ -11993,7 +12010,7 @@ typedef struct r_decalsystem_splatqueue_s
        float color[4];
        float tcrange[4];
        float worldsize;
-       int decalsequence;
+       unsigned int decalsequence;
 }
 r_decalsystem_splatqueue_t;
 
@@ -12032,7 +12049,7 @@ static void R_DrawModelDecals_FadeEntity(entity_render_t *ent)
        int i;
        decalsystem_t *decalsystem = &ent->decalsystem;
        int numdecals;
-       int killsequence;
+       unsigned int killsequence;
        tridecal_t *decal;
        float frametime;
        float lifetime;
@@ -12049,7 +12066,7 @@ static void R_DrawModelDecals_FadeEntity(entity_render_t *ent)
                return;
        }
 
-       killsequence = cl.decalsequence - max(1, cl_decals_max.integer);
+       killsequence = cl.decalsequence - bound(1, (unsigned int) cl_decals_max.integer, cl.decalsequence);
        lifetime = cl_decals_time.value + cl_decals_fadetime.value;
 
        if (decalsystem->lastupdatetime)
@@ -12064,7 +12081,7 @@ static void R_DrawModelDecals_FadeEntity(entity_render_t *ent)
                if (decal->color4f[0][3])
                {
                        decal->lived += frametime;
-                       if (killsequence - decal->decalsequence > 0 || decal->lived >= lifetime)
+                       if (killsequence > decal->decalsequence || decal->lived >= lifetime)
                        {
                                memset(decal, 0, sizeof(*decal));
                                if (decalsystem->freedecal > i)