added transformations, translate, scale, rotate

This commit is contained in:
Thomas Friedel 2018-01-29 16:04:56 +01:00
parent 6480345a60
commit 395ef95009
3 changed files with 37 additions and 14 deletions

View file

@ -63,13 +63,18 @@ func New(x, y, w, h int) *Canvas {
stateStack: make([]drawState, 0, 20), stateStack: make([]drawState, 0, 20),
} }
cv.state.stroke.lineWidth = 1 cv.state.stroke.lineWidth = 1
cv.state.transform = lm.Mat3x3Identity()
return cv return cv
} }
func (cv *Canvas) xToGL(x float32) float32 { return x*2/cv.fw - 1 } func (cv *Canvas) ptToGL(x, y float32) (fx, fy float32) {
func (cv *Canvas) yToGL(y float32) float32 { return -y*2/cv.fh + 1 } return cv.vecToGL(lm.Vec2{x, y})
func (cv *Canvas) ptToGL(x, y float32) (fx, fy float32) { return x*2/cv.fw - 1, -y*2/cv.fh + 1 } }
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) vecToGL(v lm.Vec2) (fx, fy float32) {
v, _ = v.MulMat3x3(cv.state.transform)
return v[0]*2/cv.fw - 1, -v[1]*2/cv.fh + 1
}
// Activate makes the canvas active and sets the viewport. Only needs // Activate makes the canvas active and sets the viewport. Only needs
// to be called if any other GL code changes the viewport // to be called if any other GL code changes the viewport
@ -214,6 +219,18 @@ func (cv *Canvas) Restore() {
cv.stateStack = cv.stateStack[:l-1] cv.stateStack = cv.stateStack[:l-1]
} }
func (cv *Canvas) Scale(x, y float32) {
cv.state.transform = cv.state.transform.Mul(lm.Mat3x3Scale(lm.Vec2{x, y}))
}
func (cv *Canvas) Translate(x, y float32) {
cv.state.transform = cv.state.transform.Mul(lm.Mat3x3Translate(lm.Vec2{x, y}))
}
func (cv *Canvas) Rotate(angle float32) {
cv.state.transform = cv.state.transform.Mul(lm.Mat3x3Rotate(angle))
}
// FillRect fills a rectangle with the active color // FillRect fills a rectangle with the active color
func (cv *Canvas) FillRect(x, y, w, h float32) { func (cv *Canvas) FillRect(x, y, w, h float32) {
cv.activate() cv.activate()
@ -221,10 +238,12 @@ func (cv *Canvas) FillRect(x, y, w, h float32) {
gli.UseProgram(sr.id) gli.UseProgram(sr.id)
x0f, y0f := cv.ptToGL(x, y) x0f, y0f := cv.ptToGL(x, y)
x1f, y1f := cv.ptToGL(x+w, y+h) x1f, y1f := cv.ptToGL(x, y+h)
x2f, y2f := cv.ptToGL(x+w, y+h)
x3f, y3f := cv.ptToGL(x+w, y)
gli.BindBuffer(gl_ARRAY_BUFFER, buf) gli.BindBuffer(gl_ARRAY_BUFFER, buf)
data := [8]float32{x0f, y0f, x0f, y1f, x1f, y1f, x1f, y0f} 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.BufferData(gl_ARRAY_BUFFER, len(data)*4, unsafe.Pointer(&data[0]), gl_STREAM_DRAW)
gli.VertexAttribPointer(sr.vertex, 2, gl_FLOAT, false, 0, nil) gli.VertexAttribPointer(sr.vertex, 2, gl_FLOAT, false, 0, nil)

View file

@ -159,7 +159,9 @@ func (cv *Canvas) DrawImage(img *Image, coords ...float32) {
} }
dx0, dy0 := cv.ptToGL(dx, dy) dx0, dy0 := cv.ptToGL(dx, dy)
dx1, dy1 := cv.ptToGL(dx+dw, dy+dh) dx1, dy1 := cv.ptToGL(dx, dy+dh)
dx2, dy2 := cv.ptToGL(dx+dw, dy+dh)
dx3, dy3 := cv.ptToGL(dx+dw, dy)
sx /= float32(img.w) sx /= float32(img.w)
sy /= float32(img.h) sy /= float32(img.h)
sw /= float32(img.w) sw /= float32(img.w)
@ -174,7 +176,7 @@ func (cv *Canvas) DrawImage(img *Image, coords ...float32) {
gli.Uniform1i(tr.image, 0) gli.Uniform1i(tr.image, 0)
gli.BindBuffer(gl_ARRAY_BUFFER, buf) gli.BindBuffer(gl_ARRAY_BUFFER, buf)
data := [16]float32{dx0, dy0, dx0, dy1, dx1, dy1, dx1, dy0, data := [16]float32{dx0, dy0, dx1, dy1, dx2, dy2, dx3, dy3,
sx, sy, sx, sy + sh, sx + sw, sy + sh, sx + sw, sy} 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.BufferData(gl_ARRAY_BUFFER, len(data)*4, unsafe.Pointer(&data[0]), gl_STREAM_DRAW)

14
text.go
View file

@ -87,12 +87,14 @@ func (cv *Canvas) FillText(str string, x, y float32) {
gli.Uniform1i(tr.image, 0) gli.Uniform1i(tr.image, 0)
gli.BindBuffer(gl_ARRAY_BUFFER, buf) gli.BindBuffer(gl_ARRAY_BUFFER, buf)
x0 := float32(bounds.Min.X) / cv.fw dx0, dy0 := cv.ptToGL(float32(bounds.Min.X), float32(bounds.Min.Y))
y0 := float32(bounds.Min.Y) / cv.fh dx1, dy1 := cv.ptToGL(float32(bounds.Min.X), float32(bounds.Max.Y))
x1 := float32(bounds.Max.X) / cv.fw dx2, dy2 := cv.ptToGL(float32(bounds.Max.X), float32(bounds.Max.Y))
y1 := float32(bounds.Max.Y) / cv.fh dx3, dy3 := cv.ptToGL(float32(bounds.Max.X), float32(bounds.Min.Y))
data := [16]float32{x0*2 - 1, -y0*2 + 1, x0*2 - 1, -y1*2 + 1, x1*2 - 1, -y1*2 + 1, x1*2 - 1, -y0*2 + 1, tw := float32(bounds.Max.X-bounds.Min.X) / cv.fw
0, 1, 0, 1 - (y1 - y0), x1 - x0, 1 - (y1 - y0), x1 - x0, 1} th := float32(bounds.Max.Y-bounds.Min.Y) / cv.fh
data := [16]float32{dx0, dy0, dx1, dy1, dx2, dy2, dx3, dy3,
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.BufferData(gl_ARRAY_BUFFER, len(data)*4, unsafe.Pointer(&data[0]), gl_STREAM_DRAW)
gli.VertexAttribPointer(tr.vertex, 2, gl_FLOAT, false, 0, nil) gli.VertexAttribPointer(tr.vertex, 2, gl_FLOAT, false, 0, nil)