moved the canvas to gl coordinate transformation to the shaders; fixed some bugs along the way
This commit is contained in:
parent
7edac03910
commit
2de2dd26a4
6 changed files with 308 additions and 357 deletions
35
canvas.go
35
canvas.go
|
@ -91,24 +91,11 @@ func New(x, y, w, h int) *Canvas {
|
|||
return cv
|
||||
}
|
||||
|
||||
func (cv *Canvas) ptToGL(x, y float32) (fx, fy float32) {
|
||||
return cv.vecToGL(lm.Vec2{x, y})
|
||||
}
|
||||
|
||||
func (cv *Canvas) vecToGL(v lm.Vec2) (fx, fy float32) {
|
||||
return v[0]*2/cv.fw - 1, -v[1]*2/cv.fh + 1
|
||||
}
|
||||
|
||||
func (cv *Canvas) tf(v lm.Vec2) lm.Vec2 {
|
||||
v, _ = v.MulMat3x3(cv.state.transform)
|
||||
return v
|
||||
}
|
||||
|
||||
func (cv *Canvas) tfToGL(x, y float32) (fx, fy float32) {
|
||||
v := cv.tf(lm.Vec2{x, y})
|
||||
return v[0]*2/cv.fw - 1, -v[1]*2/cv.fh + 1
|
||||
}
|
||||
|
||||
// Activate makes the canvas active and sets the viewport. Only needs
|
||||
// to be called if any other GL code changes the viewport
|
||||
func (cv *Canvas) Activate() {
|
||||
|
@ -193,8 +180,10 @@ func LoadGL(glimpl GL) (err error) {
|
|||
|
||||
var solidVS = `
|
||||
attribute vec2 vertex;
|
||||
uniform vec2 canvasSize;
|
||||
void main() {
|
||||
gl_Position = vec4(vertex, 0.0, 1.0);
|
||||
vec2 glp = vertex * 2.0 / canvasSize - 1.0;
|
||||
gl_Position = vec4(glp.x, -glp.y, 0.0, 1.0);
|
||||
}`
|
||||
var solidFS = `
|
||||
#ifdef GL_ES
|
||||
|
@ -207,10 +196,12 @@ void main() {
|
|||
|
||||
var textureVS = `
|
||||
attribute vec2 vertex, texCoord;
|
||||
uniform vec2 canvasSize;
|
||||
varying vec2 v_texCoord;
|
||||
void main() {
|
||||
v_texCoord = texCoord;
|
||||
gl_Position = vec4(vertex, 0.0, 1.0);
|
||||
vec2 glp = vertex * 2.0 / canvasSize - 1.0;
|
||||
gl_Position = vec4(glp.x, -glp.y, 0.0, 1.0);
|
||||
}`
|
||||
var textureFS = `
|
||||
#ifdef GL_ES
|
||||
|
@ -364,7 +355,6 @@ func (cv *Canvas) SetTransform(a, b, c, d, e, f float32) {
|
|||
func (cv *Canvas) FillRect(x, y, w, h float32) {
|
||||
cv.activate()
|
||||
|
||||
if lg := cv.state.fill.linearGradient; lg != nil {
|
||||
p0 := cv.tf(lm.Vec2{x, y})
|
||||
p1 := cv.tf(lm.Vec2{x, y + h})
|
||||
p2 := cv.tf(lm.Vec2{x + w, y + h})
|
||||
|
@ -374,12 +364,12 @@ func (cv *Canvas) FillRect(x, y, w, h float32) {
|
|||
data := [8]float32{p0[0], p0[1], p1[0], p1[1], p2[0], p2[1], p3[0], p3[1]}
|
||||
gli.BufferData(gl_ARRAY_BUFFER, len(data)*4, unsafe.Pointer(&data[0]), gl_STREAM_DRAW)
|
||||
|
||||
if lg := cv.state.fill.linearGradient; lg != nil {
|
||||
lg.load()
|
||||
gli.UseProgram(lgr.id)
|
||||
gli.VertexAttribPointer(lgr.vertex, 2, gl_FLOAT, false, 0, nil)
|
||||
gli.ActiveTexture(gl_TEXTURE0)
|
||||
gli.BindTexture(gl_TEXTURE_1D, lg.tex)
|
||||
|
||||
gli.Uniform2f(lgr.canvasSize, cv.fw, cv.fh)
|
||||
from := cv.tf(lg.from)
|
||||
to := cv.tf(lg.to)
|
||||
|
@ -389,23 +379,14 @@ func (cv *Canvas) FillRect(x, y, w, h float32) {
|
|||
gli.Uniform2f(lgr.from, from[0], from[1])
|
||||
gli.Uniform2f(lgr.dir, dir[0], dir[1])
|
||||
gli.Uniform1f(lgr.length, length)
|
||||
|
||||
gli.Uniform1i(lgr.gradient, 0)
|
||||
gli.EnableVertexAttribArray(lgr.vertex)
|
||||
gli.DrawArrays(gl_TRIANGLE_FAN, 0, 4)
|
||||
gli.DisableVertexAttribArray(lgr.vertex)
|
||||
} else {
|
||||
x0f, y0f := cv.tfToGL(x, y)
|
||||
x1f, y1f := cv.tfToGL(x, y+h)
|
||||
x2f, y2f := cv.tfToGL(x+w, y+h)
|
||||
x3f, y3f := cv.tfToGL(x+w, y)
|
||||
|
||||
gli.BindBuffer(gl_ARRAY_BUFFER, buf)
|
||||
data := [8]float32{x0f, y0f, x1f, y1f, x2f, y2f, x3f, y3f}
|
||||
gli.BufferData(gl_ARRAY_BUFFER, len(data)*4, unsafe.Pointer(&data[0]), gl_STREAM_DRAW)
|
||||
|
||||
gli.UseProgram(sr.id)
|
||||
gli.VertexAttribPointer(sr.vertex, 2, gl_FLOAT, false, 0, nil)
|
||||
gli.Uniform2f(sr.canvasSize, cv.fw, cv.fh)
|
||||
c := cv.state.fill.color
|
||||
gli.Uniform4f(sr.color, c.r, c.g, c.b, c.a)
|
||||
gli.EnableVertexAttribArray(lgr.vertex)
|
||||
|
|
21
imagedata.go
21
imagedata.go
|
@ -45,15 +45,17 @@ func (cv *Canvas) GetImageData(x, y, w, h int) *image.RGBA {
|
|||
func (cv *Canvas) PutImageData(img *image.RGBA, x, y int) {
|
||||
cv.activate()
|
||||
|
||||
gli.ActiveTexture(gl_TEXTURE0)
|
||||
if imageBufTex == 0 {
|
||||
gli.GenTextures(1, &imageBufTex)
|
||||
}
|
||||
gli.ActiveTexture(gl_TEXTURE0)
|
||||
gli.BindTexture(gl_TEXTURE_2D, imageBufTex)
|
||||
gli.TexParameteri(gl_TEXTURE_2D, gl_TEXTURE_MIN_FILTER, gl_LINEAR)
|
||||
gli.TexParameteri(gl_TEXTURE_2D, gl_TEXTURE_MAG_FILTER, gl_LINEAR)
|
||||
gli.TexParameteri(gl_TEXTURE_2D, gl_TEXTURE_WRAP_S, gl_CLAMP_TO_EDGE)
|
||||
gli.TexParameteri(gl_TEXTURE_2D, gl_TEXTURE_WRAP_T, gl_CLAMP_TO_EDGE)
|
||||
} else {
|
||||
gli.BindTexture(gl_TEXTURE_2D, imageBufTex)
|
||||
}
|
||||
|
||||
w, h := img.Bounds().Dx(), img.Bounds().Dy()
|
||||
|
||||
|
@ -72,19 +74,14 @@ func (cv *Canvas) PutImageData(img *image.RGBA, x, y int) {
|
|||
dx, dy := float32(x), float32(y)
|
||||
dw, dh := float32(w), float32(h)
|
||||
|
||||
dx0, dy0 := dx*2/cv.fw-1, -dy*2/cv.fh+1
|
||||
dx1, dy1 := dx0, -(dy+dh)*2/cv.fh+1
|
||||
dx2, dy2 := (dx+dw)*2/cv.fw-1, dy1
|
||||
dx3, dy3 := dx2, dy0
|
||||
gli.BindBuffer(gl_ARRAY_BUFFER, buf)
|
||||
data := [16]float32{dx, dy, dx + dw, dy, dx + dw, dy + dh, dx, dy + dh,
|
||||
0, 0, 1, 0, 1, 1, 0, 1}
|
||||
gli.BufferData(gl_ARRAY_BUFFER, len(data)*4, unsafe.Pointer(&data[0]), gl_STREAM_DRAW)
|
||||
|
||||
gli.UseProgram(tr.id)
|
||||
gli.Uniform1i(tr.image, 0)
|
||||
|
||||
gli.BindBuffer(gl_ARRAY_BUFFER, buf)
|
||||
data := [16]float32{dx0, dy0, dx1, dy1, dx2, dy2, dx3, dy3,
|
||||
0, 0, 0, 1, 1, 1, 1, 0}
|
||||
gli.BufferData(gl_ARRAY_BUFFER, len(data)*4, unsafe.Pointer(&data[0]), gl_STREAM_DRAW)
|
||||
|
||||
gli.Uniform2f(tr.canvasSize, cv.fw, cv.fh)
|
||||
gli.VertexAttribPointer(tr.vertex, 2, gl_FLOAT, false, 0, nil)
|
||||
gli.VertexAttribPointer(tr.texCoord, 2, gl_FLOAT, false, 0, gli.PtrOffset(8*4))
|
||||
gli.EnableVertexAttribArray(tr.vertex)
|
||||
|
|
27
images.go
27
images.go
|
@ -7,6 +7,8 @@ import (
|
|||
"io/ioutil"
|
||||
"runtime"
|
||||
"unsafe"
|
||||
|
||||
"github.com/tfriedel6/lm"
|
||||
)
|
||||
|
||||
type Image struct {
|
||||
|
@ -172,6 +174,8 @@ func (cv *Canvas) DrawImage(img *Image, coords ...float32) {
|
|||
return
|
||||
}
|
||||
|
||||
cv.activate()
|
||||
|
||||
var sx, sy, sw, sh, dx, dy, dw, dh float32
|
||||
sw, sh = float32(img.w), float32(img.h)
|
||||
dw, dh = float32(img.w), float32(img.h)
|
||||
|
@ -187,28 +191,27 @@ func (cv *Canvas) DrawImage(img *Image, coords ...float32) {
|
|||
dw, dh = coords[6], coords[7]
|
||||
}
|
||||
|
||||
dx0, dy0 := cv.tfToGL(dx, dy)
|
||||
dx1, dy1 := cv.tfToGL(dx, dy+dh)
|
||||
dx2, dy2 := cv.tfToGL(dx+dw, dy+dh)
|
||||
dx3, dy3 := cv.tfToGL(dx+dw, dy)
|
||||
sx /= float32(img.w)
|
||||
sy /= float32(img.h)
|
||||
sw /= float32(img.w)
|
||||
sh /= float32(img.h)
|
||||
|
||||
cv.activate()
|
||||
|
||||
gli.UseProgram(tr.id)
|
||||
|
||||
gli.ActiveTexture(gl_TEXTURE0)
|
||||
gli.BindTexture(gl_TEXTURE_2D, img.tex)
|
||||
gli.Uniform1i(tr.image, 0)
|
||||
p0 := cv.tf(lm.Vec2{dx, dy})
|
||||
p1 := cv.tf(lm.Vec2{dx, dy + dh})
|
||||
p2 := cv.tf(lm.Vec2{dx + dw, dy + dh})
|
||||
p3 := cv.tf(lm.Vec2{dx + dw, dy})
|
||||
|
||||
gli.BindBuffer(gl_ARRAY_BUFFER, buf)
|
||||
data := [16]float32{dx0, dy0, dx1, dy1, dx2, dy2, dx3, dy3,
|
||||
data := [16]float32{p0[0], p0[1], p1[0], p1[1], p2[0], p2[1], p3[0], p3[1],
|
||||
sx, sy, sx, sy + sh, sx + sw, sy + sh, sx + sw, sy}
|
||||
gli.BufferData(gl_ARRAY_BUFFER, len(data)*4, unsafe.Pointer(&data[0]), gl_STREAM_DRAW)
|
||||
|
||||
gli.ActiveTexture(gl_TEXTURE0)
|
||||
gli.BindTexture(gl_TEXTURE_2D, img.tex)
|
||||
|
||||
gli.UseProgram(tr.id)
|
||||
gli.Uniform1i(tr.image, 0)
|
||||
gli.Uniform2f(tr.canvasSize, cv.fw, cv.fh)
|
||||
gli.VertexAttribPointer(tr.vertex, 2, gl_FLOAT, false, 0, nil)
|
||||
gli.VertexAttribPointer(tr.texCoord, 2, gl_FLOAT, false, 0, gli.PtrOffset(8*4))
|
||||
gli.EnableVertexAttribArray(tr.vertex)
|
||||
|
|
396
made_shaders.go
396
made_shaders.go
|
@ -6,6 +6,206 @@ 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
|
||||
texCoord uint32
|
||||
canvasSize int32
|
||||
image int32
|
||||
}
|
||||
|
||||
func loadTextureShader() (*textureShader, error) {
|
||||
var vs, fs, program uint32
|
||||
|
||||
{
|
||||
csource, freeFunc := gli.Strs(textureVS + "\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(textureFS + "\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 := &textureShader{}
|
||||
result.id = program
|
||||
result.vertex = uint32(gli.GetAttribLocation(program, gli.Str("vertex\x00")))
|
||||
result.texCoord = uint32(gli.GetAttribLocation(program, gli.Str("texCoord\x00")))
|
||||
result.canvasSize = gli.GetUniformLocation(program, gli.Str("canvasSize\x00"))
|
||||
result.image = gli.GetUniformLocation(program, gli.Str("image\x00"))
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
type linearGradientShader struct {
|
||||
id uint32
|
||||
vertex uint32
|
||||
|
@ -110,199 +310,3 @@ func loadLinearGradientShader() (*linearGradientShader, error) {
|
|||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
type solidShader struct {
|
||||
id uint32
|
||||
vertex uint32
|
||||
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.color = gli.GetUniformLocation(program, gli.Str("color\x00"))
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
type textureShader struct {
|
||||
id uint32
|
||||
vertex uint32
|
||||
texCoord uint32
|
||||
image int32
|
||||
}
|
||||
|
||||
func loadTextureShader() (*textureShader, error) {
|
||||
var vs, fs, program uint32
|
||||
|
||||
{
|
||||
csource, freeFunc := gli.Strs(textureVS + "\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(textureFS + "\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 := &textureShader{}
|
||||
result.id = program
|
||||
result.vertex = uint32(gli.GetAttribLocation(program, gli.Str("vertex\x00")))
|
||||
result.texCoord = uint32(gli.GetAttribLocation(program, gli.Str("texCoord\x00")))
|
||||
result.image = gli.GetUniformLocation(program, gli.Str("image\x00"))
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
|
145
paths.go
145
paths.go
|
@ -86,9 +86,8 @@ func (cv *Canvas) Arc(x, y, radius, startAngle, endAngle float32, anticlockwise
|
|||
}
|
||||
if !anticlockwise && endAngle <= startAngle {
|
||||
endAngle += math.Pi * 2
|
||||
} else if anticlockwise && startAngle <= endAngle {
|
||||
startAngle += math.Pi * 2
|
||||
startAngle, endAngle = endAngle, startAngle
|
||||
} else if anticlockwise && endAngle >= startAngle {
|
||||
endAngle -= math.Pi * 2
|
||||
}
|
||||
tr := cv.tf(lm.Vec2{radius, radius})
|
||||
step := 6 / fmath.Max(tr[0], tr[1])
|
||||
|
@ -165,16 +164,11 @@ func (cv *Canvas) Stroke() {
|
|||
gli.StencilOp(gl_KEEP, gl_KEEP, gl_REPLACE)
|
||||
gli.StencilMask(0x01)
|
||||
|
||||
gli.UseProgram(sr.id)
|
||||
c := cv.state.stroke.color
|
||||
gli.Uniform4f(sr.color, c.r, c.g, c.b, c.a)
|
||||
gli.EnableVertexAttribArray(sr.vertex)
|
||||
|
||||
gli.BindBuffer(gl_ARRAY_BUFFER, buf)
|
||||
|
||||
var buf [1000]float32
|
||||
tris := buf[:0]
|
||||
tris = append(tris, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1)
|
||||
tris = append(tris, 0, 0, cv.fw, 0, cv.fw, cv.fh, 0, 0, cv.fw, cv.fh, 0, cv.fh)
|
||||
|
||||
start := true
|
||||
var p0 lm.Vec2
|
||||
|
@ -190,18 +184,18 @@ func (cv *Canvas) Stroke() {
|
|||
v1 := lm.Vec2{v0[1], -v0[0]}.MulF(cv.state.stroke.lineWidth * 0.5)
|
||||
v0 = v0.MulF(cv.state.stroke.lineWidth * 0.5)
|
||||
|
||||
l0p0 := p0.Add(v1)
|
||||
l0p1 := p1.Add(v1)
|
||||
l0p2 := p0.Sub(v1)
|
||||
l0p3 := p1.Sub(v1)
|
||||
lp0 := p0.Add(v1)
|
||||
lp1 := p1.Add(v1)
|
||||
lp2 := p0.Sub(v1)
|
||||
lp3 := p1.Sub(v1)
|
||||
|
||||
if start {
|
||||
switch cv.state.lineEnd {
|
||||
case Butt:
|
||||
// no need to do anything
|
||||
case Square:
|
||||
l0p0 = l0p0.Sub(v0)
|
||||
l0p2 = l0p2.Sub(v0)
|
||||
lp0 = lp0.Sub(v0)
|
||||
lp2 = lp2.Sub(v0)
|
||||
case Round:
|
||||
tris = cv.addCircleTris(p0, cv.state.stroke.lineWidth*0.5, tris)
|
||||
}
|
||||
|
@ -212,24 +206,19 @@ func (cv *Canvas) Stroke() {
|
|||
case Butt:
|
||||
// no need to do anything
|
||||
case Square:
|
||||
l0p1 = l0p1.Add(v0)
|
||||
l0p3 = l0p3.Add(v0)
|
||||
lp1 = lp1.Add(v0)
|
||||
lp3 = lp3.Add(v0)
|
||||
case Round:
|
||||
tris = cv.addCircleTris(p1, cv.state.stroke.lineWidth*0.5, tris)
|
||||
}
|
||||
}
|
||||
|
||||
l0x0f, l0y0f := cv.vecToGL(l0p0)
|
||||
l0x1f, l0y1f := cv.vecToGL(l0p1)
|
||||
l0x2f, l0y2f := cv.vecToGL(l0p2)
|
||||
l0x3f, l0y3f := cv.vecToGL(l0p3)
|
||||
|
||||
tris = append(tris,
|
||||
l0x0f, l0y0f, l0x1f, l0y1f, l0x3f, l0y3f,
|
||||
l0x0f, l0y0f, l0x3f, l0y3f, l0x2f, l0y2f)
|
||||
lp0[0], lp0[1], lp1[0], lp1[1], lp3[0], lp3[1],
|
||||
lp0[0], lp0[1], lp3[0], lp3[1], lp2[0], lp2[1])
|
||||
|
||||
if p.attach {
|
||||
tris = cv.lineJoint(p, p0, p1, p.next, l0p0, l0p1, l0p2, l0p3, tris)
|
||||
tris = cv.lineJoint(p, p0, p1, p.next, lp0, lp1, lp2, lp3, tris)
|
||||
}
|
||||
|
||||
p0 = p1
|
||||
|
@ -237,10 +226,20 @@ func (cv *Canvas) Stroke() {
|
|||
}
|
||||
|
||||
gli.BufferData(gl_ARRAY_BUFFER, len(tris)*4, unsafe.Pointer(&tris[0]), gl_STREAM_DRAW)
|
||||
|
||||
gli.UseProgram(sr.id)
|
||||
c := cv.state.stroke.color
|
||||
gli.Uniform4f(sr.color, c.r, c.g, c.b, c.a)
|
||||
gli.Uniform2f(sr.canvasSize, cv.fw, cv.fh)
|
||||
|
||||
gli.ColorMask(false, false, false, false)
|
||||
|
||||
gli.EnableVertexAttribArray(sr.vertex)
|
||||
gli.VertexAttribPointer(sr.vertex, 2, gl_FLOAT, false, 0, nil)
|
||||
gli.DrawArrays(gl_TRIANGLES, 6, int32(len(tris)/2-6))
|
||||
|
||||
gli.ColorMask(true, true, true, true)
|
||||
|
||||
gli.StencilFunc(gl_EQUAL, 1, 0xFF)
|
||||
gli.StencilMask(0xFF)
|
||||
|
||||
|
@ -248,7 +247,6 @@ func (cv *Canvas) Stroke() {
|
|||
|
||||
gli.DisableVertexAttribArray(sr.vertex)
|
||||
|
||||
gli.ColorMask(true, true, true, true)
|
||||
gli.StencilOp(gl_KEEP, gl_KEEP, gl_KEEP)
|
||||
gli.StencilFunc(gl_EQUAL, 0, 0xFF)
|
||||
|
||||
|
@ -261,9 +259,6 @@ func (cv *Canvas) lineJoint(p pathPoint, p0, p1, p2, l0p0, l0p1, l0p2, l0p3 lm.V
|
|||
v2 := p1.Sub(p2).Norm()
|
||||
v3 := lm.Vec2{v2[1], -v2[0]}.MulF(cv.state.stroke.lineWidth * 0.5)
|
||||
|
||||
l0x1f, l0y1f := cv.vecToGL(l0p1)
|
||||
l0x3f, l0y3f := cv.vecToGL(l0p3)
|
||||
|
||||
switch cv.state.lineJoin {
|
||||
case Miter:
|
||||
l1p0 := p2.Sub(v3)
|
||||
|
@ -271,33 +266,21 @@ func (cv *Canvas) lineJoint(p pathPoint, p0, p1, p2, l0p0, l0p1, l0p2, l0p3 lm.V
|
|||
l1p2 := p2.Add(v3)
|
||||
l1p3 := p1.Add(v3)
|
||||
|
||||
l1x1f, l1y1f := cv.vecToGL(l1p1)
|
||||
l1x3f, l1y3f := cv.vecToGL(l1p3)
|
||||
|
||||
ip0 := lineIntersection(l0p0, l0p1, l1p1, l1p0)
|
||||
ip1 := lineIntersection(l0p2, l0p3, l1p3, l1p2)
|
||||
|
||||
cxf, cyf := cv.vecToGL(p1)
|
||||
ix0f, iy0f := cv.vecToGL(ip0)
|
||||
ix1f, iy1f := cv.vecToGL(ip1)
|
||||
|
||||
tris = append(tris,
|
||||
cxf, cyf, l0x1f, l0y1f, ix0f, iy0f,
|
||||
cxf, cyf, ix0f, iy0f, l1x1f, l1y1f,
|
||||
cxf, cyf, l1x3f, l1y3f, ix1f, iy1f,
|
||||
cxf, cyf, ix1f, iy1f, l0x3f, l0y3f)
|
||||
p1[0], p1[1], l0p1[0], l0p1[1], ip0[0], ip0[1],
|
||||
p1[0], p1[1], ip0[0], ip0[1], l1p1[0], l1p1[1],
|
||||
p1[0], p1[1], l1p3[0], l1p3[1], ip1[0], ip1[1],
|
||||
p1[0], p1[1], ip1[0], ip1[1], l0p3[0], l0p3[1])
|
||||
case Bevel:
|
||||
l1p1 := p1.Sub(v3)
|
||||
l1p3 := p1.Add(v3)
|
||||
|
||||
l1x1f, l1y1f := cv.vecToGL(l1p1)
|
||||
l1x3f, l1y3f := cv.vecToGL(l1p3)
|
||||
|
||||
cxf, cyf := cv.vecToGL(p1)
|
||||
|
||||
tris = append(tris,
|
||||
cxf, cyf, l0x1f, l0y1f, l1x1f, l1y1f,
|
||||
cxf, cyf, l1x3f, l1y3f, l0x3f, l0y3f)
|
||||
p1[0], p1[1], l0p1[0], l0p1[1], l1p1[0], l1p1[1],
|
||||
p1[0], p1[1], l1p3[0], l1p3[1], l0p3[0], l0p3[1])
|
||||
case Round:
|
||||
tris = cv.addCircleTris(p1, cv.state.stroke.lineWidth*0.5, tris)
|
||||
}
|
||||
|
@ -305,9 +288,8 @@ func (cv *Canvas) lineJoint(p pathPoint, p0, p1, p2, l0p0, l0p1, l0p2, l0p3 lm.V
|
|||
return tris
|
||||
}
|
||||
|
||||
func (cv *Canvas) addCircleTris(p lm.Vec2, radius float32, tris []float32) []float32 {
|
||||
cxf, cyf := cv.vecToGL(p)
|
||||
p0x, p0y := cv.vecToGL(lm.Vec2{p[0], p[1] + radius})
|
||||
func (cv *Canvas) addCircleTris(center lm.Vec2, radius float32, tris []float32) []float32 {
|
||||
p0 := lm.Vec2{center[0], center[1] + radius}
|
||||
step := 6 / radius
|
||||
if step > 0.8 {
|
||||
step = 0.8
|
||||
|
@ -316,9 +298,9 @@ func (cv *Canvas) addCircleTris(p lm.Vec2, radius float32, tris []float32) []flo
|
|||
}
|
||||
for angle := step; angle <= math.Pi*2+step; angle += step {
|
||||
s, c := fmath.Sincos(angle)
|
||||
p1x, p1y := cv.vecToGL(lm.Vec2{p[0] + s*radius, p[1] + c*radius})
|
||||
tris = append(tris, cxf, cyf, p0x, p0y, p1x, p1y)
|
||||
p0x, p0y = p1x, p1y
|
||||
p1 := lm.Vec2{center[0] + s*radius, center[1] + c*radius}
|
||||
tris = append(tris, center[0], center[1], p0[0], p0[1], p1[0], p1[1])
|
||||
p0 = p1
|
||||
}
|
||||
return tris
|
||||
}
|
||||
|
@ -352,28 +334,18 @@ func (cv *Canvas) Fill() {
|
|||
|
||||
cv.activate()
|
||||
|
||||
gli.BindBuffer(gl_ARRAY_BUFFER, buf)
|
||||
var buf [1000]float32
|
||||
tris := triangulatePath(path, buf[:0])
|
||||
gli.BufferData(gl_ARRAY_BUFFER, len(tris)*4, unsafe.Pointer(&tris[0]), gl_STREAM_DRAW)
|
||||
|
||||
gli.UseProgram(sr.id)
|
||||
c := cv.state.fill.color
|
||||
gli.Uniform4f(sr.color, c.r, c.g, c.b, c.a)
|
||||
gli.Uniform2f(sr.canvasSize, cv.fw, cv.fh)
|
||||
gli.EnableVertexAttribArray(sr.vertex)
|
||||
|
||||
gli.BindBuffer(gl_ARRAY_BUFFER, buf)
|
||||
|
||||
var buf [1000]float32
|
||||
tris := buf[:0]
|
||||
tris = append(tris)
|
||||
|
||||
tris = triangulatePath(path, tris)
|
||||
total := len(tris)
|
||||
for i := 0; i < total; i += 2 {
|
||||
x, y := tris[i], tris[i+1]
|
||||
tris[i], tris[i+1] = cv.ptToGL(x, y)
|
||||
}
|
||||
|
||||
gli.BufferData(gl_ARRAY_BUFFER, len(tris)*4, unsafe.Pointer(&tris[0]), gl_STREAM_DRAW)
|
||||
gli.VertexAttribPointer(sr.vertex, 2, gl_FLOAT, false, 0, nil)
|
||||
gli.DrawArrays(gl_TRIANGLES, 0, int32(len(tris)/2))
|
||||
|
||||
gli.DisableVertexAttribArray(sr.vertex)
|
||||
}
|
||||
|
||||
|
@ -388,33 +360,26 @@ func (cv *Canvas) Clip() {
|
|||
func (cv *Canvas) clip(path []pathPoint) {
|
||||
cv.activate()
|
||||
|
||||
gli.BindBuffer(gl_ARRAY_BUFFER, buf)
|
||||
var buf [1000]float32
|
||||
tris := buf[:0]
|
||||
tris = append(tris, 0, 0, cv.fw, 0, cv.fw, cv.fh, 0, 0, cv.fw, cv.fh, 0, cv.fh)
|
||||
tris = triangulatePath(path, tris)
|
||||
gli.BufferData(gl_ARRAY_BUFFER, len(tris)*4, unsafe.Pointer(&tris[0]), gl_STREAM_DRAW)
|
||||
gli.VertexAttribPointer(sr.vertex, 2, gl_FLOAT, false, 0, nil)
|
||||
|
||||
gli.UseProgram(sr.id)
|
||||
c := cv.state.fill.color
|
||||
gli.Uniform4f(sr.color, c.r, c.g, c.b, c.a)
|
||||
gli.Uniform2f(sr.canvasSize, cv.fw, cv.fh)
|
||||
gli.EnableVertexAttribArray(sr.vertex)
|
||||
|
||||
gli.ColorMask(false, false, false, false)
|
||||
gli.StencilFunc(gl_ALWAYS, 2, 0xFF)
|
||||
gli.StencilOp(gl_KEEP, gl_KEEP, gl_REPLACE)
|
||||
gli.StencilMask(0x02)
|
||||
gli.Clear(gl_STENCIL_BUFFER_BIT)
|
||||
|
||||
gli.UseProgram(sr.id)
|
||||
c := cv.state.fill.color
|
||||
gli.Uniform4f(sr.color, c.r, c.g, c.b, c.a)
|
||||
gli.EnableVertexAttribArray(sr.vertex)
|
||||
|
||||
gli.BindBuffer(gl_ARRAY_BUFFER, buf)
|
||||
|
||||
var buf [1000]float32
|
||||
tris := buf[:0]
|
||||
tris = append(tris, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1)
|
||||
|
||||
tris = triangulatePath(path, tris)
|
||||
total := len(tris)
|
||||
for i := 12; i < total; i += 2 {
|
||||
x, y := tris[i], tris[i+1]
|
||||
tris[i], tris[i+1] = cv.ptToGL(x, y)
|
||||
}
|
||||
|
||||
gli.BufferData(gl_ARRAY_BUFFER, len(tris)*4, unsafe.Pointer(&tris[0]), gl_STREAM_DRAW)
|
||||
gli.VertexAttribPointer(sr.vertex, 2, gl_FLOAT, false, 0, nil)
|
||||
|
||||
gli.DrawArrays(gl_TRIANGLES, 0, 6)
|
||||
gli.StencilFunc(gl_ALWAYS, 0, 0xFF)
|
||||
gli.DrawArrays(gl_TRIANGLES, 6, int32(len(tris)/2-6))
|
||||
|
|
17
text.go
17
text.go
|
@ -8,6 +8,7 @@ import (
|
|||
|
||||
"github.com/golang/freetype"
|
||||
"github.com/golang/freetype/truetype"
|
||||
"github.com/tfriedel6/lm"
|
||||
"golang.org/x/image/math/fixed"
|
||||
)
|
||||
|
||||
|
@ -82,20 +83,20 @@ func (cv *Canvas) FillText(str string, x, y float32) {
|
|||
}
|
||||
}
|
||||
|
||||
gli.UseProgram(tr.id)
|
||||
gli.Uniform1i(tr.image, 0)
|
||||
|
||||
gli.BindBuffer(gl_ARRAY_BUFFER, buf)
|
||||
dx0, dy0 := cv.ptToGL(float32(bounds.Min.X), float32(bounds.Min.Y))
|
||||
dx1, dy1 := cv.ptToGL(float32(bounds.Min.X), float32(bounds.Max.Y))
|
||||
dx2, dy2 := cv.ptToGL(float32(bounds.Max.X), float32(bounds.Max.Y))
|
||||
dx3, dy3 := cv.ptToGL(float32(bounds.Max.X), float32(bounds.Min.Y))
|
||||
p0 := cv.tf(lm.Vec2{float32(bounds.Min.X), float32(bounds.Min.Y)})
|
||||
p1 := cv.tf(lm.Vec2{float32(bounds.Min.X), float32(bounds.Max.Y)})
|
||||
p2 := cv.tf(lm.Vec2{float32(bounds.Max.X), float32(bounds.Max.Y)})
|
||||
p3 := cv.tf(lm.Vec2{float32(bounds.Max.X), float32(bounds.Min.Y)})
|
||||
tw := float32(bounds.Max.X-bounds.Min.X) / cv.fw
|
||||
th := float32(bounds.Max.Y-bounds.Min.Y) / cv.fh
|
||||
data := [16]float32{dx0, dy0, dx1, dy1, dx2, dy2, dx3, dy3,
|
||||
data := [16]float32{p0[0], p0[1], p1[0], p1[1], p2[0], p2[1], p3[0], p3[1],
|
||||
0, 1, 0, 1 - th, tw, 1 - th, tw, 1}
|
||||
gli.BufferData(gl_ARRAY_BUFFER, len(data)*4, unsafe.Pointer(&data[0]), gl_STREAM_DRAW)
|
||||
|
||||
gli.UseProgram(tr.id)
|
||||
gli.Uniform1i(tr.image, 0)
|
||||
|
||||
gli.VertexAttribPointer(tr.vertex, 2, gl_FLOAT, false, 0, nil)
|
||||
gli.VertexAttribPointer(tr.texCoord, 2, gl_FLOAT, false, 0, gli.PtrOffset(8*4))
|
||||
gli.EnableVertexAttribArray(tr.vertex)
|
||||
|
|
Loading…
Reference in a new issue