From bed6cdc50a938fba8ed6f2024c2305302ca26835 Mon Sep 17 00:00:00 2001 From: Thomas Friedel Date: Thu, 8 Feb 2018 16:03:35 +0100 Subject: [PATCH] radial gradient works now --- canvas.go | 30 +++++-- made_shaders.go | 204 +++++++++++++++++++++++++----------------------- 2 files changed, 129 insertions(+), 105 deletions(-) diff --git a/canvas.go b/canvas.go index 0bc42e0..798a088 100644 --- a/canvas.go +++ b/canvas.go @@ -261,14 +261,29 @@ precision mediump float; #endif varying vec2 v_cp; uniform sampler1D gradient; -uniform vec2 from, dir; +uniform vec2 from, to, dir; +uniform float radFrom, radTo; uniform float len; +bool isNaN(float v) { + return v < 0.0 || 0.0 < v || v == 0.0 ? false : true; +} void main() { - vec2 v0 = v_cp - from; - //vec2 v1 = v_cp - (from + dir); - float r = length(v0) / len; - r = clamp(r, 0.0, 1.0); - gl_FragColor = texture1D(gradient, r); + float o_a = 0.5 * sqrt( + pow(-2.0*from.x*from.x+2.0*from.x*to.x+2.0*from.x*v_cp.x-2.0*to.x*v_cp.x-2.0*from.y*from.y+2.0*from.y*to.y+2.0*from.y*v_cp.y-2.0*to.y*v_cp.y+2.0*radFrom*radFrom-2.0*radFrom*radTo, 2.0) + -4.0*(from.x*from.x-2.0*from.x*v_cp.x+v_cp.x*v_cp.x+from.y*from.y-2.0*from.y*v_cp.y+v_cp.y*v_cp.y-radFrom*radFrom) + *(from.x*from.x-2.0*from.x*to.x+to.x*to.x+from.y*from.y-2.0*from.y*to.y+to.y*to.y-radFrom*radFrom+2.0*radFrom*radTo-radTo*radTo) + ); + float o_b = (from.x*from.x-from.x*to.x-from.x*v_cp.x+to.x*v_cp.x+from.y*from.y-from.y*to.y-from.y*v_cp.y+to.y*v_cp.y-radFrom*radFrom+radFrom*radTo); + float o_c = (from.x*from.x-2.0*from.x*to.x+to.x*to.x+from.y*from.y-2.0*from.y*to.y+to.y*to.y-radFrom*radFrom+2.0*radFrom*radTo-radTo*radTo); + float o1 = (-o_a + o_b) / o_c; + float o2 = (o_a + o_b) / o_c; + if (isNaN(o1) && isNaN(o2)) { + gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0); + return; + } + float o = max(o1, o2); + float r = radFrom + o * (radTo - radFrom); + gl_FragColor = texture1D(gradient, o); }` func glError() error { @@ -434,7 +449,10 @@ func (cv *Canvas) FillRect(x, y, w, h float32) { length := dir.Len() dir = dir.DivF(length) gli.Uniform2f(rgr.from, from[0], from[1]) + gli.Uniform2f(rgr.to, to[0], to[1]) gli.Uniform2f(rgr.dir, dir[0], dir[1]) + gli.Uniform1f(rgr.radFrom, rg.radFrom) + gli.Uniform1f(rgr.radTo, rg.radTo) gli.Uniform1f(rgr.len, length) gli.Uniform1i(rgr.gradient, 0) gli.EnableVertexAttribArray(rgr.vertex) diff --git a/made_shaders.go b/made_shaders.go index f714a90..bdc490b 100755 --- a/made_shaders.go +++ b/made_shaders.go @@ -6,105 +6,6 @@ import ( "strings" ) -type solidShader struct { - id uint32 - vertex uint32 - canvasSize int32 - color int32 -} - -func loadSolidShader() (*solidShader, error) { - var vs, fs, program uint32 - - { - csource, freeFunc := gli.Strs(solidVS + "\x00") - defer freeFunc() - - vs = gli.CreateShader(gl_VERTEX_SHADER) - gli.ShaderSource(vs, 1, csource, nil) - gli.CompileShader(vs) - - var logLength int32 - gli.GetShaderiv(vs, gl_INFO_LOG_LENGTH, &logLength) - if logLength > 0 { - shLog := strings.Repeat("\x00", int(logLength+1)) - gli.GetShaderInfoLog(vs, logLength, nil, gli.Str(shLog)) - fmt.Printf("VERTEX_SHADER compilation log:\n\n%s\n", shLog) - } - - var status int32 - gli.GetShaderiv(vs, gl_COMPILE_STATUS, &status) - if status != gl_TRUE { - gli.DeleteShader(vs) - return nil, errors.New("Error compiling GL_VERTEX_SHADER shader part") - } - if glErr := gli.GetError(); glErr != gl_NO_ERROR { - return nil, errors.New("error compiling shader part, glError: " + fmt.Sprint(glErr)) - } - } - - { - csource, freeFunc := gli.Strs(solidFS + "\x00") - defer freeFunc() - - fs = gli.CreateShader(gl_FRAGMENT_SHADER) - gli.ShaderSource(fs, 1, csource, nil) - gli.CompileShader(fs) - - var logLength int32 - gli.GetShaderiv(fs, gl_INFO_LOG_LENGTH, &logLength) - if logLength > 0 { - shLog := strings.Repeat("\x00", int(logLength+1)) - gli.GetShaderInfoLog(fs, logLength, nil, gli.Str(shLog)) - fmt.Printf("FRAGMENT_SHADER compilation log:\n\n%s\n", shLog) - } - - var status int32 - gli.GetShaderiv(fs, gl_COMPILE_STATUS, &status) - if status != gl_TRUE { - gli.DeleteShader(fs) - return nil, errors.New("Error compiling GL_FRAGMENT_SHADER shader part") - } - if glErr := gli.GetError(); glErr != gl_NO_ERROR { - return nil, errors.New("error compiling shader part, glError: " + fmt.Sprint(glErr)) - } - } - - { - program = gli.CreateProgram() - gli.AttachShader(program, vs) - gli.AttachShader(program, fs) - gli.LinkProgram(program) - - var logLength int32 - gli.GetProgramiv(program, gl_INFO_LOG_LENGTH, &logLength) - if logLength > 0 { - shLog := strings.Repeat("\x00", int(logLength+1)) - gli.GetProgramInfoLog(program, logLength, nil, gli.Str(shLog)) - fmt.Printf("Shader link log:\n\n%s\n", shLog) - } - - var status int32 - gli.GetProgramiv(program, gl_LINK_STATUS, &status) - if status != gl_TRUE { - gli.DeleteShader(vs) - gli.DeleteShader(fs) - return nil, errors.New("error linking shader") - } - if glErr := gli.GetError(); glErr != gl_NO_ERROR { - return nil, errors.New("error linking shader, glError: " + fmt.Sprint(glErr)) - } - } - - result := &solidShader{} - result.id = program - result.vertex = uint32(gli.GetAttribLocation(program, gli.Str("vertex\x00"))) - result.canvasSize = gli.GetUniformLocation(program, gli.Str("canvasSize\x00")) - result.color = gli.GetUniformLocation(program, gli.Str("color\x00")) - - return result, nil -} - type textureShader struct { id uint32 vertex uint32 @@ -206,6 +107,105 @@ func loadTextureShader() (*textureShader, error) { return result, nil } +type solidShader struct { + id uint32 + vertex uint32 + canvasSize int32 + color int32 +} + +func loadSolidShader() (*solidShader, error) { + var vs, fs, program uint32 + + { + csource, freeFunc := gli.Strs(solidVS + "\x00") + defer freeFunc() + + vs = gli.CreateShader(gl_VERTEX_SHADER) + gli.ShaderSource(vs, 1, csource, nil) + gli.CompileShader(vs) + + var logLength int32 + gli.GetShaderiv(vs, gl_INFO_LOG_LENGTH, &logLength) + if logLength > 0 { + shLog := strings.Repeat("\x00", int(logLength+1)) + gli.GetShaderInfoLog(vs, logLength, nil, gli.Str(shLog)) + fmt.Printf("VERTEX_SHADER compilation log:\n\n%s\n", shLog) + } + + var status int32 + gli.GetShaderiv(vs, gl_COMPILE_STATUS, &status) + if status != gl_TRUE { + gli.DeleteShader(vs) + return nil, errors.New("Error compiling GL_VERTEX_SHADER shader part") + } + if glErr := gli.GetError(); glErr != gl_NO_ERROR { + return nil, errors.New("error compiling shader part, glError: " + fmt.Sprint(glErr)) + } + } + + { + csource, freeFunc := gli.Strs(solidFS + "\x00") + defer freeFunc() + + fs = gli.CreateShader(gl_FRAGMENT_SHADER) + gli.ShaderSource(fs, 1, csource, nil) + gli.CompileShader(fs) + + var logLength int32 + gli.GetShaderiv(fs, gl_INFO_LOG_LENGTH, &logLength) + if logLength > 0 { + shLog := strings.Repeat("\x00", int(logLength+1)) + gli.GetShaderInfoLog(fs, logLength, nil, gli.Str(shLog)) + fmt.Printf("FRAGMENT_SHADER compilation log:\n\n%s\n", shLog) + } + + var status int32 + gli.GetShaderiv(fs, gl_COMPILE_STATUS, &status) + if status != gl_TRUE { + gli.DeleteShader(fs) + return nil, errors.New("Error compiling GL_FRAGMENT_SHADER shader part") + } + if glErr := gli.GetError(); glErr != gl_NO_ERROR { + return nil, errors.New("error compiling shader part, glError: " + fmt.Sprint(glErr)) + } + } + + { + program = gli.CreateProgram() + gli.AttachShader(program, vs) + gli.AttachShader(program, fs) + gli.LinkProgram(program) + + var logLength int32 + gli.GetProgramiv(program, gl_INFO_LOG_LENGTH, &logLength) + if logLength > 0 { + shLog := strings.Repeat("\x00", int(logLength+1)) + gli.GetProgramInfoLog(program, logLength, nil, gli.Str(shLog)) + fmt.Printf("Shader link log:\n\n%s\n", shLog) + } + + var status int32 + gli.GetProgramiv(program, gl_LINK_STATUS, &status) + if status != gl_TRUE { + gli.DeleteShader(vs) + gli.DeleteShader(fs) + return nil, errors.New("error linking shader") + } + if glErr := gli.GetError(); glErr != gl_NO_ERROR { + return nil, errors.New("error linking shader, glError: " + fmt.Sprint(glErr)) + } + } + + result := &solidShader{} + result.id = program + result.vertex = uint32(gli.GetAttribLocation(program, gli.Str("vertex\x00"))) + result.canvasSize = gli.GetUniformLocation(program, gli.Str("canvasSize\x00")) + result.color = gli.GetUniformLocation(program, gli.Str("color\x00")) + + return result, nil +} + type linearGradientShader struct { id uint32 vertex uint32 @@ -317,7 +317,10 @@ type radialGradientShader struct { canvasSize int32 gradient int32 from int32 + to int32 dir int32 + radFrom int32 + radTo int32 len int32 } @@ -410,7 +413,10 @@ func loadRadialGradientShader() (*radialGradientShader, error) { result.canvasSize = gli.GetUniformLocation(program, gli.Str("canvasSize\x00")) result.gradient = gli.GetUniformLocation(program, gli.Str("gradient\x00")) result.from = gli.GetUniformLocation(program, gli.Str("from\x00")) + result.to = gli.GetUniformLocation(program, gli.Str("to\x00")) result.dir = gli.GetUniformLocation(program, gli.Str("dir\x00")) + result.radFrom = gli.GetUniformLocation(program, gli.Str("radFrom\x00")) + result.radTo = gli.GetUniformLocation(program, gli.Str("radTo\x00")) result.len = gli.GetUniformLocation(program, gli.Str("len\x00")) return result, nil