From 395ef95009782c0d0793dfae98d0738c4d6b5ef0 Mon Sep 17 00:00:00 2001 From: Thomas Friedel Date: Mon, 29 Jan 2018 16:04:56 +0100 Subject: [PATCH] added transformations, translate, scale, rotate --- canvas.go | 31 +++++++++++++++++++++++++------ images.go | 6 ++++-- text.go | 14 ++++++++------ 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/canvas.go b/canvas.go index fa75a5d..93af9e0 100644 --- a/canvas.go +++ b/canvas.go @@ -63,13 +63,18 @@ func New(x, y, w, h int) *Canvas { stateStack: make([]drawState, 0, 20), } cv.state.stroke.lineWidth = 1 + cv.state.transform = lm.Mat3x3Identity() return cv } -func (cv *Canvas) xToGL(x float32) float32 { return x*2/cv.fw - 1 } -func (cv *Canvas) yToGL(y float32) float32 { return -y*2/cv.fh + 1 } -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) ptToGL(x, y float32) (fx, fy float32) { + return cv.vecToGL(lm.Vec2{x, y}) +} + +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 // 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] } +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 func (cv *Canvas) FillRect(x, y, w, h float32) { cv.activate() @@ -221,10 +238,12 @@ func (cv *Canvas) FillRect(x, y, w, h float32) { gli.UseProgram(sr.id) 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) - 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.VertexAttribPointer(sr.vertex, 2, gl_FLOAT, false, 0, nil) diff --git a/images.go b/images.go index ea49003..c747f67 100644 --- a/images.go +++ b/images.go @@ -159,7 +159,9 @@ func (cv *Canvas) DrawImage(img *Image, coords ...float32) { } 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) sy /= float32(img.h) sw /= float32(img.w) @@ -174,7 +176,7 @@ func (cv *Canvas) DrawImage(img *Image, coords ...float32) { gli.Uniform1i(tr.image, 0) 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} gli.BufferData(gl_ARRAY_BUFFER, len(data)*4, unsafe.Pointer(&data[0]), gl_STREAM_DRAW) diff --git a/text.go b/text.go index afd8337..838cfae 100644 --- a/text.go +++ b/text.go @@ -87,12 +87,14 @@ func (cv *Canvas) FillText(str string, x, y float32) { gli.Uniform1i(tr.image, 0) gli.BindBuffer(gl_ARRAY_BUFFER, buf) - x0 := float32(bounds.Min.X) / cv.fw - y0 := float32(bounds.Min.Y) / cv.fh - x1 := float32(bounds.Max.X) / cv.fw - y1 := float32(bounds.Max.Y) / cv.fh - 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, - 0, 1, 0, 1 - (y1 - y0), x1 - x0, 1 - (y1 - y0), x1 - x0, 1} + 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)) + 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, + 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.VertexAttribPointer(tr.vertex, 2, gl_FLOAT, false, 0, nil)