From 99399e8944fa74c366f1100d7c833b7499de2d92 Mon Sep 17 00:00:00 2001 From: Ketmar Dark Date: Fri, 29 Apr 2016 22:05:00 +0300 Subject: [PATCH] geometry highlighter now highlights the whole tile --- data/shaders/srlight_blur.frag | 22 ++- data/shaders/srlight_geom.frag | 315 ++++++++++++++++++++++++---------------- data/shaders/srlight_trace.frag | 78 ++++------ glutils.d | 19 ++- render.d | 127 +++++++++------- 5 files changed, 330 insertions(+), 231 deletions(-) rewrite data/shaders/srlight_geom.frag (60%) diff --git a/data/shaders/srlight_blur.frag b/data/shaders/srlight_blur.frag index efa11ca..70fd75d 100644 --- a/data/shaders/srlight_blur.frag +++ b/data/shaders/srlight_blur.frag @@ -17,6 +17,8 @@ */ #version 130 +//#define TWO_TEXTURES + // alpha threshold for our occlusion map #define THRESHOLD (0.75) @@ -52,6 +54,12 @@ void main (void) { if (texelFetch(texOccFull, iocxy, 0).a > THRESHOLD) { // occluder hit, this will take care of lighted walls (we'll fix wall in next pass) color = vec4(0.0, 0.0, 0.0, 0.0); + #ifdef TWO_TEXTURES + gl_FragData[0] = color; + gl_FragData[1] = color; + #else + gl_FragColor = color; + #endif } else { float ltsxi = 1.0/lightTexSize.x; @@ -94,6 +102,12 @@ void main (void) { if (lit == 0.0) { color = vec4(0.0, 0.0, 0.0, 0.0); + #ifdef TWO_TEXTURES + gl_FragData[0] = color; + gl_FragData[1] = color; + #else + gl_FragColor = color; + #endif } else { // has some light here vec4 bcolor = texelFetch(texBg, ibtxy, 0); @@ -104,8 +118,12 @@ void main (void) { color += bcolor*lit; color.a = lit/2.0; } + #ifdef TWO_TEXTURES + gl_FragData[0] = color; + gl_FragData[1] = vec4(1.0, 1.0, 1.0, lit); + #else + gl_FragColor = color; + #endif } } - - gl_FragColor = color; } diff --git a/data/shaders/srlight_geom.frag b/data/shaders/srlight_geom.frag dissimilarity index 60% index dec5b0c..52f30f4 100644 --- a/data/shaders/srlight_geom.frag +++ b/data/shaders/srlight_geom.frag @@ -1,124 +1,191 @@ -/* DooM2D: Midnight on the Firing Line - * coded by Ketmar // Invisible Vector - * Understanding is not required. Only obedience. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -// this shader will light level geometry -#version 130 - -#define PI 3.1415926 - -// alpha threshold for our occlusion map -#define THRESHOLD (0.75) - -#define SEARCH_RADIUS (4) -#define MIN_ALPHA (0.05) - -uniform sampler2D texLMap; // light texture of lightTexSize -uniform sampler2D texBg; // background -uniform sampler2D texOccFull; // occluders -uniform sampler2D texOccSmall; // occluders, small map -uniform vec2 lightTexSize; // x: lightSize; y: size of this texture -uniform vec2 mapPixSize; -uniform vec4 lightColor; -uniform vec2 lightPos; - - -//gl_FragCoord: in background - -void main (void) { - // light is y-mirrored - vec2 ourpos = vec2(gl_FragCoord.x, mapPixSize.y-gl_FragCoord.y); - - vec2 ocxy = ourpos/mapPixSize; - if (texture2D(texOccFull, ocxy).a <= THRESHOLD) { discard; return; } // empty space - - // occluder hit - // first, we should check if there is no other occluders in +x, +y and +x+y direction - vec2 a8 = trunc(ourpos/8); - vec2 ldxy = vec2(sign(lightPos.x-gl_FragCoord.x), sign(gl_FragCoord.y-lightPos.y)); - vec2 s8 = ldxy/(mapPixSize/8); - if (texture2D(texOccSmall, vec2(a8.x+s8.x, a8.y)).a > THRESHOLD && - texture2D(texOccSmall, vec2(a8.x, a8.y+s8.y)).a > THRESHOLD && - texture2D(texOccSmall, a8+s8).a > THRESHOLD) { discard; return; } - - /* - vec4 clr = vec4(0, 0, 0, 1); - if (ldxy.x < 0) clr.r = 0.5; else if (ldxy.x > 0) clr.r = 1; - if (ldxy.y < 0) clr.g = 0.5; else if (ldxy.y > 0) clr.g = 1; - gl_FragColor = clr; - return; - */ - - // ok, it's not blocked - // now move to tile edge, and trace 8px in +dx, +dy, +dx+dy dirs to find some light - vec2 ltpos = gl_TexCoord[0].xy; // in light texture (texLMap) - float pixelStep = 1.0/lightTexSize.y; // in light texture - // left-top tile pixel - vec2 tileopos = trunc(ourpos/8); - tileopos *= 8; - - //ldxy.y = -ldxy.y; - // move to opposide tile side if necessary - if (ldxy.x > 0) tileopos.x += 7; - if (ldxy.y > 0) tileopos.y += 7; - - //vec4 xcolor = texture2D(texBg, vec2(tileopos.x, mapPixSize.y-tileopos.y)/mapPixSize); - //gl_FragColor = vec4(xcolor.r, xcolor.g, xcolor.b, 1); - //return; - - // shift position in light texture to sync it with tileopos - ltpos += vec2((tileopos.x-ourpos.x)*pixelStep, -(tileopos.y-ourpos.y)*pixelStep); - - // trace light - bool lightHit = false; - ldxy *= pixelStep; // so we can use it to step in light texture - for (float count = 8; count > 0; --count) { - if (texture2D(texLMap, ltpos+ldxy).a > MIN_ALPHA || - texture2D(texLMap, vec2(ltpos.x+ldxy.x, ltpos.y)).a > MIN_ALPHA || - texture2D(texLMap, vec2(ltpos.x, ltpos.y+ldxy.y)).a > MIN_ALPHA) - { - lightHit = true; - break; - } - ltpos += ldxy; - } - // no hit -- get out of here - if (!lightHit) { discard; return; } - - //gl_FragColor = vec4(1, 1, 0, 1); - //return; - - vec4 color; - - // background - vec2 btxy = gl_FragCoord.xy/mapPixSize; - vec4 bcolor = texture2D(texBg, btxy); - // light is y-mirrored - //vec2 ourpos = gl_FragCoord.xy; - //ourpos.y = mapPixSize.y-ourpos.y; - // distance from this point to light origin - float lit = clamp(1.0-(distance(ourpos, lightPos)/(lightTexSize.x/2.0)), 0.0, 1.0); - lit = smoothstep(0.1, 1.0, lit); - if (lightColor.a == 0.0) { - color = bcolor*vec4(vec3(1.0), lit); - } else { - color = lightColor*lit; - color += bcolor*lit; - color.a = lit/2.0; - } - - gl_FragColor = color; -} +/* DooM2D: Midnight on the Firing Line + * coded by Ketmar // Invisible Vector + * Understanding is not required. Only obedience. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +// this shader will light level geometry +#version 130 + +#define PI 3.1415926 + +// alpha threshold for our occlusion map +#define THRESHOLD (0.75) + +#define SEARCH_RADIUS (4) +#define MIN_ALPHA (0.04) + +uniform sampler2D texLMap; // light texture of lightTexSize +uniform sampler2D texBg; // background +uniform sampler2D texOccFull; // occluders +uniform sampler2D texOccSmall; // occluders, small map +uniform vec2 lightTexSize; // x: lightSize; y: size of this texture +uniform vec2 mapPixSize; +uniform vec4 lightColor; +uniform vec2 lightPos; + + +bool lightAtTile (vec2 ltpos, float pixelStep) { + if (ltpos.x < 0 || ltpos.y < 0 || ltpos.x >= 1.0 || ltpos.y >= 1.0) return false; + float lx = ltpos.x; + for (int dy = 8; dy > 0; --dy) { + for (int dx = 8; dx > 0; --dx) { + if (texture2D(texLMap, ltpos, 0).a > MIN_ALPHA) return true; + ltpos.x += pixelStep; + } + ltpos = vec2(lx, ltpos.y+pixelStep); + } + return false; +} + + +//gl_FragCoord: in background + +void main (void) { + // light is y-mirrored + vec2 ourpos = vec2(gl_FragCoord.x, mapPixSize.y-gl_FragCoord.y); + + ivec2 ocxy = ivec2(int(ourpos.x), int(ourpos.y)); + // empty space? + if (texelFetch(texOccFull, ocxy, 0).a <= THRESHOLD) { + discard; + //gl_FragColor = vec4(1.0, 0.0, 0.0, 0.5); + return; + } + + // check ajacent tiles + bool hit = false; + /* + for (int dy = -1; dy < 2; ++dy) { + for (int dx = -1; dx < 2; ++dx) { + if (dx != 0.0 || dy != 0.0) { + if (hit = lightAtTile(ivec2(ocxy.x+dx*8, ocxy.y+dy*8), dx, dy)) break; + } + } + } + */ + { + vec2 ltpos = gl_TexCoord[0].xy; // in light texture (texLMap) + float pixelStep = 1.0/lightTexSize.y; // in light texture + int move = ocxy.x&0x07; + ltpos.x -= pixelStep*move; + move = int(gl_FragCoord.y)&0x07; + ltpos.y -= pixelStep*move; + // check ajacent tiles + ltpos -= pixelStep*8; + float savedx = ltpos.x; + for (int dy = -1; dy < 2 && !hit; ++dy) { + for (int dx = -1; dx < 2 && !hit; ++dx) { + if (dx != 0 || dy != 0) hit = lightAtTile(ltpos, pixelStep); + ltpos.x += pixelStep*8; + } + ltpos = vec2(savedx, ltpos.y+pixelStep*8); + } + /* + for (int dy = 8; dy > 0; --dy) { + if (texture2D(texLMap, ltpos, 0).a > MIN_ALPHA) { hit = true; break; } + ltpos.y -= pixelStep; + } + */ + } + + if (hit) { + vec4 color; + // background + //vec2 btxy = gl_FragCoord.xy/mapPixSize; + //vec4 bcolor = texture2D(texBg, btxy); + vec4 bcolor = texelFetch(texBg, ivec2(int(gl_FragCoord.x), int(gl_FragCoord.y)), 0); + // distance from this point to light origin + float lit = clamp(1.0-(distance(ourpos, lightPos)/(lightTexSize.x/2.0)), 0.0, 1.0); + lit = smoothstep(0.1, 1.0, lit); + if (lightColor.a == 0.0) { + color = bcolor*vec4(vec3(1.0), lit); + } else { + color = lightColor*lit; + color += bcolor*lit; + color.a = lit/2.0; + } + gl_FragColor = color; + //gl_FragColor = bcolor; + } else { + discard; + //gl_FragColor = vec4(0.0, 0.0, 1.0, 0.5); + } + +#if 0 + // occluder hit + // first, we should check if there is no other occluders in +x, +y, and +x+y directions + ivec2 a8 = ocxy/8; + //ivec2 ldxy = ivec2(int(sign(lightPos.x-gl_FragCoord.x)), int(sign(gl_FragCoord.y-lightPos.y))); + ivec2 ltposd8 = ivec2(int(lightPos.x), int(lightPos.y))/8; + //ivec2 ltposd8 = ocxy/8; + ivec2 ldxy = ivec2(sign(ltposd8.x-a8.x), sign(ltposd8.y-a8.y)); +#if 0 + if (ldxy.x == 0 && ldxy.y == 0) { discard; return; } + if (ldxy.x != 0 && ldxy.y != 0) { + // both directions + if (/*texelFetch(texOccSmall, ivec2(a8.x+ldxy.x, a8.y), 0).a > THRESHOLD && + texelFetch(texOccSmall, ivec2(a8.x, a8.y+ldxy.y), 0).a > THRESHOLD &&*/ + texelFetch(texOccSmall, a8+ldxy, 0).a > THRESHOLD) { discard; return; } + } else { + // only horizontal or only vertical + if (texelFetch(texOccSmall, a8+ldxy, 0).a > THRESHOLD) { discard; return; } + } +#endif + // ok, it's not blocked + + // check for light in +x, +y, and +x+y directions + vec2 ltpos = gl_TexCoord[0].xy*textureSize(texLMap, 0).y/*lightTexSize.y*/; // in light texture (texLMap) + ivec2 iltpos = ivec2(int(ltpos.x), int(ltpos.y)); + + bool hit = false; + float litlt = 0; + for (int f = 1; f > 0; --f) { + float ar = texelFetch(texLMap, iltpos, 0).a; + ar = max(ar, texelFetch(texLMap, ivec2(iltpos.x+ldxy.x, iltpos.y), 0).a); + ar = max(ar, texelFetch(texLMap, ivec2(iltpos.x, iltpos.y+ldxy.x), 0).a); + ar = max(ar, texelFetch(texLMap, ivec2(iltpos.x+ldxy.x, iltpos.y+ldxy.x), 0).a); + if (ar > MIN_ALPHA) { + hit = true; + ar *= 1.5; + litlt = max(min(ar, 1.0), 0.0); + break; + } + iltpos += ldxy; + } + + if (hit) { + vec4 color; + // background + //vec2 btxy = gl_FragCoord.xy/mapPixSize; + //vec4 bcolor = texture2D(texBg, btxy); + vec4 bcolor = texelFetch(texBg, ivec2(int(gl_FragCoord.x), int(gl_FragCoord.y)), 0); + // distance from this point to light origin + float lit = clamp(1.0-(distance(ourpos, lightPos)/(lightTexSize.x/2.0)), 0.0, 1.0); + lit = smoothstep(0.1, 1.0, lit); + lit = litlt; + if (lightColor.a == 0.0) { + color = bcolor*vec4(vec3(1.0), lit); + } else { + color = lightColor*lit; + color += bcolor*lit; + color.a = lit/2.0; + } + //gl_FragColor = color; + gl_FragColor = bcolor; + } else { + discard; + } +#endif +} diff --git a/data/shaders/srlight_trace.frag b/data/shaders/srlight_trace.frag index 0566239..1495333 100644 --- a/data/shaders/srlight_trace.frag +++ b/data/shaders/srlight_trace.frag @@ -21,6 +21,8 @@ #define INTO_DEPTH (4) +#define BIGSTEP (1) + #define PI (3.14159265) //uniform sampler2D texOcc; @@ -29,7 +31,7 @@ uniform vec2 lightTexSize; uniform sampler2D texOccFull; // occluders map, full uniform sampler2D texOccSmall; // occluders, small map uniform vec2 lightPos; // light coords in occluders map -//uniform vec2 mapPixSize; // size of occluders map +uniform vec2 mapPixSize; // size of occluders map // alpha threshold for our occlusion map #define THRESHOLD (0.75) @@ -72,58 +74,38 @@ void main (void) { step = vec2((b.x-a.x)/len, sign(b.y-a.y)); } - vec2 a8 = trunc(lightPos/8); - vec2 b8 = a8+dir*(lightTexSize.x/8/2); - vec2 step8; - float len8; - if (abs(b8.x-a8.x) > abs(b8.y-a8.y)) { - // horizontal - len8 = abs(b8.x-a8.x); - step8 = vec2(sign(b8.x-a8.x), (b8.y-a8.y)/len8); - } else { - // vertical - len8 = abs(b8.y-a8.y); - step8 = vec2((b8.x-a8.x)/len8, sign(b8.y-a8.y)); - } - - //vec2 sps = mapPixSize/8; - bool detailStep = (texelFetch(texOccSmall, ivec2(int(a8.x), int(a8.y)), 0).a > THRESHOLD); - while (len > 0) { - // big steps - if (!detailStep) { - vec2 nx8 = round(vec2(a8.x+step8.x, a8.y)); - vec2 ny8 = round(vec2(a8.x, a8.y+step8.y)); - a8 += step8; - if (texelFetch(texOccSmall, ivec2(int(a8.x), int(a8.y)), 0).a <= THRESHOLD && - texelFetch(texOccSmall, ivec2(int(nx8.x), int(nx8.y)), 0).a <= THRESHOLD && - texelFetch(texOccSmall, ivec2(int(ny8.x), int(ny8.y)), 0).a <= THRESHOLD) - { - len -= 8; - a += step*8; - } else { - // do 8 small steps - int xlen = (len > 8 ? 8 : int(len)); - while (xlen-- > 0) { - if (texelFetch(texOccFull, ivec2(int(a.x), int(a.y)), 0).a > THRESHOLD) { - #ifdef INTO_DEPTH - for (int stp = INTO_DEPTH; stp > 0; --stp) { - vec2 b = a+step; - if (texelFetch(texOccFull, ivec2(int(b.x), int(b.y)), 0).a <= THRESHOLD) break; - a = b; - } - #endif - dst = distance(lightPos, a)/(lightTexSize.x/2.0); - xlen = -42; - break; + // do big step + vec2 aa = a; + a += step*BIGSTEP; + vec2 ctxa = a/mapPixSize; + vec2 ctxaa = aa/mapPixSize; + if (texture2D(texOccSmall, ctxa, 0).a > THRESHOLD || + texture2D(texOccSmall, ctxaa, 0).a > THRESHOLD || + texture2D(texOccSmall, vec2(ctxaa.x, ctxa.y), 0).a > THRESHOLD || + texture2D(texOccSmall, vec2(ctxa.x, ctxaa.y), 0).a > THRESHOLD) + { + // do small steps + int xlen = (len >= BIGSTEP ? BIGSTEP : int(len)); + while (xlen-- > 0) { + if (texture2D(texOccFull, aa/mapPixSize, 0).a > THRESHOLD) { + #ifdef INTO_DEPTH + for (int stp = INTO_DEPTH; stp > 0; --stp) { + vec2 b = aa+step; + if (texture2D(texOccFull, b/mapPixSize, 0).a <= THRESHOLD) break; + aa = b; } - --len; - a += step; + #endif + dst = distance(lightPos, aa)/(lightTexSize.x/2.0); + //xlen = -42; + len = -42; + break; } - if (xlen <= -42) break; - detailStep = false; // just in case + --xlen; + aa += step; } } + len -= BIGSTEP; } // done diff --git a/glutils.d b/glutils.d index 1e2f5e8..2e461d5 100644 --- a/glutils.d +++ b/glutils.d @@ -129,6 +129,7 @@ public final class Texture : OpenGLObject { UByte, Float, // create floating point texture Depth, // FBO: attach depth buffer + FBO2, // create two FBO attaches } this (string fname, in Option[] opts...) { loadImage(fname, opts); } @@ -319,7 +320,7 @@ public final class FBO : OpenGLObject { int width; int height; GLuint fbo; - Texture tex; + Texture tex, tex1; Texture texdepth; //Texture.Option[] xopts; @@ -335,6 +336,7 @@ public final class FBO : OpenGLObject { ~this () { //FIXME: this may be wrong, as texture may be already destroyed (and it's wrong too); we need refcount for textures glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, 0, 0); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, 0, 0); glDeleteFramebuffersEXT(1, &fbo); fbo = 0; } @@ -343,13 +345,16 @@ public final class FBO : OpenGLObject { if (fbo) { // detach texture glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, 0, 0); - glDeleteFramebuffersEXT(1, &fbo); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, 0, 0); + //glDeleteFramebuffersEXT(1, &fbo); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0); glDeleteFramebuffersEXT(1, &fbo); fbo = 0; } if (tex !is null) tex.clear(); tex = null; + if (tex1 !is null) tex1.clear(); + tex1 = null; if (texdepth !is null) texdepth.clear(); texdepth = null; } @@ -389,6 +394,9 @@ private: void createWithTexture (Texture atex, Texture.Option[] opts...) { assert(atex !is null && atex.tid); + bool need2 = false; + foreach (immutable opt; opts) if (opt == Texture.Option.FBO2) { need2 = true; break; } + tex = atex; glGenFramebuffersEXT(1, &fbo); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); @@ -397,6 +405,12 @@ private: glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tex.tid, 0); // GL_COLOR_ATTACHMENT0_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_STENCIL_ATTACHMENT_EXT + if (need2) { + tex1 = new Texture(tex.width, tex.height, opts); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, tex1.tid, 0); + } + + /+ void createDepth () { uint fboDepthId; glGenRenderbuffersEXT(1, &fboDepthId); @@ -407,6 +421,7 @@ private: // kill it (we don't need it anymore) glDeleteRenderbuffersEXT(1, &fboDepthId); } + +/ /* foreach (Texture.Option opt; opts) { diff --git a/render.d b/render.d index 71970a8..2776bb9 100644 --- a/render.d +++ b/render.d @@ -383,7 +383,7 @@ enum MaxLightRadius = 256; // ////////////////////////////////////////////////////////////////////////// // // for light __gshared FBO[MaxLightRadius+1] fboDistMap; -__gshared FBO fboLSpot, fboLSpotSmall; +__gshared FBO /*fboLSpot,*/ fboLSpotBG, fboLSpotSmall; __gshared Shader shadLightTrace, shadLightBlur, shadLightGeom, shadLightAmbient; __gshared TrueColorImage editorImg; __gshared FBO fboEditor; @@ -445,8 +445,9 @@ public void initOpenGL () { shad["texOccSmall"] = 3; }); - fboLSpot = new FBO(MaxLightRadius*2, MaxLightRadius*2, Texture.Option.Clamp, Texture.Option.Linear); - fboLSpotSmall = new FBO(fboLSpot.width/8, fboLSpot.height/8, Texture.Option.Clamp, Texture.Option.Linear); + fboLSpotBG = new FBO(MaxLightRadius*2, MaxLightRadius*2, Texture.Option.Clamp, Texture.Option.Linear/*, Texture.Option.FBO2*/); + //fboLSpotBG = new FBO(fboLSpot.width, fboLSpot.height, Texture.Option.Clamp, Texture.Option.Linear); + fboLSpotSmall = new FBO(fboLSpotBG.width/8, fboLSpotBG.height/8, Texture.Option.Clamp, Texture.Option.Nearest/*Linear*/); //TODO: this sux! foreach (int sz; 2..MaxLightRadius+1) { fboDistMap[sz] = new FBO(sz*2, 1, Texture.Option.Clamp, Texture.Option.Linear); // create 1d distance map FBO @@ -583,6 +584,7 @@ void loadMap (string mapname) { fboLMaskSmall = new FBO(map.width, map.height, Texture.Option.Nearest); // small lightmask //shadLightTrace.exec((Shader shad) { shad["mapPixSize"] = SVec2F(map.width*TileSize-1, map.height*TileSize-1); }); + shadLightTrace.exec((Shader shad) { shad["mapPixSize"] = SVec2F(map.width*TileSize, map.height*TileSize); }); shadLightBlur.exec((Shader shad) { shad["mapPixSize"] = SVec2F(map.width*TileSize, map.height*TileSize); }); shadLightGeom.exec((Shader shad) { shad["mapPixSize"] = SVec2F(map.width*TileSize, map.height*TileSize); }); shadLightAmbient.exec((Shader shad) { shad["mapPixSize"] = SVec2F(map.width*TileSize, map.height*TileSize); }); @@ -842,17 +844,17 @@ void renderLight() (int lightX, int lightY, in auto ref SVec4F lcol, int lightRa }); // build light texture for blending - fboLSpot.exec({ + fboLSpotBG.exec({ // no need to clear it, shader will take care of that // debug // need to clear it, for "small" - //glClearColor(0.0f, 0.0f, 1.0f, 1.0f); - //glClear(GL_COLOR_BUFFER_BIT); + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT); shadLightBlur.exec((Shader shad) { shad["lightTexSize"] = SVec2F(lightSize, MaxLightRadius*2); // x: size of distmap; y: size of this texture shad["lightColor"] = SVec4F(lcol.x, lcol.y, lcol.z, lcol.w); shad["lightPos"] = SVec2F(lightX-lightRadius, lightY-lightRadius); - orthoCamera(fboLSpot.tex.width, fboLSpot.tex.height); + orthoCamera(fboLSpotBG.tex.width, fboLSpotBG.tex.height); //drawAtXY(fboDistMap[lightRadius].tex.tid, 0, 0, lightSize, lightSize); bindTexture(fboDistMap.ptr[lightRadius].tex.tid); glBegin(GL_QUADS); @@ -866,45 +868,37 @@ void renderLight() (int lightX, int lightY, in auto ref SVec4F lcol, int lightRa // build "small" light texture for geometry-light shader //glUseProgram(0); - version(none) fboLSpotSmall.exec({ - glClearColor(0.0f, 1.0f, 0.0f, 1.0f); + /*version(none)*/ fboLSpotSmall.exec({ + glDisable(GL_BLEND); + //glClearColor(0.0f, 1.0f, 0.0f, 1.0f); + glClearColor(0.0f, 0.0f, 0.0f, 0.1f); glClear(GL_COLOR_BUFFER_BIT); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - //orthoCamera(fboLSpotSmall.tex.width, fboLSpotSmall.tex.height); - //orthoCamera(fboLSpot.width, fboLSpot.height); - orthoCamera(lightSize, lightSize); - //orthoCamera(fboLevelLight.tex.width, fboLevelLight.tex.height); - bindTexture(fboLSpot.tex.tid); + //orthoCamera(fboLSpotSmall.width, fboLSpotSmall.height); + //conwriteln(fboLSpotSmall.width, "x", fboLSpotSmall.height, "; ", fboLSpotBG.width, "x", fboLSpotBG.height); + //orthoCamera(fboLSpotBG.width, fboLSpotBG.height); + orthoCamera(fboLSpotSmall.width, fboLSpotSmall.height); + bindTexture(fboLSpotBG.tex.tid); float occe = 1.0f*lightSize/(MaxLightRadius*2); float occs = 1.0f-occe; + int w = fboLSpotSmall.width; + int h = fboLSpotSmall.height; + int h0 = fboLSpotSmall.height; + int h1 = fboLSpotSmall.height-h; + occe = 1.0f; + occs = 0.0f; + float occt = 1.0f; glBegin(GL_QUADS); - /* - glTexCoord2f(0.0f, 0.0f); glVertex2i(0, 0); // top-left - glTexCoord2f(1.0f, 0.0f); glVertex2i(fboLSpotSmall.tex.width, 0); // top-right - glTexCoord2f(1.0f, 1.0f); glVertex2i(fboLSpotSmall.tex.width, fboLSpotSmall.tex.height); // bottom-right - glTexCoord2f(0.0f, 1.0f); glVertex2i(0, fboLSpotSmall.tex.height); // bottom-left - */ - /* - glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0f, 0.0f); // top-left - glTexCoord2f(1.0f, 0.0f); glVertex2f(1.0f, 0.0f); // top-right - glTexCoord2f(1.0f, 1.0f); glVertex2f(1.0f, 1.0f); // bottom-right - glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0f, 1.0f); // bottom-left - */ - /* - glTexCoord2f(0.0f, occs); glVertex2i(0, 0); // top-left - glTexCoord2f(occe, occs); glVertex2i(lightSize, 0); // top-right - glTexCoord2f(occe, 1.0f); glVertex2i(lightSize, lightSize); // bottom-right - glTexCoord2f(0.0f, 1.0f); glVertex2i(0, lightSize); // bottom-left - */ - glTexCoord2f(0.0f, 0.0f); glVertex2i(0, 0); // top-left - glTexCoord2f(occe, 0.0f); glVertex2i(lightSize, 0); // top-right - glTexCoord2f(occe, 1.0f); glVertex2i(lightSize, lightSize); // bottom-right - glTexCoord2f(0.0f, 1.0f); glVertex2i(0, lightSize); // bottom-left + glTexCoord2f(0.0f, occt); glVertex2i(0, h0); // top-left + glTexCoord2f(occe, occt); glVertex2i(w, h0); // top-right + glTexCoord2f(occe, occs); glVertex2i(w, h1); // bottom-right + glTexCoord2f(0.0f, occs); glVertex2i(0, h1); // bottom-left glEnd(); /* bindTexture(0); glColor4f(1.0f, 0.0f, 0.0f, 0.5f); - glRectf(0, 0, fboLSpotSmall.tex.width, fboLSpotSmall.tex.height); + //glRectf(0, 0, lightSize, lightSize); + glRectf(0, fboLSpotSmall.height-8, 8, fboLSpotSmall.height); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); */ }); @@ -920,25 +914,32 @@ void renderLight() (int lightX, int lightY, in auto ref SVec4F lcol, int lightRa int y0 = lightY+lightRadius-1+1; float occe = 1.0f*lightSize/(MaxLightRadius*2); float occs = 1.0f-occe; - /*version(none)*/ { - bindTexture(fboLSpot.tex.tid); - glBegin(GL_QUADS); - glTexCoord2f(0.0f, occs); glVertex2i(x0, y0); // top-left - glTexCoord2f(occe, occs); glVertex2i(x1, y0); // top-right - glTexCoord2f(occe, 1.0f); glVertex2i(x1, y1); // bottom-right - glTexCoord2f(0.0f, 1.0f); glVertex2i(x0, y1); // bottom-left - glEnd(); - }/* else { - glDisable(GL_BLEND); + version(smspot) { + //glDisable(GL_BLEND); float occn = 1.0f*lightSize/(MaxLightRadius*2); + float occt = 1.0f-occn; bindTexture(fboLSpotSmall.tex.tid); glBegin(GL_QUADS); + /* + glTexCoord2f(0.0f, 0.0f); glVertex2i(x0, y0); // top-left + glTexCoord2f(occn, 0.0f); glVertex2i(x1, y0); // top-right + glTexCoord2f(occn, occn); glVertex2i(x1, y1); // bottom-right + glTexCoord2f(0.0f, occn); glVertex2i(x0, y1); // bottom-left + */ glTexCoord2f(0.0f, occn); glVertex2i(x0, y0); // top-left glTexCoord2f(occn, occn); glVertex2i(x1, y0); // top-right glTexCoord2f(occn, 0.0f); glVertex2i(x1, y1); // bottom-right glTexCoord2f(0.0f, 0.0f); glVertex2i(x0, y1); // bottom-left glEnd(); - }*/ + } else { + bindTexture(fboLSpotBG.tex.tid); + glBegin(GL_QUADS); + glTexCoord2f(0.0f, occs); glVertex2i(x0, y0); // top-left + glTexCoord2f(occe, occs); glVertex2i(x1, y0); // top-right + glTexCoord2f(occe, 1.0f); glVertex2i(x1, y1); // bottom-right + glTexCoord2f(0.0f, 1.0f); glVertex2i(x0, y1); // bottom-left + glEnd(); + } /* bindTexture(0); glRectf(x0, y0, x1, y1); @@ -946,18 +947,34 @@ void renderLight() (int lightX, int lightY, in auto ref SVec4F lcol, int lightRa // and blend it again, with the shader that will touch only occluders shadLightGeom.exec((Shader shad) { //shad["lightTexSize"] = SVec2F(lightSize, lightSize); - shad["lightTexSize"] = SVec2F(lightSize, fboLSpot.tex.height); + version(smspot) { + shad["lightTexSize"] = SVec2F(lightSize, fboLSpotSmall.height); + } else { + shad["lightTexSize"] = SVec2F(lightSize, fboLSpotBG.tex.height); + } shad["lightColor"] = SVec4F(lcol.x, lcol.y, lcol.z, lcol.w); shad["lightPos"] = SVec2F(lightX, lightY); //shad["lightPos"] = SVec2F(lightX-lightRadius, lightY-lightRadius); - bindTexture(fboLSpot.tex.tid); + version(smspot) { + bindTexture(fboLSpotSmall.tex.tid); + } else { + bindTexture(fboLSpotBG.tex.tid); + } + float occn = 1.0f*lightSize/(MaxLightRadius*2); glBegin(GL_QUADS); - glTexCoord2f(0.0f, occs); glVertex2i(x0, y0); // top-left - glTexCoord2f(occe, occs); glVertex2i(x1, y0); // top-right - glTexCoord2f(occe, 1.0f); glVertex2i(x1, y1); // bottom-right - glTexCoord2f(0.0f, 1.0f); glVertex2i(x0, y1); // bottom-left + version(smspot) { + glTexCoord2f(0.0f, occn); glVertex2i(x0, y0); // top-left + glTexCoord2f(occn, occn); glVertex2i(x1, y0); // top-right + glTexCoord2f(occn, 0.0f); glVertex2i(x1, y1); // bottom-right + glTexCoord2f(0.0f, 0.0f); glVertex2i(x0, y1); // bottom-left + } else { + glTexCoord2f(0.0f, occs); glVertex2i(x0, y0); // top-left + glTexCoord2f(occe, occs); glVertex2i(x1, y0); // top-right + glTexCoord2f(occe, 1.0f); glVertex2i(x1, y1); // bottom-right + glTexCoord2f(0.0f, 1.0f); glVertex2i(x0, y1); // bottom-left + } glEnd(); - //drawAtXY(fboLSpot.tex.tid, lightX-lightRadius, lightY-lightRadius, lightSize, lightSize, mirrorY:true); + //drawAtXY(fboLSpotBG.tex.tid, lightX-lightRadius, lightY-lightRadius, lightSize, lightSize, mirrorY:true); }); }); } -- 2.11.4.GIT