summaryrefslogtreecommitdiff
path: root/src/engine/rendertarget.h
diff options
context:
space:
mode:
authorxolatile2025-08-06 22:54:55 +0200
committerxolatile2025-08-06 22:54:55 +0200
commit0a1172b75f571685c264a8b9d8ee224bbf11381f (patch)
treed041fdc68a60f0ebb48a3852bbcce6d9432f83d5 /src/engine/rendertarget.h
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/rendertarget.h')
-rw-r--r--src/engine/rendertarget.h181
1 files changed, 40 insertions, 141 deletions
diff --git a/src/engine/rendertarget.h b/src/engine/rendertarget.h
index a22298b..e89393a 100644
--- a/src/engine/rendertarget.h
+++ b/src/engine/rendertarget.h
@@ -1,7 +1,6 @@
extern int rtsharefb, rtscissor, blurtile;
-struct rendertarget
-{
+struct rendertarget {
int texw, texh, vieww, viewh;
GLenum colorfmt, depthfmt;
GLuint rendertex, renderfb, renderdb, blurtex, blurfb, blurdb;
@@ -9,70 +8,49 @@ struct rendertarget
float blursigma;
float blurweights[MAXBLURRADIUS+1], bluroffsets[MAXBLURRADIUS+1];
float bluryweights[MAXBLURRADIUS+1], bluryoffsets[MAXBLURRADIUS+1];
-
float scissorx1, scissory1, scissorx2, scissory2;
#define BLURTILES 32
#define BLURTILEMASK (0xFFFFFFFFU>>(32-BLURTILES))
uint blurtiles[BLURTILES+1];
-
bool initialized;
-
- rendertarget() : texw(0), texh(0), vieww(0), viewh(0), colorfmt(GL_FALSE), depthfmt(GL_FALSE), rendertex(0), renderfb(0), renderdb(0), blurtex(0), blurfb(0), blurdb(0), blursize(0), blurysize(0), blursigma(0), initialized(false)
- {
+ rendertarget() : texw(0), texh(0), vieww(0), viewh(0), colorfmt(GL_FALSE), depthfmt(GL_FALSE), rendertex(0), renderfb(0), renderdb(0), blurtex(0), blurfb(0), blurdb(0), blursize(0), blurysize(0), blursigma(0), initialized(false) {
}
-
virtual ~rendertarget() {}
-
- virtual GLenum attachment() const
- {
+ virtual GLenum attachment() const {
return GL_COLOR_ATTACHMENT0;
}
-
- virtual const GLenum *colorformats() const
- {
+ virtual const GLenum *colorformats() const {
static const GLenum colorfmts[] = { GL_RGB, GL_RGB8, GL_FALSE };
return colorfmts;
}
-
- virtual const GLenum *depthformats() const
- {
+ virtual const GLenum *depthformats() const {
static const GLenum depthfmts[] = { GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT32, GL_FALSE };
return depthfmts;
}
-
virtual bool depthtest() const { return true; }
-
- void cleanup(bool fullclean = false)
- {
+ void cleanup(bool fullclean = false) {
if(renderfb) { glDeleteFramebuffers_(1, &renderfb); renderfb = 0; }
if(renderdb) { glDeleteRenderbuffers_(1, &renderdb); renderdb = 0; }
if(rendertex) { glDeleteTextures(1, &rendertex); rendertex = 0; }
texw = texh = 0;
cleanupblur();
-
if(fullclean) colorfmt = depthfmt = GL_FALSE;
}
-
- void cleanupblur()
- {
+ void cleanupblur() {
if(blurfb) { glDeleteFramebuffers_(1, &blurfb); blurfb = 0; }
if(blurtex) { glDeleteTextures(1, &blurtex); blurtex = 0; }
if(blurdb) { glDeleteRenderbuffers_(1, &blurdb); blurdb = 0; }
blursize = blurysize = 0;
blursigma = 0.0f;
}
-
- void setupblur()
- {
+ void setupblur() {
if(!blurtex) glGenTextures(1, &blurtex);
createtexture(blurtex, texw, texh, NULL, 3, 1, colorfmt);
-
if(!swaptexs() || rtsharefb) return;
if(!blurfb) glGenFramebuffers_(1, &blurfb);
glBindFramebuffer_(GL_FRAMEBUFFER, blurfb);
glFramebufferTexture2D_(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, blurtex, 0);
- if(depthtest())
- {
+ if(depthtest()) {
if(!blurdb) glGenRenderbuffers_(1, &blurdb);
glGenRenderbuffers_(1, &blurdb);
glBindRenderbuffer_(GL_RENDERBUFFER, blurdb);
@@ -81,39 +59,30 @@ struct rendertarget
}
glBindFramebuffer_(GL_FRAMEBUFFER, 0);
}
-
- void setup(int w, int h)
- {
+ void setup(int w, int h) {
if(!renderfb) glGenFramebuffers_(1, &renderfb);
glBindFramebuffer_(GL_FRAMEBUFFER, renderfb);
if(!rendertex) glGenTextures(1, &rendertex);
-
GLenum attach = attachment();
- if(attach == GL_DEPTH_ATTACHMENT)
- {
+ if(attach == GL_DEPTH_ATTACHMENT) {
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
}
-
const GLenum *colorfmts = colorformats();
int find = 0;
- do
- {
+ do {
createtexture(rendertex, w, h, NULL, 3, filter() ? 1 : 0, colorfmt ? colorfmt : colorfmts[find]);
glFramebufferTexture2D_(GL_FRAMEBUFFER, attach, GL_TEXTURE_2D, rendertex, 0);
if(glCheckFramebufferStatus_(GL_FRAMEBUFFER)==GL_FRAMEBUFFER_COMPLETE) break;
}
while(!colorfmt && colorfmts[++find]);
if(!colorfmt) colorfmt = colorfmts[find];
-
- if(attach != GL_DEPTH_ATTACHMENT && depthtest())
- {
+ if(attach != GL_DEPTH_ATTACHMENT && depthtest()) {
if(!renderdb) { glGenRenderbuffers_(1, &renderdb); depthfmt = GL_FALSE; }
if(!depthfmt) glBindRenderbuffer_(GL_RENDERBUFFER, renderdb);
const GLenum *depthfmts = depthformats();
find = 0;
- do
- {
+ do {
if(!depthfmt) glRenderbufferStorage_(GL_RENDERBUFFER, depthfmts[find], w, h);
glFramebufferRenderbuffer_(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderdb);
if(glCheckFramebufferStatus_(GL_FRAMEBUFFER)==GL_FRAMEBUFFER_COMPLETE) break;
@@ -121,72 +90,53 @@ struct rendertarget
while(!depthfmt && depthfmts[++find]);
if(!depthfmt) depthfmt = depthfmts[find];
}
-
glBindFramebuffer_(GL_FRAMEBUFFER, 0);
-
texw = w;
texh = h;
initialized = false;
}
-
- bool addblurtiles(float x1, float y1, float x2, float y2, float blurmargin = 0)
- {
+ bool addblurtiles(float x1, float y1, float x2, float y2, float blurmargin = 0) {
if(x1 >= 1 || y1 >= 1 || x2 <= -1 || y2 <= -1) return false;
-
scissorx1 = min(scissorx1, max(x1, -1.0f));
scissory1 = min(scissory1, max(y1, -1.0f));
scissorx2 = max(scissorx2, min(x2, 1.0f));
scissory2 = max(scissory2, min(y2, 1.0f));
-
float blurerror = 2.0f*float(2*blursize + blurmargin);
int tx1 = max(0, min(BLURTILES - 1, int((x1-blurerror/vieww + 1)/2 * BLURTILES))),
ty1 = max(0, min(BLURTILES - 1, int((y1-blurerror/viewh + 1)/2 * BLURTILES))),
tx2 = max(0, min(BLURTILES - 1, int((x2+blurerror/vieww + 1)/2 * BLURTILES))),
ty2 = max(0, min(BLURTILES - 1, int((y2+blurerror/viewh + 1)/2 * BLURTILES)));
-
uint mask = (BLURTILEMASK>>(BLURTILES - (tx2+1))) & (BLURTILEMASK<<tx1);
for(int y = ty1; y <= ty2; y++) blurtiles[y] |= mask;
return true;
}
-
- bool checkblurtiles(float x1, float y1, float x2, float y2, float blurmargin = 0)
- {
+ bool checkblurtiles(float x1, float y1, float x2, float y2, float blurmargin = 0) {
float blurerror = 2.0f*float(2*blursize + blurmargin);
if(x2+blurerror/vieww < scissorx1 || y2+blurerror/viewh < scissory1 ||
x1-blurerror/vieww > scissorx2 || y1-blurerror/viewh > scissory2)
return false;
-
if(!blurtile) return true;
-
int tx1 = max(0, min(BLURTILES - 1, int((x1 + 1)/2 * BLURTILES))),
ty1 = max(0, min(BLURTILES - 1, int((y1 + 1)/2 * BLURTILES))),
tx2 = max(0, min(BLURTILES - 1, int((x2 + 1)/2 * BLURTILES))),
ty2 = max(0, min(BLURTILES - 1, int((y2 + 1)/2 * BLURTILES)));
-
uint mask = (BLURTILEMASK>>(BLURTILES - (tx2+1))) & (BLURTILEMASK<<tx1);
for(int y = ty1; y <= ty2; y++) if(blurtiles[y] & mask) return true;
-
return false;
}
-
- void rendertiles()
- {
+ void rendertiles() {
float wscale = vieww/float(texw), hscale = viewh/float(texh);
- if(blurtile && scissorx1 < scissorx2 && scissory1 < scissory2)
- {
+ if(blurtile && scissorx1 < scissorx2 && scissory1 < scissory2) {
uint tiles[sizeof(blurtiles)/sizeof(uint)];
memcpy(tiles, blurtiles, sizeof(blurtiles));
-
LOCALPARAMF(screentexcoord0, wscale*0.5f, hscale*0.5f, wscale*0.5f, hscale*0.5f);
gle::defvertex(2);
gle::begin(GL_QUADS);
float tsz = 1.0f/BLURTILES;
- loop(y, BLURTILES+1)
- {
+ loop(y, BLURTILES+1) {
uint mask = tiles[y];
int x = 0;
- while(mask)
- {
+ while(mask) {
while(!(mask&0xFF)) { mask >>= 8; x += 8; }
while(!(mask&1)) { mask >>= 1; x++; }
int xstart = x;
@@ -207,71 +157,49 @@ struct rendertarget
}
gle::end();
}
- else
- {
+ else {
screenquad(wscale, hscale);
}
}
-
- void blur(int wantsblursize, float wantsblursigma, int wantsblurysize, int x, int y, int w, int h, bool scissor)
- {
+ void blur(int wantsblursize, float wantsblursigma, int wantsblurysize, int x, int y, int w, int h, bool scissor) {
if(!blurtex) setupblur();
- if(blursize!=wantsblursize || blurysize != wantsblurysize || (wantsblursize && blursigma!=wantsblursigma))
- {
+ if(blursize!=wantsblursize || blurysize != wantsblurysize || (wantsblursize && blursigma!=wantsblursigma)) {
setupblurkernel(wantsblursize, wantsblursigma, blurweights, bluroffsets);
if(wantsblurysize != wantsblursize) setupblurkernel(wantsblurysize, wantsblursigma, bluryweights, bluryoffsets);
blursize = wantsblursize;
blursigma = wantsblursigma;
blurysize = wantsblurysize;
}
-
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
-
- if(scissor)
- {
+ if(scissor) {
glScissor(x, y, w, h);
glEnable(GL_SCISSOR_TEST);
}
-
- loopi(2)
- {
+ loopi(2) {
if(i && blurysize != blursize) setblurshader(i, texh, blurysize, bluryweights, bluryoffsets);
else setblurshader(i, i ? texh : texw, blursize, blurweights, bluroffsets);
-
if(!swaptexs() || rtsharefb) glFramebufferTexture2D_(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, i ? rendertex : blurtex, 0);
else glBindFramebuffer_(GL_FRAMEBUFFER, i ? renderfb : blurfb);
glBindTexture(GL_TEXTURE_2D, i ? blurtex : rendertex);
-
rendertiles();
}
-
if(scissor) glDisable(GL_SCISSOR_TEST);
-
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
}
-
virtual bool swaptexs() const { return false; }
-
virtual bool dorender() { return true; }
-
virtual bool shouldrender() { return true; }
-
- virtual void doblur(int blursize, float blursigma, int blurysize)
- {
+ virtual void doblur(int blursize, float blursigma, int blurysize) {
int sx, sy, sw, sh;
bool scissoring = rtscissor && scissorblur(sx, sy, sw, sh) && sw > 0 && sh > 0;
if(!scissoring) { sx = sy = 0; sw = vieww; sh = viewh; }
blur(blursize, blursigma, blurysize, sx, sy, sw, sh, scissoring);
}
-
- virtual bool scissorrender(int &x, int &y, int &w, int &h)
- {
- if(scissorx1 >= scissorx2 || scissory1 >= scissory2)
- {
- if(vieww < texw || viewh < texh)
- {
+ virtual bool scissorrender(int &x, int &y, int &w, int &h) {
+ if(scissorx1 >= scissorx2 || scissory1 >= scissory2) {
+ if(vieww < texw || viewh < texh) {
x = y = 0;
w = vieww;
h = viewh;
@@ -285,13 +213,9 @@ struct rendertarget
h = min(int(ceil((scissory2+1)/2*viewh)) + 2*blursize, viewh) - y;
return true;
}
-
- virtual bool scissorblur(int &x, int &y, int &w, int &h)
- {
- if(scissorx1 >= scissorx2 || scissory1 >= scissory2)
- {
- if(vieww < texw || viewh < texh)
- {
+ virtual bool scissorblur(int &x, int &y, int &w, int &h) {
+ if(scissorx1 >= scissorx2 || scissory1 >= scissory2) {
+ if(vieww < texw || viewh < texh) {
x = y = 0;
w = vieww;
h = viewh;
@@ -305,45 +229,32 @@ struct rendertarget
h = min(int(ceil((scissory2+1)/2*viewh)), viewh) - y;
return true;
}
-
virtual void doclear() {}
-
virtual bool screenrect() const { return false; }
virtual bool filter() const { return true; }
-
- void render(int w, int h, int blursize = 0, float blursigma = 0, int blurysize = 0)
- {
+ void render(int w, int h, int blursize = 0, float blursigma = 0, int blurysize = 0) {
w = min(w, hwtexsize);
h = min(h, hwtexsize);
- if(screenrect())
- {
+ if(screenrect()) {
if(w > screenw) w = screenw;
if(h > screenh) h = screenh;
}
vieww = w;
viewh = h;
if(w!=texw || h!=texh || (swaptexs() && !rtsharefb ? !blurfb : blurfb)) cleanup();
-
- if(!filter())
- {
+ if(!filter()) {
if(blurtex) cleanupblur();
blursize = blurysize = 0;
}
-
if(!rendertex) setup(w, h);
-
scissorx2 = scissory2 = -1;
scissorx1 = scissory1 = 1;
memset(blurtiles, 0, sizeof(blurtiles));
-
if(!shouldrender()) return;
-
if(blursize && !blurtex) setupblur();
- if(swaptexs() && blursize)
- {
+ if(swaptexs() && blursize) {
swap(rendertex, blurtex);
- if(!rtsharefb)
- {
+ if(!rtsharefb) {
swap(renderfb, blurfb);
swap(renderdb, blurdb);
}
@@ -352,38 +263,26 @@ struct rendertarget
if(swaptexs() && blursize && rtsharefb)
glFramebufferTexture2D_(GL_FRAMEBUFFER, attachment(), GL_TEXTURE_2D, rendertex, 0);
glViewport(0, 0, vieww, viewh);
-
doclear();
-
int sx, sy, sw, sh;
bool scissoring = rtscissor && scissorrender(sx, sy, sw, sh) && sw > 0 && sh > 0;
- if(scissoring)
- {
+ if(scissoring) {
glScissor(sx, sy, sw, sh);
glEnable(GL_SCISSOR_TEST);
}
- else
- {
+ else {
sx = sy = 0;
sw = vieww;
sh = viewh;
}
-
if(!depthtest()) glDisable(GL_DEPTH_TEST);
-
bool succeeded = dorender();
-
if(!depthtest()) glEnable(GL_DEPTH_TEST);
-
if(scissoring) glDisable(GL_SCISSOR_TEST);
-
- if(succeeded)
- {
+ if(succeeded) {
initialized = true;
-
if(blursize) doblur(blursize, blursigma, blurysize ? blurysize : blursize);
}
-
glBindFramebuffer_(GL_FRAMEBUFFER, 0);
glViewport(0, 0, screenw, screenh);
}