added image patterns
This commit is contained in:
parent
bed6cdc50a
commit
3710a446b5
2 changed files with 258 additions and 111 deletions
46
canvas.go
46
canvas.go
|
@ -39,6 +39,7 @@ type drawState struct {
|
|||
color glColor
|
||||
radialGradient *RadialGradient
|
||||
linearGradient *LinearGradient
|
||||
image *Image
|
||||
}
|
||||
stroke struct {
|
||||
color glColor
|
||||
|
@ -128,6 +129,7 @@ var (
|
|||
tr *textureShader
|
||||
lgr *linearGradientShader
|
||||
rgr *radialGradientShader
|
||||
ipr *imagePatternShader
|
||||
glChan = make(chan func())
|
||||
)
|
||||
|
||||
|
@ -172,6 +174,15 @@ func LoadGL(glimpl GL) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
ipr, err = loadImagePatternShader()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = glError()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
gli.GenBuffers(1, &buf)
|
||||
err = glError()
|
||||
if err != nil {
|
||||
|
@ -285,6 +296,26 @@ void main() {
|
|||
float r = radFrom + o * (radTo - radFrom);
|
||||
gl_FragColor = texture1D(gradient, o);
|
||||
}`
|
||||
var imagePatternVS = `
|
||||
attribute vec2 vertex;
|
||||
uniform vec2 canvasSize;
|
||||
varying vec2 v_cp;
|
||||
void main() {
|
||||
v_cp = vertex;
|
||||
vec2 glp = vertex * 2.0 / canvasSize - 1.0;
|
||||
gl_Position = vec4(glp.x, -glp.y, 0.0, 1.0);
|
||||
}`
|
||||
var imagePatternFS = `
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
varying vec2 v_cp;
|
||||
uniform vec2 imageSize;
|
||||
uniform sampler2D image;
|
||||
void main() {
|
||||
gl_FragColor = texture2D(image, mod(v_cp / imageSize, 1.0));
|
||||
//gl_FragColor = vec4(v_cp * 0.1, 0.0, 1.0);
|
||||
}`
|
||||
|
||||
func glError() error {
|
||||
glErr := gli.GetError()
|
||||
|
@ -299,6 +330,7 @@ func (cv *Canvas) SetFillStyle(value ...interface{}) {
|
|||
cv.state.fill.color = glColor{}
|
||||
cv.state.fill.linearGradient = nil
|
||||
cv.state.fill.radialGradient = nil
|
||||
cv.state.fill.image = nil
|
||||
if len(value) == 1 {
|
||||
switch v := value[0].(type) {
|
||||
case *LinearGradient:
|
||||
|
@ -307,6 +339,9 @@ func (cv *Canvas) SetFillStyle(value ...interface{}) {
|
|||
case *RadialGradient:
|
||||
cv.state.fill.radialGradient = v
|
||||
return
|
||||
case *Image:
|
||||
cv.state.fill.image = v
|
||||
return
|
||||
}
|
||||
}
|
||||
c, ok := parseColor(value...)
|
||||
|
@ -458,6 +493,17 @@ func (cv *Canvas) FillRect(x, y, w, h float32) {
|
|||
gli.EnableVertexAttribArray(rgr.vertex)
|
||||
gli.DrawArrays(gl_TRIANGLE_FAN, 0, 4)
|
||||
gli.DisableVertexAttribArray(rgr.vertex)
|
||||
} else if img := cv.state.fill.image; img != nil {
|
||||
gli.UseProgram(ipr.id)
|
||||
gli.VertexAttribPointer(ipr.vertex, 2, gl_FLOAT, false, 0, nil)
|
||||
gli.ActiveTexture(gl_TEXTURE0)
|
||||
gli.BindTexture(gl_TEXTURE_1D, img.tex)
|
||||
gli.Uniform2f(ipr.canvasSize, cv.fw, cv.fh)
|
||||
gli.Uniform2f(ipr.imageSize, float32(img.w), float32(img.h))
|
||||
gli.Uniform1i(ipr.image, 0)
|
||||
gli.EnableVertexAttribArray(ipr.vertex)
|
||||
gli.DrawArrays(gl_TRIANGLE_FAN, 0, 4)
|
||||
gli.DisableVertexAttribArray(ipr.vertex)
|
||||
} else {
|
||||
gli.UseProgram(sr.id)
|
||||
gli.VertexAttribPointer(sr.vertex, 2, gl_FLOAT, false, 0, nil)
|
||||
|
|
323
made_shaders.go
323
made_shaders.go
|
@ -6,6 +6,107 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
type imagePatternShader struct {
|
||||
id uint32
|
||||
vertex uint32
|
||||
canvasSize int32
|
||||
imageSize int32
|
||||
image int32
|
||||
}
|
||||
|
||||
func loadImagePatternShader() (*imagePatternShader, error) {
|
||||
var vs, fs, program uint32
|
||||
|
||||
{
|
||||
csource, freeFunc := gli.Strs(imagePatternVS + "\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(imagePatternFS + "\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 := &imagePatternShader{}
|
||||
result.id = program
|
||||
result.vertex = uint32(gli.GetAttribLocation(program, gli.Str("vertex\x00")))
|
||||
result.canvasSize = gli.GetUniformLocation(program, gli.Str("canvasSize\x00"))
|
||||
result.imageSize = gli.GetUniformLocation(program, gli.Str("imageSize\x00"))
|
||||
result.image = gli.GetUniformLocation(program, gli.Str("image\x00"))
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
type textureShader struct {
|
||||
id uint32
|
||||
vertex uint32
|
||||
|
@ -107,6 +208,117 @@ func loadTextureShader() (*textureShader, error) {
|
|||
return result, nil
|
||||
}
|
||||
|
||||
type radialGradientShader struct {
|
||||
id uint32
|
||||
vertex uint32
|
||||
canvasSize int32
|
||||
gradient int32
|
||||
from int32
|
||||
to int32
|
||||
dir int32
|
||||
radFrom int32
|
||||
radTo int32
|
||||
len int32
|
||||
}
|
||||
|
||||
func loadRadialGradientShader() (*radialGradientShader, error) {
|
||||
var vs, fs, program uint32
|
||||
|
||||
{
|
||||
csource, freeFunc := gli.Strs(radialGradientVS + "\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(radialGradientFS + "\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 := &radialGradientShader{}
|
||||
result.id = program
|
||||
result.vertex = uint32(gli.GetAttribLocation(program, gli.Str("vertex\x00")))
|
||||
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
|
||||
}
|
||||
|
||||
type solidShader struct {
|
||||
id uint32
|
||||
vertex uint32
|
||||
|
@ -310,114 +522,3 @@ func loadLinearGradientShader() (*linearGradientShader, error) {
|
|||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
type radialGradientShader struct {
|
||||
id uint32
|
||||
vertex uint32
|
||||
canvasSize int32
|
||||
gradient int32
|
||||
from int32
|
||||
to int32
|
||||
dir int32
|
||||
radFrom int32
|
||||
radTo int32
|
||||
len int32
|
||||
}
|
||||
|
||||
func loadRadialGradientShader() (*radialGradientShader, error) {
|
||||
var vs, fs, program uint32
|
||||
|
||||
{
|
||||
csource, freeFunc := gli.Strs(radialGradientVS + "\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(radialGradientFS + "\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 := &radialGradientShader{}
|
||||
result.id = program
|
||||
result.vertex = uint32(gli.GetAttribLocation(program, gli.Str("vertex\x00")))
|
||||
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
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue