summaryrefslogtreecommitdiff
path: root/src/engine/shadowmap.cpp
diff options
context:
space:
mode:
authorxolatile2025-08-06 22:54:55 +0200
committerxolatile2025-08-06 22:54:55 +0200
commit0a1172b75f571685c264a8b9d8ee224bbf11381f (patch)
treed041fdc68a60f0ebb48a3852bbcce6d9432f83d5 /src/engine/shadowmap.cpp
parentaffde05dc07a94643f1fd2751b2b441f57f73d7d (diff)
downloadxolatile-badassbug-0a1172b75f571685c264a8b9d8ee224bbf11381f.tar.xz
xolatile-badassbug-0a1172b75f571685c264a8b9d8ee224bbf11381f.tar.zst
Please do not hate me, it makes sense...
Diffstat (limited to 'src/engine/shadowmap.cpp')
-rw-r--r--src/engine/shadowmap.cpp100
1 files changed, 21 insertions, 79 deletions
diff --git a/src/engine/shadowmap.cpp b/src/engine/shadowmap.cpp
index 24a6fe5..1eefe4b 100644
--- a/src/engine/shadowmap.cpp
+++ b/src/engine/shadowmap.cpp
@@ -11,8 +11,7 @@ VARP(shadowmapdist, 128, 256, 512);
VARFP(fpshadowmap, 0, 0, 1, cleanshadowmap());
VARFP(shadowmapprecision, 0, 0, 1, cleanshadowmap());
bvec shadowmapambientcolor(0, 0, 0);
-HVARFR(shadowmapambient, 0, 0, 0xFFFFFF,
-{
+HVARFR(shadowmapambient, 0, 0, 0xFFFFFF, {
if(shadowmapambient <= 255) shadowmapambient |= (shadowmapambient<<8) | (shadowmapambient<<16);
shadowmapambientcolor = bvec((shadowmapambient>>16)&0xFF, (shadowmapambient>>8)&0xFF, shadowmapambient&0xFF);
});
@@ -27,36 +26,29 @@ vec shadowoffset(0, 0, 0), shadowfocus(0, 0, 0), shadowdir(0, SHADOWSKEW, 1);
VAR(shadowmapcasters, 1, 0, 0);
float shadowmapmaxz = 0;
-void setshadowdir(int angle)
-{
+void setshadowdir(int angle) {
shadowdir = vec(0, SHADOWSKEW, 1);
shadowdir.rotate_around_z(angle*RAD);
}
VARFR(shadowmapangle, 0, 0, 360, setshadowdir(shadowmapangle));
-void guessshadowdir()
-{
+void guessshadowdir() {
if(shadowmapangle) return;
- vec dir;
- {
+ vec dir; {
vec lightpos(0, 0, 0), casterpos(0, 0, 0);
int numlights = 0, numcasters = 0;
const vector<extentity *> &ents = entities::getents();
- loopv(ents)
- {
+ loopv(ents) {
extentity &e = *ents[i];
- switch(e.type)
- {
+ switch(e.type) {
case ET_LIGHT:
if(!e.attr1) { lightpos.add(e.o); numlights++; }
break;
-
case ET_MAPMODEL:
casterpos.add(e.o);
numcasters++;
break;
-
default:
if(e.type<ET_GAMESPECIFIC) break;
casterpos.add(e.o);
@@ -86,148 +78,112 @@ VARP(shadowmappeelbias, 0, 20, 1024);
VAR(smdepthpeel, 0, 1, 1);
VAR(smoothshadowmappeel, 1, 0, 0);
-static struct shadowmaptexture : rendertarget
-{
- const GLenum *colorformats() const
- {
+static struct shadowmaptexture : rendertarget {
+ const GLenum *colorformats() const {
static const GLenum rgbafmts[] = { GL_RGBA16F, GL_RGBA16, GL_RGBA, GL_RGBA8, GL_FALSE };
return &rgbafmts[fpshadowmap && hasTF ? 0 : (shadowmapprecision ? 1 : 2)];
}
-
bool swaptexs() const { return true; }
-
- bool scissorblur(int &x, int &y, int &w, int &h)
- {
+ bool scissorblur(int &x, int &y, int &w, int &h) {
x = max(int(floor((scissorx1+1)/2*vieww)) - 2*blursize, 2);
y = max(int(floor((scissory1+1)/2*viewh)) - 2*blursize, 2);
w = min(int(ceil((scissorx2+1)/2*vieww)) + 2*blursize, vieww-2) - x;
h = min(int(ceil((scissory2+1)/2*viewh)) + 2*blursize, viewh-2) - y;
return true;
}
-
- bool scissorrender(int &x, int &y, int &w, int &h)
- {
+ bool scissorrender(int &x, int &y, int &w, int &h) {
x = y = 2;
w = vieww - 2*2;
h = viewh - 2*2;
return true;
}
-
- void doclear()
- {
+ void doclear() {
glClearColor(0, 0, 0, 0);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
}
-
- bool dorender()
- {
+ bool dorender() {
vec skewdir(shadowdir);
skewdir.rotate_around_z(-camera1->yaw*RAD);
-
vec dir;
vecfromyawpitch(camera1->yaw, camera1->pitch, 1, 0, dir);
dir.z = 0;
dir.mul(shadowmapradius);
-
vec dirx, diry;
vecfromyawpitch(camera1->yaw, 0, 0, 1, dirx);
vecfromyawpitch(camera1->yaw, 0, 1, 0, diry);
shadowoffset.x = -fmod(dirx.dot(camera1->o) - skewdir.x*camera1->o.z, 2.0f*shadowmapradius/vieww);
shadowoffset.y = -fmod(diry.dot(camera1->o) - skewdir.y*camera1->o.z, 2.0f*shadowmapradius/viewh);
-
shadowmatrix.ortho(-shadowmapradius, shadowmapradius, -shadowmapradius, shadowmapradius, -shadowmapdist, shadowmapdist);
shadowmatrix.mul(matrix3(vec(1, 0, 0), vec(0, 1, 0), vec(skewdir.x, skewdir.y, 1)));
shadowmatrix.translate(skewdir.x*shadowmapheight + shadowoffset.x, skewdir.y*shadowmapheight + shadowoffset.y + dir.magnitude(), -shadowmapheight);
shadowmatrix.rotate_around_z((camera1->yaw+180)*-RAD);
shadowmatrix.translate(vec(camera1->o).neg());
GLOBALPARAM(shadowmatrix, shadowmatrix);
-
shadowfocus = camera1->o;
shadowfocus.add(dir);
shadowfocus.add(vec(shadowdir).mul(shadowmapheight));
shadowfocus.add(dirx.mul(shadowoffset.x));
shadowfocus.add(diry.mul(shadowoffset.y));
-
gle::colorf(0, 0, 0);
-
GLOBALPARAMF(shadowmapbias, -shadowmapbias/float(shadowmapdist), 1 - (shadowmapbias + (smoothshadowmappeel ? 0 : shadowmappeelbias))/float(shadowmapdist));
-
shadowmapcasters = 0;
shadowmapmaxz = shadowfocus.z - shadowmapdist;
shadowmapping = true;
rendergame();
shadowmapping = false;
shadowmapmaxz = min(shadowmapmaxz, shadowfocus.z);
-
- if(shadowmapcasters && smdepthpeel)
- {
+ if(shadowmapcasters && smdepthpeel) {
int sx, sy, sw, sh;
bool scissoring = rtscissor && scissorblur(sx, sy, sw, sh) && sw > 0 && sh > 0;
if(scissoring) glScissor(sx, sy, sw, sh);
if(!rtscissor || scissoring) rendershadowmapreceivers();
}
-
return shadowmapcasters>0;
}
} shadowmaptex;
-void cleanshadowmap()
-{
+void cleanshadowmap() {
shadowmaptex.cleanup(true);
}
-void calcshadowmapbb(const vec &o, float xyrad, float zrad, float &x1, float &y1, float &x2, float &y2)
-{
+void calcshadowmapbb(const vec &o, float xyrad, float zrad, float &x1, float &y1, float &x2, float &y2) {
vec skewdir(shadowdir);
skewdir.rotate_around_z(-camera1->yaw*RAD);
-
vec ro(o);
ro.sub(camera1->o);
ro.rotate_around_z(-(camera1->yaw+180)*RAD);
ro.x += ro.z * skewdir.x + shadowoffset.x;
ro.y += ro.z * skewdir.y + shadowmapradius * cosf(camera1->pitch*RAD) + shadowoffset.y;
-
vec high(ro), low(ro);
high.x += zrad * skewdir.x;
high.y += zrad * skewdir.y;
low.x -= zrad * skewdir.x;
low.y -= zrad * skewdir.y;
-
x1 = (min(high.x, low.x) - xyrad) / shadowmapradius;
y1 = (min(high.y, low.y) - xyrad) / shadowmapradius;
x2 = (max(high.x, low.x) + xyrad) / shadowmapradius;
y2 = (max(high.y, low.y) + xyrad) / shadowmapradius;
}
-bool addshadowmapcaster(const vec &o, float xyrad, float zrad)
-{
+bool addshadowmapcaster(const vec &o, float xyrad, float zrad) {
if(o.z + zrad <= shadowfocus.z - shadowmapdist || o.z - zrad >= shadowfocus.z) return false;
-
shadowmapmaxz = max(shadowmapmaxz, o.z + zrad);
-
float x1, y1, x2, y2;
calcshadowmapbb(o, xyrad, zrad, x1, y1, x2, y2);
-
if(!shadowmaptex.addblurtiles(x1, y1, x2, y2, 2)) return false;
-
shadowmapcasters++;
return true;
}
-bool isshadowmapreceiver(vtxarray *va)
-{
+bool isshadowmapreceiver(vtxarray *va) {
if(!shadowmap || !shadowmapcasters) return false;
-
if(va->shadowmapmax.z <= shadowfocus.z - shadowmapdist || va->shadowmapmin.z >= shadowmapmaxz) return false;
-
float xyrad = SQRT2*0.5f*max(va->shadowmapmax.x-va->shadowmapmin.x, va->shadowmapmax.y-va->shadowmapmin.y),
zrad = 0.5f*(va->shadowmapmax.z-va->shadowmapmin.z),
x1, y1, x2, y2;
if(xyrad<0 || zrad<0) return false;
-
vec center = vec(va->shadowmapmin).add(vec(va->shadowmapmax)).mul(0.5f);
calcshadowmapbb(center, xyrad, zrad, x1, y1, x2, y2);
-
return shadowmaptex.checkblurtiles(x1, y1, x2, y2, 2);
#if 0
@@ -244,8 +200,7 @@ bool isshadowmapreceiver(vtxarray *va)
#endif
}
-bool isshadowmapcaster(const vec &o, float rad)
-{
+bool isshadowmapcaster(const vec &o, float rad) {
// cheaper inexact test
float dz = o.z - shadowfocus.z;
float cx = shadowfocus.x + dz*shadowdir.x, cy = shadowfocus.y + dz*shadowdir.y;
@@ -258,22 +213,16 @@ bool isshadowmapcaster(const vec &o, float rad)
return true;
}
-void pushshadowmap()
-{
+void pushshadowmap() {
if(!shadowmap || !shadowmaptex.rendertex) return;
-
glActiveTexture_(GL_TEXTURE7);
glBindTexture(GL_TEXTURE_2D, shadowmaptex.rendertex);
-
matrix4 m = shadowmatrix;
m.projective(-1, 1-shadowmapbias/float(shadowmapdist));
GLOBALPARAM(shadowmapproject, m);
-
glActiveTexture_(GL_TEXTURE0);
-
float r, g, b;
- if(!shadowmapambient)
- {
+ if(!shadowmapambient) {
r = max(25.0f, 2.0f*ambientcolor[0]);
g = max(25.0f, 2.0f*ambientcolor[1]);
b = max(25.0f, 2.0f*ambientcolor[2]);
@@ -282,14 +231,7 @@ void pushshadowmap()
GLOBALPARAMF(shadowmapambient, r/255.0f, g/255.0f, b/255.0f);
}
-void popshadowmap()
-{
- if(!shadowmap || !shadowmaptex.rendertex) return;
-}
-
-void rendershadowmap()
-{
+void rendershadowmap() {
if(!shadowmap) return;
-
shadowmaptex.render(1<<shadowmapsize, 1<<shadowmapsize, blurshadowmap, blursmsigma/100.0f);
}