ref: a5b441d0296071fa3b3eb6a3e7501e781da9cb4d
parent: 67e63b7e1b4b799192b3e9c8a9702e54c83b67d1
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Sun Dec 17 19:06:37 EST 2023
fog: R_BlendFog for external callers
--- a/d_local.h
+++ b/d_local.h
@@ -33,8 +33,6 @@
int u, v, count;
} sspan_t;
-typedef s32int uzint;
-
extern cvar_t d_subdiv16;
extern float scale_for_mip;
--- a/r_fog.c
+++ b/r_fog.c
@@ -6,6 +6,7 @@
static struct {
float density;
pixel_t color;
+ byte c0, c1, c2;
}r_fog_data;
static void
@@ -20,7 +21,7 @@
case 5:
case 2:
x = atof(Cmd_Argv(i++));
- r_fog_data.density = max(0.0, x) * 0.016;
+ r_fog_data.density = clamp(x, 0.0, 1.0) * 0.016;
r_fog_data.density *= r_fog_data.density;
if(n == 2)
break;
@@ -30,6 +31,9 @@
x = atof(Cmd_Argv(i));
r_fog_data.color = r_fog_data.color << 8 | (int)(0xff * clamp(x, 0.0, 1.0));
}
+ r_fog_data.c0 = r_fog_data.color>> 0;
+ r_fog_data.c1 = r_fog_data.color>> 8;
+ r_fog_data.c2 = r_fog_data.color>>16;
break;
}
}
@@ -42,45 +46,52 @@
setcvar("r_skyfog", "0");
}
+pixel_t
+R_BlendFog(pixel_t pix, uzint z)
+{
+ byte a;
+ float d;
+
+ if(r_fog.value <= 0 || r_fog_data.density <= 0.0)
+ return pix;
+
+ if(z > 65536){
+ d = 65536ULL*65536ULL / (u64int)z;
+ if((pix & ~0xffffff) == 0)
+ d /= 1.5;
+ d = 1.0 - exp2(-r_fog_data.density * d*d);
+ a = 255*d;
+ }else if(z < 0){
+ a = 255 * clamp(r_skyfog.value, 0, 1.0);
+ }else
+ a = 0;
+
+ if(a == 0)
+ return pix;
+
+ return
+ ((a*r_fog_data.c0 + (255-a)*((pix>> 0)&0xff)) >> 8) << 0 |
+ ((a*r_fog_data.c1 + (255-a)*((pix>> 8)&0xff)) >> 8) << 8 |
+ ((a*r_fog_data.c2 + (255-a)*((pix>>16)&0xff)) >> 8) << 16;
+}
+
void
R_DrawFog(void)
{
- byte ca0, ca1, ca2, skyfogalpha, a;
pixel_t *pix;
int i, x, y;
uzint *z;
- float d;
if(r_fog.value <= 0 || r_fog_data.density <= 0.0)
return;
- ca0 = r_fog_data.color>> 0;
- ca1 = r_fog_data.color>> 8;
- ca2 = r_fog_data.color>>16;
-
- skyfogalpha = 255 * clamp(r_skyfog.value, 0, 1.0);
/* FIXME(sigrid): this is super slow */
for(y = r_refdef.vrect.y; y < r_refdef.vrectbottom; y++){
i = y * vid.width + r_refdef.vrect.x;
pix = vid.buffer + i;
z = d_pzbuffer + i;
- for(x = r_refdef.vrect.x; x < r_refdef.vrectright; x++, i++, pix++, z++){
- if(*z > 65536){
- d = 65536.0 / (float)(*z >> 16);
- d = 1.0 - exp2(-r_fog_data.density * d*d);
- a = 255*clamp(d, 0.0, 1.0);
- }else if(*z < 0){
- a = skyfogalpha;
- }else
- continue;
-
- if(a > 0){
- *pix =
- ((a*ca0 + (255-a)*((*pix>> 0)&0xff)) >> 8) << 0 |
- ((a*ca1 + (255-a)*((*pix>> 8)&0xff)) >> 8) << 8 |
- ((a*ca2 + (255-a)*((*pix>>16)&0xff)) >> 8) << 16;
- }
- }
+ for(x = r_refdef.vrect.x; x < r_refdef.vrectright; x++, i++, pix++, z++)
+ *pix = R_BlendFog(*pix, *z);
}
}
--- a/r_local.h
+++ b/r_local.h
@@ -102,6 +102,7 @@
extern int r_drawflags;
void R_ResetFog(void);
+pixel_t R_BlendFog(pixel_t pix, uzint z);
void R_DrawFog(void);
void R_InitFog(void);
--- a/r_shared.h
+++ b/r_shared.h
@@ -13,6 +13,8 @@
#define SIN_BUFFER_SIZE (MAXDIMENSION+CYCLE)
+typedef s32int uzint;
+
//===================================================================
extern int cachewidth;