move OpenGL specific stuff to pixelgl (except for Picture)

This commit is contained in:
faiface 2017-02-22 20:44:38 +01:00
parent 3300f02d21
commit dbd90a0bcb
7 changed files with 98 additions and 50 deletions

View File

@ -1,10 +1,11 @@
package pixel package pixelgl
import ( import (
"image/color" "image/color"
"github.com/faiface/glhf" "github.com/faiface/glhf"
"github.com/faiface/mainthread" "github.com/faiface/mainthread"
"github.com/faiface/pixel"
"github.com/go-gl/mathgl/mgl32" "github.com/go-gl/mathgl/mgl32"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@ -19,9 +20,9 @@ type Canvas struct {
copyVs *glhf.VertexSlice copyVs *glhf.VertexSlice
smooth bool smooth bool
drawTd TrianglesDrawer drawTd pixel.TrianglesDrawer
pic *Picture pic *pixel.Picture
mat mgl32.Mat3 mat mgl32.Mat3
col mgl32.Vec4 col mgl32.Vec4
bnd mgl32.Vec4 bnd mgl32.Vec4
@ -56,13 +57,14 @@ func NewCanvas(width, height float64, smooth bool) *Canvas {
c.copyVs.End() c.copyVs.End()
}) })
c.drawTd = TrianglesDrawer{Triangles: &TrianglesData{ white := pixel.NRGBA{R: 1, G: 1, B: 1, A: 1}
{Position: V(-1, -1), Color: NRGBA{1, 1, 1, 1}, Texture: V(0, 0)}, c.drawTd = pixel.TrianglesDrawer{Triangles: &pixel.TrianglesData{
{Position: V(1, -1), Color: NRGBA{1, 1, 1, 1}, Texture: V(1, 0)}, {Position: pixel.V(-1, -1), Color: white, Texture: pixel.V(0, 0)},
{Position: V(1, 1), Color: NRGBA{1, 1, 1, 1}, Texture: V(1, 1)}, {Position: pixel.V(1, -1), Color: white, Texture: pixel.V(1, 0)},
{Position: V(-1, -1), Color: NRGBA{1, 1, 1, 1}, Texture: V(0, 0)}, {Position: pixel.V(1, 1), Color: white, Texture: pixel.V(1, 1)},
{Position: V(1, 1), Color: NRGBA{1, 1, 1, 1}, Texture: V(1, 1)}, {Position: pixel.V(-1, -1), Color: white, Texture: pixel.V(0, 0)},
{Position: V(-1, 1), Color: NRGBA{1, 1, 1, 1}, Texture: V(0, 1)}, {Position: pixel.V(1, 1), Color: white, Texture: pixel.V(1, 1)},
{Position: pixel.V(-1, 1), Color: white, Texture: pixel.V(0, 1)},
}} }}
c.pic = nil c.pic = nil
@ -74,7 +76,7 @@ func NewCanvas(width, height float64, smooth bool) *Canvas {
// SetSize resizes the Canvas. The original content will be stretched to fit the new size. // SetSize resizes the Canvas. The original content will be stretched to fit the new size.
func (c *Canvas) SetSize(width, height float64) { func (c *Canvas) SetSize(width, height float64) {
if V(width, height) == V(c.Size()) { if pixel.V(width, height) == pixel.V(c.Size()) {
return return
} }
mainthread.Call(func() { mainthread.Call(func() {
@ -107,15 +109,15 @@ func (c *Canvas) Size() (width, height float64) {
// Content returns a Picture that contains the content of this Canvas. The returned Picture changes // Content returns a Picture that contains the content of this Canvas. The returned Picture changes
// as you draw onto the Canvas, so there is no real need to call this method more than once (but it // as you draw onto the Canvas, so there is no real need to call this method more than once (but it
// might be beneficial to your code to do so). // might be beneficial to your code to do so).
func (c *Canvas) Content() *Picture { func (c *Canvas) Content() *pixel.Picture {
return PictureFromTexture(c.f.Texture()) return pixel.PictureFromTexture(c.f.Texture())
} }
// Clear fills the whole Canvas with one specified color. // Clear fills the whole Canvas with one specified color.
func (c *Canvas) Clear(col color.Color) { func (c *Canvas) Clear(col color.Color) {
mainthread.CallNonBlock(func() { mainthread.CallNonBlock(func() {
c.f.Begin() c.f.Begin()
col := NRGBAModel.Convert(col).(NRGBA) col := pixel.NRGBAModel.Convert(col).(pixel.NRGBA)
glhf.Clear(float32(col.R), float32(col.G), float32(col.B), float32(col.A)) glhf.Clear(float32(col.R), float32(col.G), float32(col.B), float32(col.A))
c.f.End() c.f.End()
}) })
@ -123,13 +125,13 @@ func (c *Canvas) Clear(col color.Color) {
// Draw draws the content of the Canvas onto another Target. If no transform is applied, the content // Draw draws the content of the Canvas onto another Target. If no transform is applied, the content
// is fully stretched to fit the Target. // is fully stretched to fit the Target.
func (c *Canvas) Draw(t Target) { func (c *Canvas) Draw(t pixel.Target) {
t.SetPicture(c.Content()) t.SetPicture(c.Content())
c.drawTd.Draw(t) c.drawTd.Draw(t)
} }
// MakeTriangles returns Triangles that draw onto this Canvas. // MakeTriangles returns Triangles that draw onto this Canvas.
func (c *Canvas) MakeTriangles(t Triangles) TargetTriangles { func (c *Canvas) MakeTriangles(t pixel.Triangles) pixel.TargetTriangles {
gt := NewGLTriangles(c.s, t).(*glTriangles) gt := NewGLTriangles(c.s, t).(*glTriangles)
return &canvasTriangles{ return &canvasTriangles{
c: c, c: c,
@ -140,10 +142,10 @@ func (c *Canvas) MakeTriangles(t Triangles) TargetTriangles {
// SetPicture sets a Picture that will be used in further draw operations. // SetPicture sets a Picture that will be used in further draw operations.
// //
// This does not set the Picture that this Canvas draws onto, don't confuse it. // This does not set the Picture that this Canvas draws onto, don't confuse it.
func (c *Canvas) SetPicture(p *Picture) { func (c *Canvas) SetPicture(p *pixel.Picture) {
if p != nil { if p != nil {
min := pictureBounds(p, V(0, 0)) min := pictureBounds(p, pixel.V(0, 0))
max := pictureBounds(p, V(1, 1)) max := pictureBounds(p, pixel.V(1, 1))
c.bnd = mgl32.Vec4{ c.bnd = mgl32.Vec4{
float32(min.X()), float32(min.Y()), float32(min.X()), float32(min.Y()),
float32(max.X()), float32(max.Y()), float32(max.X()), float32(max.Y()),
@ -153,16 +155,16 @@ func (c *Canvas) SetPicture(p *Picture) {
} }
// SetTransform sets the transformations used in further draw operations. // SetTransform sets the transformations used in further draw operations.
func (c *Canvas) SetTransform(t ...Transform) { func (c *Canvas) SetTransform(t ...pixel.Transform) {
c.mat = transformToMat(t...) c.mat = transformToMat(t...)
} }
// SetMaskColor sets the mask color used in further draw operations. // SetMaskColor sets the mask color used in further draw operations.
func (c *Canvas) SetMaskColor(col color.Color) { func (c *Canvas) SetMaskColor(col color.Color) {
if col == nil { if col == nil {
col = NRGBA{1, 1, 1, 1} col = pixel.NRGBA{R: 1, G: 1, B: 1, A: 1}
} }
nrgba := NRGBAModel.Convert(col).(NRGBA) nrgba := pixel.NRGBAModel.Convert(col).(pixel.NRGBA)
r := float32(nrgba.R) r := float32(nrgba.R)
g := float32(nrgba.G) g := float32(nrgba.G)
b := float32(nrgba.B) b := float32(nrgba.B)

View File

@ -1,10 +1,11 @@
package pixel package pixelgl
import ( import (
"fmt" "fmt"
"github.com/faiface/glhf" "github.com/faiface/glhf"
"github.com/faiface/mainthread" "github.com/faiface/mainthread"
"github.com/faiface/pixel"
) )
// NewGLTriangles returns OpenGL triangles implemented using glhf.VertexSlice. A few notes. // NewGLTriangles returns OpenGL triangles implemented using glhf.VertexSlice. A few notes.
@ -15,7 +16,7 @@ import (
// Draw method simply draws the underlying glhf.VertexSlice. It needs to be called in the main // Draw method simply draws the underlying glhf.VertexSlice. It needs to be called in the main
// thread manually. Also, you need to take care of additional Target initialization or setting of // thread manually. Also, you need to take care of additional Target initialization or setting of
// uniform attributes. // uniform attributes.
func NewGLTriangles(shader *glhf.Shader, t Triangles) TargetTriangles { func NewGLTriangles(shader *glhf.Shader, t pixel.Triangles) pixel.TargetTriangles {
var gt *glTriangles var gt *glTriangles
mainthread.Call(func() { mainthread.Call(func() {
gt = &glTriangles{ gt = &glTriangles{
@ -54,7 +55,7 @@ func (gt *glTriangles) SetLen(len int) {
} }
} }
func (gt *glTriangles) Slice(i, j int) Triangles { func (gt *glTriangles) Slice(i, j int) pixel.Triangles {
return &glTriangles{ return &glTriangles{
vs: gt.vs.Slice(i, j), vs: gt.vs.Slice(i, j),
data: gt.data[i*gt.vs.Stride() : j*gt.vs.Stride()], data: gt.data[i*gt.vs.Stride() : j*gt.vs.Stride()],
@ -62,7 +63,7 @@ func (gt *glTriangles) Slice(i, j int) Triangles {
} }
} }
func (gt *glTriangles) updateData(t Triangles) { func (gt *glTriangles) updateData(t pixel.Triangles) {
// glTriangles short path // glTriangles short path
if t, ok := t.(*glTriangles); ok { if t, ok := t.(*glTriangles); ok {
copy(gt.data, t.data) copy(gt.data, t.data)
@ -70,7 +71,7 @@ func (gt *glTriangles) updateData(t Triangles) {
} }
// TrianglesData short path // TrianglesData short path
if t, ok := t.(*TrianglesData); ok { if t, ok := t.(*pixel.TrianglesData); ok {
for i := 0; i < gt.Len(); i++ { for i := 0; i < gt.Len(); i++ {
var ( var (
px, py = (*t)[i].Position.XY() px, py = (*t)[i].Position.XY()
@ -89,14 +90,14 @@ func (gt *glTriangles) updateData(t Triangles) {
return return
} }
if t, ok := t.(TrianglesPosition); ok { if t, ok := t.(pixel.TrianglesPosition); ok {
for i := 0; i < gt.Len(); i++ { for i := 0; i < gt.Len(); i++ {
px, py := t.Position(i).XY() px, py := t.Position(i).XY()
gt.data[i*gt.vs.Stride()+0] = float32(px) gt.data[i*gt.vs.Stride()+0] = float32(px)
gt.data[i*gt.vs.Stride()+1] = float32(py) gt.data[i*gt.vs.Stride()+1] = float32(py)
} }
} }
if t, ok := t.(TrianglesColor); ok { if t, ok := t.(pixel.TrianglesColor); ok {
for i := 0; i < gt.Len(); i++ { for i := 0; i < gt.Len(); i++ {
col := t.Color(i) col := t.Color(i)
gt.data[i*gt.vs.Stride()+2] = float32(col.R) gt.data[i*gt.vs.Stride()+2] = float32(col.R)
@ -105,7 +106,7 @@ func (gt *glTriangles) updateData(t Triangles) {
gt.data[i*gt.vs.Stride()+5] = float32(col.A) gt.data[i*gt.vs.Stride()+5] = float32(col.A)
} }
} }
if t, ok := t.(TrianglesTexture); ok { if t, ok := t.(pixel.TrianglesTexture); ok {
for i := 0; i < gt.Len(); i++ { for i := 0; i < gt.Len(); i++ {
tx, ty := t.Texture(i).XY() tx, ty := t.Texture(i).XY()
gt.data[i*gt.vs.Stride()+6] = float32(tx) gt.data[i*gt.vs.Stride()+6] = float32(tx)
@ -125,7 +126,7 @@ func (gt *glTriangles) submitData() {
}) })
} }
func (gt *glTriangles) Update(t Triangles) { func (gt *glTriangles) Update(t pixel.Triangles) {
if gt.Len() != t.Len() { if gt.Len() != t.Len() {
panic(fmt.Errorf("%T.Update: invalid triangles len", gt)) panic(fmt.Errorf("%T.Update: invalid triangles len", gt))
} }
@ -133,7 +134,7 @@ func (gt *glTriangles) Update(t Triangles) {
gt.submitData() gt.submitData()
} }
func (gt *glTriangles) Copy() Triangles { func (gt *glTriangles) Copy() pixel.Triangles {
return NewGLTriangles(gt.shader, gt) return NewGLTriangles(gt.shader, gt)
} }
@ -143,18 +144,18 @@ func (gt *glTriangles) Draw() {
gt.vs.End() gt.vs.End()
} }
func (gt *glTriangles) Position(i int) Vec { func (gt *glTriangles) Position(i int) pixel.Vec {
px := gt.data[i*gt.vs.Stride()+0] px := gt.data[i*gt.vs.Stride()+0]
py := gt.data[i*gt.vs.Stride()+1] py := gt.data[i*gt.vs.Stride()+1]
return V(float64(px), float64(py)) return pixel.V(float64(px), float64(py))
} }
func (gt *glTriangles) Color(i int) NRGBA { func (gt *glTriangles) Color(i int) pixel.NRGBA {
r := gt.data[i*gt.vs.Stride()+2] r := gt.data[i*gt.vs.Stride()+2]
g := gt.data[i*gt.vs.Stride()+3] g := gt.data[i*gt.vs.Stride()+3]
b := gt.data[i*gt.vs.Stride()+4] b := gt.data[i*gt.vs.Stride()+4]
a := gt.data[i*gt.vs.Stride()+5] a := gt.data[i*gt.vs.Stride()+5]
return NRGBA{ return pixel.NRGBA{
R: float64(r), R: float64(r),
G: float64(g), G: float64(g),
B: float64(b), B: float64(b),
@ -162,8 +163,8 @@ func (gt *glTriangles) Color(i int) NRGBA {
} }
} }
func (gt *glTriangles) Texture(i int) Vec { func (gt *glTriangles) Texture(i int) pixel.Vec {
tx := gt.data[i*gt.vs.Stride()+6] tx := gt.data[i*gt.vs.Stride()+6]
ty := gt.data[i*gt.vs.Stride()+7] ty := gt.data[i*gt.vs.Stride()+7]
return V(float64(tx), float64(ty)) return pixel.V(float64(tx), float64(ty))
} }

View File

@ -1,7 +1,8 @@
package pixel package pixelgl
import ( import (
"github.com/faiface/mainthread" "github.com/faiface/mainthread"
"github.com/faiface/pixel"
"github.com/go-gl/glfw/v3.2/glfw" "github.com/go-gl/glfw/v3.2/glfw"
) )
@ -21,7 +22,7 @@ func (w *Window) JustReleased(button Button) bool {
} }
// MousePosition returns the current mouse position relative to the window. // MousePosition returns the current mouse position relative to the window.
func (w *Window) MousePosition() Vec { func (w *Window) MousePosition() pixel.Vec {
var x, y, width, height float64 var x, y, width, height float64
mainthread.Call(func() { mainthread.Call(func() {
x, y = w.window.GetCursorPos() x, y = w.window.GetCursorPos()
@ -33,11 +34,11 @@ func (w *Window) MousePosition() Vec {
x = (x - width/2) / (width / 2) x = (x - width/2) / (width / 2)
y = (height/2 - y) / (height / 2) y = (height/2 - y) / (height / 2)
return V(x, y) return pixel.V(x, y)
} }
// MouseScroll returns the scroll amount (in both axis) since the last call to Window.Update. // MouseScroll returns the scroll amount (in both axis) since the last call to Window.Update.
func (w *Window) MouseScroll() Vec { func (w *Window) MouseScroll() pixel.Vec {
return w.currInp.scroll return w.currInp.scroll
} }
@ -348,7 +349,7 @@ func (w *Window) initInput() {
}) })
w.window.SetScrollCallback(func(_ *glfw.Window, xoff, yoff float64) { w.window.SetScrollCallback(func(_ *glfw.Window, xoff, yoff float64) {
w.currInp.scroll += V(xoff, yoff) w.currInp.scroll += pixel.V(xoff, yoff)
}) })
}) })
} }

View File

@ -1,4 +1,4 @@
package pixel package pixelgl
import ( import (
"github.com/faiface/mainthread" "github.com/faiface/mainthread"

View File

@ -1,4 +1,4 @@
package pixel package pixelgl
import ( import (
"github.com/faiface/mainthread" "github.com/faiface/mainthread"

43
pixelgl/util.go Normal file
View File

@ -0,0 +1,43 @@
package pixelgl
import (
"github.com/faiface/pixel"
"github.com/go-gl/mathgl/mgl32"
)
func clamp(x, low, high float64) float64 {
if x < low {
return low
}
if x > high {
return high
}
return x
}
func lerp(x float64, a, b pixel.Vec) pixel.Vec {
return a.Scaled(1-x) + b.Scaled(x)
}
func lerp2d(x, a, b pixel.Vec) pixel.Vec {
return pixel.V(
lerp(x.X(), a, b).X(),
lerp(x.Y(), a, b).Y(),
)
}
func transformToMat(t ...pixel.Transform) mgl32.Mat3 {
mat := mgl32.Ident3()
for i := range t {
mat = mat.Mul3(t[i].Mat())
}
return mat
}
func pictureBounds(p *pixel.Picture, v pixel.Vec) pixel.Vec {
w, h := float64(p.Texture().Width()), float64(p.Texture().Height())
a := p.Bounds().Pos
b := p.Bounds().Pos + p.Bounds().Size
u := lerp2d(v, a, b)
return pixel.V(u.X()/w, u.Y()/h)
}

View File

@ -1,4 +1,4 @@
package pixel package pixelgl
import ( import (
"image/color" "image/color"
@ -7,6 +7,7 @@ import (
"github.com/faiface/glhf" "github.com/faiface/glhf"
"github.com/faiface/mainthread" "github.com/faiface/mainthread"
"github.com/faiface/pixel"
"github.com/go-gl/glfw/v3.2/glfw" "github.com/go-gl/glfw/v3.2/glfw"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@ -70,7 +71,7 @@ type Window struct {
prevInp, tempInp, currInp struct { prevInp, tempInp, currInp struct {
buttons [KeyLast + 1]bool buttons [KeyLast + 1]bool
scroll Vec scroll pixel.Vec
} }
} }
@ -368,19 +369,19 @@ func (w *Window) end() {
// Window. // Window.
// //
// Window supports TrianglesPosition, TrianglesColor and TrianglesTexture. // Window supports TrianglesPosition, TrianglesColor and TrianglesTexture.
func (w *Window) MakeTriangles(t Triangles) TargetTriangles { func (w *Window) MakeTriangles(t pixel.Triangles) pixel.TargetTriangles {
return w.canvas.MakeTriangles(t) return w.canvas.MakeTriangles(t)
} }
// SetPicture sets a Picture that will be used in subsequent drawings onto the Window. // SetPicture sets a Picture that will be used in subsequent drawings onto the Window.
func (w *Window) SetPicture(p *Picture) { func (w *Window) SetPicture(p *pixel.Picture) {
w.canvas.SetPicture(p) w.canvas.SetPicture(p)
} }
// SetTransform sets a global transformation matrix for the Window. // SetTransform sets a global transformation matrix for the Window.
// //
// Transforms are applied right-to-left. // Transforms are applied right-to-left.
func (w *Window) SetTransform(t ...Transform) { func (w *Window) SetTransform(t ...pixel.Transform) {
w.canvas.SetTransform(t...) w.canvas.SetTransform(t...)
} }