diff options
| author | xolatile | 2025-08-06 22:54:55 +0200 |
|---|---|---|
| committer | xolatile | 2025-08-06 22:54:55 +0200 |
| commit | 0a1172b75f571685c264a8b9d8ee224bbf11381f (patch) | |
| tree | d041fdc68a60f0ebb48a3852bbcce6d9432f83d5 /src/engine/rendertarget.h | |
| parent | affde05dc07a94643f1fd2751b2b441f57f73d7d (diff) | |
| download | xolatile-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.h | 181 |
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); } |
