From 0d915f71780e17260351616c516ea66f31f61d67 Mon Sep 17 00:00:00 2001 From: Thomas Friedel Date: Wed, 12 Feb 2020 17:38:33 +0100 Subject: [PATCH] fixed and improved shadows --- backend/goglbackend/fill.go | 35 +++++++++++++++++++-------------- backend/goglbackend/gogl.go | 30 +++++++++------------------- backend/goglbackend/shaders.go | 16 ++++++++------- testdata/Shadow.png | Bin 2013 -> 2122 bytes 4 files changed, 38 insertions(+), 43 deletions(-) diff --git a/backend/goglbackend/fill.go b/backend/goglbackend/fill.go index f9b6b08..39d67c2 100644 --- a/backend/goglbackend/fill.go +++ b/backend/goglbackend/fill.go @@ -245,6 +245,10 @@ func (b *GoGLBackend) drawBlurred(size float64, min, max vec) { min[1] -= fsize * 3 max[0] += fsize * 3 max[1] += fsize * 3 + min[0] = math.Max(0.0, math.Min(b.fw, min[0])) + min[1] = math.Max(0.0, math.Min(b.fh, min[1])) + max[0] = math.Max(0.0, math.Min(b.fw, max[0])) + max[1] = math.Max(0.0, math.Min(b.fh, max[1])) gl.BindBuffer(gl.ARRAY_BUFFER, b.shadowBuf) data := [16]float32{ @@ -276,27 +280,27 @@ func (b *GoGLBackend) drawBlurred(size float64, min, max vec) { gl.ClearColor(0, 0, 0, 0) - gl.BindTexture(gl.TEXTURE_2D, b.offscr1.tex) b.enableTextureRenderTarget(&b.offscr2) - gl.Clear(gl.COLOR_BUFFER_BIT) - b.box3(sizea, false) - gl.BindTexture(gl.TEXTURE_2D, b.offscr2.tex) + gl.BindTexture(gl.TEXTURE_2D, b.offscr1.tex) + gl.Clear(gl.COLOR_BUFFER_BIT | gl.STENCIL_BUFFER_BIT) + b.box3(sizea, 0, false) b.enableTextureRenderTarget(&b.offscr1) - b.box3(sizeb, false) - gl.BindTexture(gl.TEXTURE_2D, b.offscr1.tex) - b.enableTextureRenderTarget(&b.offscr2) - b.box3(sizec, false) gl.BindTexture(gl.TEXTURE_2D, b.offscr2.tex) - b.enableTextureRenderTarget(&b.offscr1) - b.box3(sizea, true) - gl.BindTexture(gl.TEXTURE_2D, b.offscr1.tex) + b.box3(sizeb, -0.5, false) b.enableTextureRenderTarget(&b.offscr2) - b.box3(sizeb, true) + gl.BindTexture(gl.TEXTURE_2D, b.offscr1.tex) + b.box3(sizec, 0, false) + b.enableTextureRenderTarget(&b.offscr1) + gl.BindTexture(gl.TEXTURE_2D, b.offscr2.tex) + b.box3(sizea, 0, true) + b.enableTextureRenderTarget(&b.offscr2) + gl.BindTexture(gl.TEXTURE_2D, b.offscr1.tex) + b.box3(sizeb, -0.5, true) gl.Enable(gl.BLEND) gl.BlendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) - gl.BindTexture(gl.TEXTURE_2D, b.offscr2.tex) b.disableTextureRenderTarget() - b.box3(sizec, true) + gl.BindTexture(gl.TEXTURE_2D, b.offscr2.tex) + b.box3(sizec, 0, true) gl.DisableVertexAttribArray(b.shd.Vertex) gl.DisableVertexAttribArray(b.shd.TexCoord) @@ -304,7 +308,7 @@ func (b *GoGLBackend) drawBlurred(size float64, min, max vec) { gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) } -func (b *GoGLBackend) box3(size int, vertical bool) { +func (b *GoGLBackend) box3(size int, offset float32, vertical bool) { gl.Uniform1i(b.shd.BoxSize, int32(size)) if vertical { gl.Uniform1i(b.shd.BoxVertical, 1) @@ -313,5 +317,6 @@ func (b *GoGLBackend) box3(size int, vertical bool) { gl.Uniform1i(b.shd.BoxVertical, 0) gl.Uniform1f(b.shd.BoxScale, 1/float32(b.fw)) } + gl.Uniform1f(b.shd.BoxOffset, offset) gl.DrawArrays(gl.TRIANGLE_FAN, 0, 4) } diff --git a/backend/goglbackend/gogl.go b/backend/goglbackend/gogl.go index f85f695..e9c4896 100644 --- a/backend/goglbackend/gogl.go +++ b/backend/goglbackend/gogl.go @@ -139,6 +139,7 @@ func New(x, y, w, h int, ctx *GLContext) (*GoGLBackend, error) { } b.disableTextureRenderTarget = func() { gl.BindFramebuffer(gl.FRAMEBUFFER, 0) + gl.Viewport(int32(b.x), int32(b.y), int32(b.w), int32(b.h)) } return b, nil @@ -288,28 +289,29 @@ func colorGoToGL(c color.RGBA) glColor { } func (b *GoGLBackend) useShader(style *backendbase.FillStyle, useAlpha bool, alphaTexSlot int32) (vertexLoc, alphaTexCoordLoc uint32) { - var alphaVal int32 + gl.UseProgram(b.shd.ID) + gl.Uniform2f(b.shd.CanvasSize, float32(b.fw), float32(b.fh)) if useAlpha { - alphaVal = 1 + gl.Uniform1i(b.shd.UseAlphaTex, 1) + gl.Uniform1i(b.shd.AlphaTex, alphaTexSlot) + } else { + gl.Uniform1i(b.shd.UseAlphaTex, 0) } + gl.Uniform1f(b.shd.GlobalAlpha, float32(style.Color.A)/255) + if lg := style.LinearGradient; lg != nil { lg := lg.(*LinearGradient) gl.ActiveTexture(gl.TEXTURE0) gl.BindTexture(gl.TEXTURE_2D, lg.tex) - gl.UseProgram(b.shd.ID) from := vec{style.Gradient.X0, style.Gradient.Y0} to := vec{style.Gradient.X1, style.Gradient.Y1} dir := to.sub(from) length := dir.len() dir = dir.scale(1 / length) - gl.Uniform2f(b.shd.CanvasSize, float32(b.fw), float32(b.fh)) gl.Uniform2f(b.shd.From, float32(from[0]), float32(from[1])) gl.Uniform2f(b.shd.Dir, float32(dir[0]), float32(dir[1])) gl.Uniform1f(b.shd.Len, float32(length)) gl.Uniform1i(b.shd.Gradient, 0) - gl.Uniform1f(b.shd.GlobalAlpha, float32(style.Color.A)/255) - gl.Uniform1i(b.shd.AlphaTex, alphaTexSlot) - gl.Uniform1i(b.shd.UseAlphaTex, alphaVal) gl.Uniform1i(b.shd.Func, shdFuncLinearGradient) return b.shd.Vertex, b.shd.TexCoord } @@ -317,28 +319,21 @@ func (b *GoGLBackend) useShader(style *backendbase.FillStyle, useAlpha bool, alp rg := rg.(*RadialGradient) gl.ActiveTexture(gl.TEXTURE0) gl.BindTexture(gl.TEXTURE_2D, rg.tex) - gl.UseProgram(b.shd.ID) from := vec{style.Gradient.X0, style.Gradient.Y0} to := vec{style.Gradient.X1, style.Gradient.Y1} - gl.Uniform2f(b.shd.CanvasSize, float32(b.fw), float32(b.fh)) gl.Uniform2f(b.shd.From, float32(from[0]), float32(from[1])) gl.Uniform2f(b.shd.To, float32(to[0]), float32(to[1])) gl.Uniform1f(b.shd.RadFrom, float32(style.Gradient.RadFrom)) gl.Uniform1f(b.shd.RadTo, float32(style.Gradient.RadTo)) gl.Uniform1i(b.shd.Gradient, 0) - gl.Uniform1f(b.shd.GlobalAlpha, float32(style.Color.A)/255) - gl.Uniform1i(b.shd.AlphaTex, alphaTexSlot) - gl.Uniform1i(b.shd.UseAlphaTex, alphaVal) gl.Uniform1i(b.shd.Func, shdFuncRadialGradient) return b.shd.Vertex, b.shd.TexCoord } if ip := style.ImagePattern; ip != nil { ipd := ip.(*ImagePattern).data img := ipd.Image.(*Image) - gl.UseProgram(b.shd.ID) gl.ActiveTexture(gl.TEXTURE0) gl.BindTexture(gl.TEXTURE_2D, img.tex) - gl.Uniform2f(b.shd.CanvasSize, float32(b.fw), float32(b.fh)) gl.Uniform2f(b.shd.ImageSize, float32(img.w), float32(img.h)) gl.Uniform1i(b.shd.Image, 0) var f32mat [9]float32 @@ -356,20 +351,13 @@ func (b *GoGLBackend) useShader(style *backendbase.FillStyle, useAlpha bool, alp case backendbase.NoRepeat: gl.Uniform2f(b.shd.Repeat, 0, 0) } - gl.Uniform1f(b.shd.GlobalAlpha, float32(style.Color.A)/255) - gl.Uniform1i(b.shd.AlphaTex, alphaTexSlot) - gl.Uniform1i(b.shd.UseAlphaTex, alphaVal) gl.Uniform1i(b.shd.Func, shdFuncImagePattern) return b.shd.Vertex, b.shd.TexCoord } - gl.UseProgram(b.shd.ID) - gl.Uniform2f(b.shd.CanvasSize, float32(b.fw), float32(b.fh)) c := colorGoToGL(style.Color) gl.Uniform4f(b.shd.Color, float32(c.r), float32(c.g), float32(c.b), float32(c.a)) gl.Uniform1f(b.shd.GlobalAlpha, 1) - gl.Uniform1i(b.shd.AlphaTex, alphaTexSlot) - gl.Uniform1i(b.shd.UseAlphaTex, alphaVal) gl.Uniform1i(b.shd.Func, shdFuncSolid) return b.shd.Vertex, b.shd.TexCoord } diff --git a/backend/goglbackend/shaders.go b/backend/goglbackend/shaders.go index fa6b183..ae29d70 100755 --- a/backend/goglbackend/shaders.go +++ b/backend/goglbackend/shaders.go @@ -41,6 +41,7 @@ uniform sampler2D alphaTex; uniform int boxSize; uniform bool boxVertical; uniform float boxScale; +uniform float boxOffset; bool isNaN(float v) { return v < 0.0 || 0.0 < v || v == 0.0 ? false : true; @@ -52,17 +53,17 @@ void main() { if (func == 5) { vec4 sum = vec4(0.0); if (boxVertical) { - vec2 start = v_tc - vec2(0.0, (float)(boxSize) * boxScale); - for (int i=0; i=km5WLz^Ik8FvbNTHhm!A}Vk<)u{k7m5W@5()g+-2?~_5>aO>!U|A?6`%+!KoM4e zBCG&KSOJQ#0u*5dD8dR*GX3@MA61S8^^dC^Ia*eLBCG(NaDT%!NI-B#kL>Sg`ugkc zVNUG#wQ5+5L)(mK1G*fR%WG(Rt|??Ih4sg8h6Q0_N=;@0(>Y4MBo2y(=0xXeGNb>U zeb%eWCuO(7G7`f5YDfzI?CtxP%WbgnF;%E|%im7(S|hABDP~k>+{ccs`5LNHy-!1L zvE@vKszOzwtbb4m2>v+DYmKnbCM6(wE9;EUOZ4ls88}|OPebpp^GOvbN|c-cI9`LL zS{*D~|ArJXGFu7dkU974AK_u(sP#S#{e&kbRiG$PG zwk$TN1j!Lc{)&T_i}Zt99jtcCfGx`aB2r0WdD%b~?1pSv8L|wS^F9~6Tui(T%MxB= z%KD&myc9OpzMLlpSQf{u0>#E0NAVtxT;%2^AhL1YOw6*#gySV^Pi#4(e_Ql5b~j`+ zJM41g?0>=>yfS2oIjoZ7*2-EVEa5ey{K#bk7Q3Vz^Te@s7Q@EhXyQ9kAhqxSzo{}iVC-(PVklzXEwB-e>Tu?xN_N| z&Q*jJpa?5K5mtaAtN_jE8(#bVWABGp-Tg3HR)8X`07X~AH{Jop|=gABKcd5DIdG(oYI9p$U?btgk>3?|1oa5e^9te%LfFy0J@OanN1T1m0mbLXr zRTTbs%l0K_Q@cycdL%lU0F^-Dk#ex+=w!^gMLk-ZDkw=Hr~S?=7lw7Id;h80d8Be% z3+**WX0+FE-n>v!x3dyU%Eu(G6tiyE4OxoX5Nu+J4PN4s0e`gn ze(Jy@kBJ9pzFD1wb<>u`lI=bwD_YjDw-ordz+5>hw@YCKO>wit8a|*F?ST!Td$yKbWUO#9L)w_YkZ;f;ENu7gi zrLg|~C6P$B`1F9sM?CHD`O&1OM}ItRvD;vq)Gtd9w8;OB-@H#L@CQDO0`m0&e7N+s8(fZDp?fv4d)6Kzc$$UZ{GUk9{v>-vI==gixlL@c@Ydo z)-kcMQmqk|S7`Q{l9ItxAQMCr+N41=0$sMp`1vk)}v9i+{{Fv1wjw zgykX#lVWSi4JJkF3qYePjeRL^DU3$%O|~RVM@okZ2aWd}-Wyau&8 zSZ*B{x3&&>U!I$43jslU^7d*4E&Xh=doTUe*lWC%*q3}G`^R3sqmJYbW9DeLyFW<%S})lHL+>S((M5_eo)IH;6V1y z&m_wQVY#lHHbx{RQ~{NmgKsLx0?7tad8CF;$*%WGu$rXtN@>r=m46!_Jm$z!q<*BI zDA_q~sO>!^_b}~=l%Sp4)0a6wyrP`c5S8Jja+8-Dsw8lUA!tlbbYGd*wx}5ua!-uD zQF;M>=sNwZ@Lu6q7)Dt>6tiXo_|7<`Bekay0k)}}oa13Z%i`q_?V!6X>1mXPWN@k> z<=&dt-d|l&kK~50M1ShpA!EzZ23AVV2y^T3+g#Hz>!f8lv*OG3X5$9mmEY~h1ud&K zE|6tWo=LG+N@*GOqPx4gd|lru*8d<(-zgch(&l1kn%Z1^tL?Yx$BK0_X7$ZV(N_h1 zd?d39);S{|wj?{MhA{PFmiBH$%&TraXp=us$#ZRfQ0aC<^uiXr zZ&~hTEf+x@sbzhzIXCn2z`+kvL(6>V-tFi}MRh6FrtsVW(%M^bvy&OrnK8?;U@J>) zyCGS$(J*lC&VQ1T?HPQ7Cv_Lt*;n1&p-gR4cIL>yYPb`cz8k{M1S`FAT&EE)>TN o0~BEeD8dR*gcYFw2LJ&7|J@5vL0IpPMgRZ+07*qoM6N<$g678$UjP6A delta 2000 zcmZ9Lc{~#g1IK00Tq7k$yq;WJ*rt|aNS>TES##UUHQGM8KaNSRVXmx+IeHuwo{725 zXA`1wWtrr0lvZ-ATt&kZA>RIbdf(r_-_P&&`|JDS$b0!*ZHgolZENKgTlTrkIcJ4? zI782@_~zM_4q7`%cgKZ)Rr%Gh;v%@CtP(N6l_{MJ&n^fFE*aBJPEtvk(=FLnV^kJq z-S04{>#cRlbgwvEXRYp$9yYQs=9{OzRZ}6JUh-sDD^8=FarqhN@X#6a@|drGAClU2 zVMTQ|j~C7dE>ZT#df?bA=JLj>tvcdiFdVnn4k)wufTK|sEp*E~hWo?!Kv7=77kwmj zBi8!M^LNeb>~^`J6l>nG(G;vn5T0SzH|u4gW4voZTaaj+4Hpx(^5Wi&-|-M z>>~u-SX+R)8@!WdRS+d|EuS55G;E!zerH9PJ9;Gr!Vd~O_~x2*b65zzqY>yEXli3C zu-_SzH3(f6JV$*JcQF+k&(BQc@miE{@Z&ub#j(wJbkJoC4e;ZG>>kKq_ue$5{1!Ax z*mj9>HGeJKfTV|a{N$YZeS*lo8%>q(9xd$?@(fwGpsO;jsh+EU?J2)bbdQu^Mz3xl zE8|ba@>K3zh({AJCz(Wyk?81!sLGA|>6#-!$fw#>)>oGM-nEJQ^F*r>qZnY{EOg#b6IDn7wu4QKz>M8-oP8feEa0r zCNB(=b>`0JcUEC@zh88~P0qLuS-X^^LlD7CXAE@l^k@NH6gr&2vYDmUE*c<$ze1-o z4RPU{P#Yz+9KNP$xYOjYky>iM%OOj;$fvjvOAj8_XCs4ii~33FhxymbQ#5zZQ8bn< z9-85tcRt|bPPg@F&imT5UuU&IgT@27~HR^3hJfWj7aE9PU$4O)0Twh?}KN%M%_6K59mlVT$6 z_RwZ#>%sfyj?g!eecuq4F8~XP7C8-TnsLaXxJL7O88S|3xmkal;Jye#FZG@*>q)qH zK(aIf4c&2StEc>nYkqb3*WOR?Y6E57{$)!;kbUTs_MSfYm_*ceG{*{Iy0`z{GN|pB zlmB1g>;-Ud&tY4vkBs;W`VC%!p{COgNus7FX~gv0y=@8>Hocha{V=T;nMa$s!mU@& z+n#k##`h1&_%EQ^ZHCMZu;m?7@|y}pz%ePpjSe|iiTy37)cV@iyYRpg|$yjm&a^*D_G8Dk!kmnJ%9l3&3 zAd-EZV!SQCHrdC__@TA%2*w|Nn3H!c9xl-yl8{#r{ZexVo|vj6e!zDaX4Pnl!=v`%2T)XO zrAqT1X{p@VOgUg#YplsKmrU2gW+qOFrhUnRLtyY-e(_gFMU~^tHp@;k(z-(P!XL~<0FOB zth!+BTUJeH9a1%X103*aahyB-B`uXY07&;xei^cwiFT_4x^A-#=jWt=G5nA z#9?Y{-ijoAI+r7zs@=!~8V&pmxKhO>An