adopt github.com/faiface/mainthread package + frame prototype
This commit is contained in:
parent
de21a40184
commit
7a7b2f2588
8
input.go
8
input.go
|
@ -1,7 +1,7 @@
|
|||
package pixel
|
||||
|
||||
import (
|
||||
"github.com/faiface/pixel/pixelgl"
|
||||
"github.com/faiface/mainthread"
|
||||
"github.com/go-gl/glfw/v3.2/glfw"
|
||||
)
|
||||
|
||||
|
@ -23,7 +23,7 @@ func (w *Window) JustReleased(button Button) bool {
|
|||
// MousePosition returns the current mouse position relative to the window.
|
||||
func (w *Window) MousePosition() Vec {
|
||||
var x, y, width, height float64
|
||||
pixelgl.Do(func() {
|
||||
mainthread.Call(func() {
|
||||
x, y = w.window.GetCursorPos()
|
||||
wi, hi := w.window.GetSize()
|
||||
width, height = float64(wi), float64(hi)
|
||||
|
@ -187,7 +187,7 @@ const (
|
|||
)
|
||||
|
||||
func (w *Window) initInput() {
|
||||
pixelgl.Do(func() {
|
||||
mainthread.Call(func() {
|
||||
w.window.SetMouseButtonCallback(func(_ *glfw.Window, button glfw.MouseButton, action glfw.Action, mod glfw.ModifierKey) {
|
||||
switch action {
|
||||
case glfw.Press:
|
||||
|
@ -220,7 +220,7 @@ func (w *Window) updateInput() {
|
|||
w.currInp.scroll -= w.tempInp.scroll
|
||||
|
||||
// get events (usually calls callbacks, but callbacks can be called outside too)
|
||||
pixelgl.Do(func() {
|
||||
mainthread.Call(func() {
|
||||
glfw.PollEvents()
|
||||
})
|
||||
|
||||
|
|
18
monitor.go
18
monitor.go
|
@ -1,7 +1,7 @@
|
|||
package pixel
|
||||
|
||||
import (
|
||||
"github.com/faiface/pixel/pixelgl"
|
||||
"github.com/faiface/mainthread"
|
||||
"github.com/go-gl/glfw/v3.2/glfw"
|
||||
)
|
||||
|
||||
|
@ -12,7 +12,7 @@ type Monitor struct {
|
|||
|
||||
// PrimaryMonitor returns the main monitor (usually the one with the taskbar and stuff).
|
||||
func PrimaryMonitor() *Monitor {
|
||||
monitor := pixelgl.DoVal(func() interface{} {
|
||||
monitor := mainthread.CallVal(func() interface{} {
|
||||
return glfw.GetPrimaryMonitor()
|
||||
}).(*glfw.Monitor)
|
||||
return &Monitor{
|
||||
|
@ -23,7 +23,7 @@ func PrimaryMonitor() *Monitor {
|
|||
// Monitors returns a slice of all currently available monitors.
|
||||
func Monitors() []*Monitor {
|
||||
var monitors []*Monitor
|
||||
pixelgl.Do(func() {
|
||||
mainthread.Call(func() {
|
||||
for _, monitor := range glfw.GetMonitors() {
|
||||
monitors = append(monitors, &Monitor{monitor: monitor})
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ func Monitors() []*Monitor {
|
|||
|
||||
// Name returns a human-readable name of a monitor.
|
||||
func (m *Monitor) Name() string {
|
||||
name := pixelgl.DoVal(func() interface{} {
|
||||
name := mainthread.CallVal(func() interface{} {
|
||||
return m.monitor.GetName()
|
||||
}).(string)
|
||||
return name
|
||||
|
@ -42,7 +42,7 @@ func (m *Monitor) Name() string {
|
|||
// PhysicalSize returns the size of the display area of a monitor in millimeters.
|
||||
func (m *Monitor) PhysicalSize() (width, height float64) {
|
||||
var wi, hi int
|
||||
pixelgl.Do(func() {
|
||||
mainthread.Call(func() {
|
||||
wi, hi = m.monitor.GetPhysicalSize()
|
||||
})
|
||||
width = float64(wi)
|
||||
|
@ -53,7 +53,7 @@ func (m *Monitor) PhysicalSize() (width, height float64) {
|
|||
// Position returns the position of the upper-left corner of a monitor in screen coordinates.
|
||||
func (m *Monitor) Position() (x, y float64) {
|
||||
var xi, yi int
|
||||
pixelgl.Do(func() {
|
||||
mainthread.Call(func() {
|
||||
xi, yi = m.monitor.GetPos()
|
||||
})
|
||||
x = float64(xi)
|
||||
|
@ -63,7 +63,7 @@ func (m *Monitor) Position() (x, y float64) {
|
|||
|
||||
// Size returns the resolution of a monitor in pixels.
|
||||
func (m *Monitor) Size() (width, height float64) {
|
||||
mode := pixelgl.DoVal(func() interface{} {
|
||||
mode := mainthread.CallVal(func() interface{} {
|
||||
return m.monitor.GetVideoMode()
|
||||
}).(*glfw.VidMode)
|
||||
width = float64(mode.Width)
|
||||
|
@ -73,7 +73,7 @@ func (m *Monitor) Size() (width, height float64) {
|
|||
|
||||
// BitDepth returns the number of bits per color of a monitor.
|
||||
func (m *Monitor) BitDepth() (red, green, blue int) {
|
||||
mode := pixelgl.DoVal(func() interface{} {
|
||||
mode := mainthread.CallVal(func() interface{} {
|
||||
return m.monitor.GetVideoMode()
|
||||
}).(*glfw.VidMode)
|
||||
red = mode.RedBits
|
||||
|
@ -84,7 +84,7 @@ func (m *Monitor) BitDepth() (red, green, blue int) {
|
|||
|
||||
// RefreshRate returns the refresh frequency of a monitor in Hz (refreshes/second).
|
||||
func (m *Monitor) RefreshRate() (rate float64) {
|
||||
mode := pixelgl.DoVal(func() interface{} {
|
||||
mode := mainthread.CallVal(func() interface{} {
|
||||
return m.monitor.GetVideoMode()
|
||||
}).(*glfw.VidMode)
|
||||
rate = float64(mode.RefreshRate)
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"image"
|
||||
"image/draw"
|
||||
|
||||
"github.com/faiface/mainthread"
|
||||
"github.com/faiface/pixel/pixelgl"
|
||||
)
|
||||
|
||||
|
@ -29,7 +30,7 @@ func NewPicture(img image.Image, smooth bool) *Picture {
|
|||
}
|
||||
|
||||
var texture *pixelgl.Texture
|
||||
pixelgl.Do(func() {
|
||||
mainthread.Call(func() {
|
||||
texture = pixelgl.NewTexture(
|
||||
img.Bounds().Dx(),
|
||||
img.Bounds().Dy(),
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
package pixelgl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
|
||||
"github.com/faiface/mainthread"
|
||||
"github.com/go-gl/gl/v3.3-core/gl"
|
||||
)
|
||||
|
||||
type Frame struct {
|
||||
fb binder
|
||||
tex *Texture
|
||||
width, height int
|
||||
}
|
||||
|
||||
func NewFrame(width, height int, smooth bool) *Frame {
|
||||
f := &Frame{
|
||||
fb: binder{
|
||||
restoreLoc: gl.FRAMEBUFFER_BINDING,
|
||||
bindFunc: func(obj uint32) {
|
||||
gl.BindFramebuffer(gl.FRAMEBUFFER, obj)
|
||||
},
|
||||
},
|
||||
width: width,
|
||||
height: height,
|
||||
}
|
||||
|
||||
gl.GenFramebuffers(1, &f.fb.obj)
|
||||
fmt.Println(f.fb.obj)
|
||||
|
||||
f.tex = NewTexture(width, height, smooth, make([]uint8, width*height*4))
|
||||
|
||||
f.fb.bind()
|
||||
gl.FramebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, f.tex.tex.obj, 0)
|
||||
f.fb.restore()
|
||||
|
||||
runtime.SetFinalizer(f, (*Frame).delete)
|
||||
|
||||
return f
|
||||
}
|
||||
|
||||
func (f *Frame) delete() {
|
||||
mainthread.CallNonBlock(func() {
|
||||
gl.DeleteFramebuffers(1, &f.fb.obj)
|
||||
})
|
||||
}
|
||||
|
||||
func (f *Frame) Width() int {
|
||||
return f.width
|
||||
}
|
||||
|
||||
func (f *Frame) Height() int {
|
||||
return f.height
|
||||
}
|
||||
|
||||
func (f *Frame) Begin() {
|
||||
f.fb.bind()
|
||||
}
|
||||
|
||||
func (f *Frame) End() {
|
||||
f.fb.restore()
|
||||
}
|
||||
|
||||
func (f *Frame) Texture() *Texture {
|
||||
return f.tex
|
||||
}
|
|
@ -2,6 +2,20 @@ package pixelgl
|
|||
|
||||
import "github.com/go-gl/gl/v3.3-core/gl"
|
||||
|
||||
// Init initializes OpenGL by loading the function pointers from the active OpenGL context.
|
||||
// This function must be manually run inside the main thread (Do, DoErr, DoVal, etc.).
|
||||
//
|
||||
// It must be called under the presence of an active OpenGL context, e.g., always after calling
|
||||
// window.MakeContextCurrent(). Also, always call this function when switching contexts.
|
||||
func Init() {
|
||||
err := gl.Init()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
gl.Enable(gl.BLEND)
|
||||
gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
|
||||
}
|
||||
|
||||
// Clear clears the current framebuffer or window with the given color.
|
||||
func Clear(r, g, b, a float32) {
|
||||
gl.ClearColor(r, g, b, a)
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"fmt"
|
||||
"runtime"
|
||||
|
||||
"github.com/faiface/mainthread"
|
||||
"github.com/go-gl/gl/v3.3-core/gl"
|
||||
"github.com/go-gl/mathgl/mgl32"
|
||||
)
|
||||
|
@ -110,7 +111,7 @@ func NewShader(vertexFmt, uniformFmt AttrFormat, vertexShader, fragmentShader st
|
|||
}
|
||||
|
||||
func (s *Shader) delete() {
|
||||
DoNoBlock(func() {
|
||||
mainthread.CallNonBlock(func() {
|
||||
gl.DeleteProgram(s.program.obj)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package pixelgl
|
|||
import (
|
||||
"runtime"
|
||||
|
||||
"github.com/faiface/mainthread"
|
||||
"github.com/go-gl/gl/v3.3-core/gl"
|
||||
"github.com/go-gl/mathgl/mgl32"
|
||||
)
|
||||
|
@ -67,7 +68,7 @@ func NewTexture(width, height int, smooth bool, pixels []uint8) *Texture {
|
|||
}
|
||||
|
||||
func (t *Texture) delete() {
|
||||
DoNoBlock(func() {
|
||||
mainthread.CallNonBlock(func() {
|
||||
gl.DeleteTextures(1, &t.tex.obj)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,102 +0,0 @@
|
|||
package pixelgl
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
|
||||
"github.com/go-gl/gl/v3.3-core/gl"
|
||||
)
|
||||
|
||||
// Due to the limitations of OpenGL and operating systems, all OpenGL related calls must be
|
||||
// done from the main thread.
|
||||
|
||||
var (
|
||||
callQueue = make(chan func(), 8)
|
||||
respChan = make(chan interface{}, 4)
|
||||
)
|
||||
|
||||
func init() {
|
||||
runtime.LockOSThread()
|
||||
}
|
||||
|
||||
// Run is essentialy the "main" function of the pixelgl package. Run this function from the
|
||||
// main function (because that's guaranteed to run in the main thread).
|
||||
//
|
||||
// This function reserves the main thread for the OpenGL stuff and runs a supplied run function
|
||||
// in a separate goroutine.
|
||||
//
|
||||
// Run returns when the provided run function finishes.
|
||||
func Run(run func()) {
|
||||
done := make(chan struct{})
|
||||
|
||||
go func() {
|
||||
run()
|
||||
close(done)
|
||||
}()
|
||||
|
||||
loop:
|
||||
for {
|
||||
select {
|
||||
case f := <-callQueue:
|
||||
f()
|
||||
case <-done:
|
||||
break loop
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Init initializes OpenGL by loading the function pointers from the active OpenGL context.
|
||||
// This function must be manually run inside the main thread (Do, DoErr, DoVal, etc.).
|
||||
//
|
||||
// It must be called under the presence of an active OpenGL context, e.g., always after calling
|
||||
// window.MakeContextCurrent(). Also, always call this function when switching contexts.
|
||||
func Init() {
|
||||
err := gl.Init()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
gl.Enable(gl.BLEND)
|
||||
gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
|
||||
}
|
||||
|
||||
// DoNoBlock executes a function inside the main OpenGL thread. DoNoBlock does not wait until
|
||||
// the function finishes.
|
||||
func DoNoBlock(f func()) {
|
||||
callQueue <- f
|
||||
}
|
||||
|
||||
// Do executes a function inside the main OpenGL thread. Do blocks until the function finishes.
|
||||
//
|
||||
// All OpenGL calls must be done in the dedicated thread.
|
||||
func Do(f func()) {
|
||||
callQueue <- func() {
|
||||
f()
|
||||
respChan <- struct{}{}
|
||||
}
|
||||
<-respChan
|
||||
}
|
||||
|
||||
// DoErr executes a function inside the main OpenGL thread and returns an error to the called.
|
||||
// DoErr blocks until the function finishes.
|
||||
//
|
||||
// All OpenGL calls must be done in the dedicated thread.
|
||||
func DoErr(f func() error) error {
|
||||
callQueue <- func() {
|
||||
respChan <- f()
|
||||
}
|
||||
err := <-respChan
|
||||
if err != nil {
|
||||
return err.(error)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DoVal executes a function inside the main OpenGL thread and returns a value to the caller.
|
||||
// DoVal blocks until the function finishes.
|
||||
//
|
||||
// All OpenGL calls must be done in the main thread.
|
||||
func DoVal(f func() interface{}) interface{} {
|
||||
callQueue <- func() {
|
||||
respChan <- f()
|
||||
}
|
||||
return <-respChan
|
||||
}
|
|
@ -4,6 +4,7 @@ import (
|
|||
"fmt"
|
||||
"runtime"
|
||||
|
||||
"github.com/faiface/mainthread"
|
||||
"github.com/go-gl/gl/v3.3-core/gl"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
@ -252,7 +253,7 @@ func newVertexArray(shader *Shader, cap int) *vertexArray {
|
|||
}
|
||||
|
||||
func (va *vertexArray) delete() {
|
||||
DoNoBlock(func() {
|
||||
mainthread.CallNonBlock(func() {
|
||||
gl.DeleteVertexArrays(1, &va.vao.obj)
|
||||
gl.DeleteBuffers(1, &va.vbo.obj)
|
||||
})
|
||||
|
|
4
run.go
4
run.go
|
@ -1,7 +1,7 @@
|
|||
package pixel
|
||||
|
||||
import (
|
||||
"github.com/faiface/pixel/pixelgl"
|
||||
"github.com/faiface/mainthread"
|
||||
"github.com/go-gl/glfw/v3.2/glfw"
|
||||
)
|
||||
|
||||
|
@ -28,5 +28,5 @@ import (
|
|||
// function.
|
||||
func Run(run func()) {
|
||||
defer glfw.Terminate()
|
||||
pixelgl.Run(run)
|
||||
mainthread.Run(run)
|
||||
}
|
||||
|
|
64
window.go
64
window.go
|
@ -5,6 +5,7 @@ import (
|
|||
|
||||
"runtime"
|
||||
|
||||
"github.com/faiface/mainthread"
|
||||
"github.com/faiface/pixel/pixelgl"
|
||||
"github.com/go-gl/glfw/v3.2/glfw"
|
||||
"github.com/go-gl/mathgl/mgl32"
|
||||
|
@ -79,6 +80,9 @@ type Window struct {
|
|||
buttons [KeyLast + 1]bool
|
||||
scroll Vec
|
||||
}
|
||||
|
||||
//DEBUG
|
||||
Frame *pixelgl.Frame
|
||||
}
|
||||
|
||||
var currentWindow *Window
|
||||
|
@ -94,7 +98,7 @@ func NewWindow(config WindowConfig) (*Window, error) {
|
|||
|
||||
w := &Window{config: config}
|
||||
|
||||
err := pixelgl.DoErr(func() error {
|
||||
err := mainthread.CallErr(func() error {
|
||||
err := glfw.Init()
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -127,7 +131,7 @@ func NewWindow(config WindowConfig) (*Window, error) {
|
|||
return nil, errors.Wrap(err, "creating window failed")
|
||||
}
|
||||
|
||||
pixelgl.Do(func() {
|
||||
mainthread.Call(func() {
|
||||
w.begin()
|
||||
w.end()
|
||||
|
||||
|
@ -160,25 +164,24 @@ func NewWindow(config WindowConfig) (*Window, error) {
|
|||
|
||||
// Destroy destroys a window. The window can't be used any further.
|
||||
func (w *Window) Destroy() {
|
||||
pixelgl.Do(func() {
|
||||
mainthread.Call(func() {
|
||||
w.window.Destroy()
|
||||
})
|
||||
}
|
||||
|
||||
// Clear clears the window with a color.
|
||||
func (w *Window) Clear(c color.Color) {
|
||||
pixelgl.DoNoBlock(func() {
|
||||
mainthread.CallNonBlock(func() {
|
||||
w.begin()
|
||||
defer w.end()
|
||||
|
||||
c := NRGBAModel.Convert(c).(NRGBA)
|
||||
pixelgl.Clear(float32(c.R), float32(c.G), float32(c.B), float32(c.A))
|
||||
w.end()
|
||||
})
|
||||
}
|
||||
|
||||
// Update swaps buffers and polls events.
|
||||
func (w *Window) Update() {
|
||||
pixelgl.Do(func() {
|
||||
mainthread.Call(func() {
|
||||
w.begin()
|
||||
if w.config.VSync {
|
||||
glfw.SwapInterval(1)
|
||||
|
@ -197,7 +200,7 @@ func (w *Window) Update() {
|
|||
// This is usefull when overriding the user's attempt to close a window, or just to close a
|
||||
// window from within a program.
|
||||
func (w *Window) SetClosed(closed bool) {
|
||||
pixelgl.Do(func() {
|
||||
mainthread.Call(func() {
|
||||
w.window.SetShouldClose(closed)
|
||||
})
|
||||
}
|
||||
|
@ -206,14 +209,14 @@ func (w *Window) SetClosed(closed bool) {
|
|||
//
|
||||
// The closed flag is automatically set when a user attempts to close a window.
|
||||
func (w *Window) Closed() bool {
|
||||
return pixelgl.DoVal(func() interface{} {
|
||||
return mainthread.CallVal(func() interface{} {
|
||||
return w.window.ShouldClose()
|
||||
}).(bool)
|
||||
}
|
||||
|
||||
// SetTitle changes the title of a window.
|
||||
func (w *Window) SetTitle(title string) {
|
||||
pixelgl.Do(func() {
|
||||
mainthread.Call(func() {
|
||||
w.window.SetTitle(title)
|
||||
})
|
||||
}
|
||||
|
@ -221,14 +224,14 @@ func (w *Window) SetTitle(title string) {
|
|||
// SetSize resizes a window to the specified size in pixels. In case of a fullscreen window,
|
||||
// it changes the resolution of that window.
|
||||
func (w *Window) SetSize(width, height float64) {
|
||||
pixelgl.Do(func() {
|
||||
mainthread.Call(func() {
|
||||
w.window.SetSize(int(width), int(height))
|
||||
})
|
||||
}
|
||||
|
||||
// Size returns the size of the client area of a window (the part you can draw on).
|
||||
func (w *Window) Size() (width, height float64) {
|
||||
pixelgl.Do(func() {
|
||||
mainthread.Call(func() {
|
||||
wi, hi := w.window.GetSize()
|
||||
width = float64(wi)
|
||||
height = float64(hi)
|
||||
|
@ -238,14 +241,14 @@ func (w *Window) Size() (width, height float64) {
|
|||
|
||||
// Show makes a window visible if it was hidden.
|
||||
func (w *Window) Show() {
|
||||
pixelgl.Do(func() {
|
||||
mainthread.Call(func() {
|
||||
w.window.Show()
|
||||
})
|
||||
}
|
||||
|
||||
// Hide hides a window if it was visible.
|
||||
func (w *Window) Hide() {
|
||||
pixelgl.Do(func() {
|
||||
mainthread.Call(func() {
|
||||
w.window.Hide()
|
||||
})
|
||||
}
|
||||
|
@ -259,7 +262,7 @@ func (w *Window) Hide() {
|
|||
func (w *Window) SetFullscreen(monitor *Monitor) {
|
||||
if w.Monitor() != monitor {
|
||||
if monitor == nil {
|
||||
pixelgl.Do(func() {
|
||||
mainthread.Call(func() {
|
||||
w.window.SetMonitor(
|
||||
nil,
|
||||
w.restore.xpos,
|
||||
|
@ -270,7 +273,7 @@ func (w *Window) SetFullscreen(monitor *Monitor) {
|
|||
)
|
||||
})
|
||||
} else {
|
||||
pixelgl.Do(func() {
|
||||
mainthread.Call(func() {
|
||||
w.restore.xpos, w.restore.ypos = w.window.GetPos()
|
||||
w.restore.width, w.restore.height = w.window.GetSize()
|
||||
|
||||
|
@ -297,7 +300,7 @@ func (w *Window) IsFullscreen() bool {
|
|||
// Monitor returns a monitor a fullscreen window is on. If the window is not fullscreen, this
|
||||
// function returns nil.
|
||||
func (w *Window) Monitor() *Monitor {
|
||||
monitor := pixelgl.DoVal(func() interface{} {
|
||||
monitor := mainthread.CallVal(func() interface{} {
|
||||
return w.window.GetMonitor()
|
||||
}).(*glfw.Monitor)
|
||||
if monitor == nil {
|
||||
|
@ -310,28 +313,28 @@ func (w *Window) Monitor() *Monitor {
|
|||
|
||||
// Focus brings a window to the front and sets input focus.
|
||||
func (w *Window) Focus() {
|
||||
pixelgl.Do(func() {
|
||||
mainthread.Call(func() {
|
||||
w.window.Focus()
|
||||
})
|
||||
}
|
||||
|
||||
// Focused returns true if a window has input focus.
|
||||
func (w *Window) Focused() bool {
|
||||
return pixelgl.DoVal(func() interface{} {
|
||||
return mainthread.CallVal(func() interface{} {
|
||||
return w.window.GetAttrib(glfw.Focused) == glfw.True
|
||||
}).(bool)
|
||||
}
|
||||
|
||||
// Maximize puts a windowed window to a maximized state.
|
||||
func (w *Window) Maximize() {
|
||||
pixelgl.Do(func() {
|
||||
mainthread.Call(func() {
|
||||
w.window.Maximize()
|
||||
})
|
||||
}
|
||||
|
||||
// Restore restores a windowed window from a maximized state.
|
||||
func (w *Window) Restore() {
|
||||
pixelgl.Do(func() {
|
||||
mainthread.Call(func() {
|
||||
w.window.Restore()
|
||||
})
|
||||
}
|
||||
|
@ -346,11 +349,19 @@ func (w *Window) begin() {
|
|||
if w.shader != nil {
|
||||
w.shader.Begin()
|
||||
}
|
||||
pixelgl.Viewport(0, 0, int32(w.width), int32(w.height))
|
||||
if w.Frame != nil {
|
||||
w.Frame.Begin()
|
||||
pixelgl.Viewport(0, 0, int32(w.Frame.Width()), int32(w.Frame.Height()))
|
||||
} else {
|
||||
pixelgl.Viewport(0, 0, int32(w.width), int32(w.height))
|
||||
}
|
||||
}
|
||||
|
||||
// Note: must be called inside the main thread.
|
||||
func (w *Window) end() {
|
||||
if w.Frame != nil {
|
||||
w.Frame.End()
|
||||
}
|
||||
if w.shader != nil {
|
||||
w.shader.End()
|
||||
}
|
||||
|
@ -373,7 +384,7 @@ func (wt *windowTriangles) Draw() {
|
|||
col := wt.w.col
|
||||
bnd := wt.w.bnd
|
||||
|
||||
pixelgl.DoNoBlock(func() {
|
||||
mainthread.CallNonBlock(func() {
|
||||
wt.w.begin()
|
||||
|
||||
wt.w.shader.SetUniformAttr(transformMat3, mat)
|
||||
|
@ -438,7 +449,7 @@ func (wt *windowTriangles) updateData(offset int, t Triangles) {
|
|||
|
||||
func (wt *windowTriangles) submitData() {
|
||||
data := wt.data // avoid race condition
|
||||
pixelgl.DoNoBlock(func() {
|
||||
mainthread.CallNonBlock(func() {
|
||||
wt.vs.Begin()
|
||||
dataLen := len(data) / wt.vs.Stride()
|
||||
if dataLen > wt.vs.Len() {
|
||||
|
@ -603,12 +614,11 @@ void main() {
|
|||
vec2 boundsMin = bounds.xy;
|
||||
vec2 boundsMax = bounds.zw;
|
||||
|
||||
float tx = boundsMin.x * (1 - Texture.x) + boundsMax.x * Texture.x;
|
||||
float ty = boundsMin.y * (1 - Texture.y) + boundsMax.y * Texture.y;
|
||||
|
||||
if (Texture == vec2(-1, -1)) {
|
||||
color = maskColor * Color;
|
||||
} else {
|
||||
float tx = boundsMin.x * (1 - Texture.x) + boundsMax.x * Texture.x;
|
||||
float ty = boundsMin.y * (1 - Texture.y) + boundsMax.y * Texture.y;
|
||||
color = maskColor * Color * texture(tex, vec2(tx, 1 - ty));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue