From d309df4ce4d8ad0ed995a8e1c4267412a7782021 Mon Sep 17 00:00:00 2001 From: xolatile Date: Mon, 4 Aug 2025 22:53:42 +0200 Subject: Bunch of small changes... --- src/engine/rendertarget.h | 766 +++++++++++++++++++++++----------------------- 1 file changed, 383 insertions(+), 383 deletions(-) (limited to 'src/engine/rendertarget.h') diff --git a/src/engine/rendertarget.h b/src/engine/rendertarget.h index f1e13e6..a22298b 100644 --- a/src/engine/rendertarget.h +++ b/src/engine/rendertarget.h @@ -2,390 +2,390 @@ extern int rtsharefb, rtscissor, blurtile; struct rendertarget { - int texw, texh, vieww, viewh; - GLenum colorfmt, depthfmt; - GLuint rendertex, renderfb, renderdb, blurtex, blurfb, blurdb; - int blursize, blurysize; - float blursigma; - float blurweights[MAXBLURRADIUS+1], bluroffsets[MAXBLURRADIUS+1]; - float bluryweights[MAXBLURRADIUS+1], bluryoffsets[MAXBLURRADIUS+1]; - - float scissorx1, scissory1, scissorx2, scissory2; + int texw, texh, vieww, viewh; + GLenum colorfmt, depthfmt; + GLuint rendertex, renderfb, renderdb, blurtex, blurfb, blurdb; + int blursize, blurysize; + 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) - { - } - - virtual ~rendertarget() {} - - virtual GLenum attachment() const - { - return GL_COLOR_ATTACHMENT0; - } - - virtual const GLenum *colorformats() const - { - static const GLenum colorfmts[] = { GL_RGB, GL_RGB8, GL_FALSE }; - return colorfmts; - } - - 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) - { - 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() - { - 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() - { - 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(!blurdb) glGenRenderbuffers_(1, &blurdb); - glGenRenderbuffers_(1, &blurdb); - glBindRenderbuffer_(GL_RENDERBUFFER, blurdb); - glRenderbufferStorage_(GL_RENDERBUFFER, depthfmt, texw, texh); - glFramebufferRenderbuffer_(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, blurdb); - } - glBindFramebuffer_(GL_FRAMEBUFFER, 0); - } - - 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) - { - glDrawBuffer(GL_NONE); - glReadBuffer(GL_NONE); - } - - const GLenum *colorfmts = colorformats(); - int find = 0; - 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(!renderdb) { glGenRenderbuffers_(1, &renderdb); depthfmt = GL_FALSE; } - if(!depthfmt) glBindRenderbuffer_(GL_RENDERBUFFER, renderdb); - const GLenum *depthfmts = depthformats(); - find = 0; - 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; - } - 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) - { - 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< 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<>= 8; x += 8; } - while(!(mask&1)) { mask >>= 1; x++; } - int xstart = x; - do { mask >>= 1; x++; } while(mask&1); - uint strip = (BLURTILEMASK>>(BLURTILES - x)) & (BLURTILEMASK< 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) - { - x = y = 0; - w = vieww; - h = viewh; - return true; - } - return false; - } - x = max(int(floor((scissorx1+1)/2*vieww)) - 2*blursize, 0); - y = max(int(floor((scissory1+1)/2*viewh)) - 2*blursize, 0); - w = min(int(ceil((scissorx2+1)/2*vieww)) + 2*blursize, vieww) - x; - 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) - { - x = y = 0; - w = vieww; - h = viewh; - return true; - } - return false; - } - x = max(int(floor((scissorx1+1)/2*vieww)), 0); - y = max(int(floor((scissory1+1)/2*viewh)), 0); - w = min(int(ceil((scissorx2+1)/2*vieww)), vieww) - x; - 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) - { - w = min(w, hwtexsize); - h = min(h, hwtexsize); - 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(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) - { - swap(rendertex, blurtex); - if(!rtsharefb) - { - swap(renderfb, blurfb); - swap(renderdb, blurdb); - } - } - glBindFramebuffer_(GL_FRAMEBUFFER, renderfb); - 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) - { - glScissor(sx, sy, sw, sh); - glEnable(GL_SCISSOR_TEST); - } - 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) - { - initialized = true; - - if(blursize) doblur(blursize, blursigma, blurysize ? blurysize : blursize); - } - - glBindFramebuffer_(GL_FRAMEBUFFER, 0); - glViewport(0, 0, screenw, screenh); - } + 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) + { + } + + virtual ~rendertarget() {} + + virtual GLenum attachment() const + { + return GL_COLOR_ATTACHMENT0; + } + + virtual const GLenum *colorformats() const + { + static const GLenum colorfmts[] = { GL_RGB, GL_RGB8, GL_FALSE }; + return colorfmts; + } + + 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) + { + 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() + { + 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() + { + 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(!blurdb) glGenRenderbuffers_(1, &blurdb); + glGenRenderbuffers_(1, &blurdb); + glBindRenderbuffer_(GL_RENDERBUFFER, blurdb); + glRenderbufferStorage_(GL_RENDERBUFFER, depthfmt, texw, texh); + glFramebufferRenderbuffer_(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, blurdb); + } + glBindFramebuffer_(GL_FRAMEBUFFER, 0); + } + + 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) + { + glDrawBuffer(GL_NONE); + glReadBuffer(GL_NONE); + } + + const GLenum *colorfmts = colorformats(); + int find = 0; + 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(!renderdb) { glGenRenderbuffers_(1, &renderdb); depthfmt = GL_FALSE; } + if(!depthfmt) glBindRenderbuffer_(GL_RENDERBUFFER, renderdb); + const GLenum *depthfmts = depthformats(); + find = 0; + 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; + } + 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) + { + 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< 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<>= 8; x += 8; } + while(!(mask&1)) { mask >>= 1; x++; } + int xstart = x; + do { mask >>= 1; x++; } while(mask&1); + uint strip = (BLURTILEMASK>>(BLURTILES - x)) & (BLURTILEMASK< 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) + { + x = y = 0; + w = vieww; + h = viewh; + return true; + } + return false; + } + x = max(int(floor((scissorx1+1)/2*vieww)) - 2*blursize, 0); + y = max(int(floor((scissory1+1)/2*viewh)) - 2*blursize, 0); + w = min(int(ceil((scissorx2+1)/2*vieww)) + 2*blursize, vieww) - x; + 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) + { + x = y = 0; + w = vieww; + h = viewh; + return true; + } + return false; + } + x = max(int(floor((scissorx1+1)/2*vieww)), 0); + y = max(int(floor((scissory1+1)/2*viewh)), 0); + w = min(int(ceil((scissorx2+1)/2*vieww)), vieww) - x; + 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) + { + w = min(w, hwtexsize); + h = min(h, hwtexsize); + 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(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) + { + swap(rendertex, blurtex); + if(!rtsharefb) + { + swap(renderfb, blurfb); + swap(renderdb, blurdb); + } + } + glBindFramebuffer_(GL_FRAMEBUFFER, renderfb); + 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) + { + glScissor(sx, sy, sw, sh); + glEnable(GL_SCISSOR_TEST); + } + 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) + { + initialized = true; + + if(blursize) doblur(blursize, blursigma, blurysize ? blurysize : blursize); + } + + glBindFramebuffer_(GL_FRAMEBUFFER, 0); + glViewport(0, 0, screenw, screenh); + } }; -- cgit v1.2.3