changed the way window scaling is done
to support high DPI scaling, use the FramebufferSize functions in glfwcanvas and sdlcanvas to determine the canvas size
This commit is contained in:
parent
259bb9e598
commit
a80e3778fd
3 changed files with 34 additions and 47 deletions
|
@ -33,6 +33,20 @@ func main() {
|
|||
cv.SetFillStyle("#000")
|
||||
cv.FillRect(0, 0, w, h)
|
||||
|
||||
// Estimated size used for scaling
|
||||
const (
|
||||
contentWidth = 1000
|
||||
contentHeight = 350
|
||||
)
|
||||
|
||||
// Calculate scaling
|
||||
sx := w / contentWidth
|
||||
sy := h / contentHeight
|
||||
scale := math.Min(sx, sy)
|
||||
cv.Save()
|
||||
defer cv.Restore()
|
||||
cv.Scale(scale, scale)
|
||||
|
||||
// Draw lines with different colors and line thickness
|
||||
for x := 1.0; x < 10.5; x += 1.0 {
|
||||
cv.SetStrokeStyle(int(x*25), 255, 255)
|
||||
|
|
|
@ -33,8 +33,6 @@ type Window struct {
|
|||
KeyUp func(scancode int, rn rune, name string)
|
||||
KeyChar func(rn rune)
|
||||
SizeChange func(w, h int)
|
||||
scalex float64
|
||||
scaley float64
|
||||
}
|
||||
|
||||
// CreateWindow creates a window using SDL and initializes the OpenGL context
|
||||
|
@ -79,8 +77,6 @@ func CreateWindow(w, h int, title string) (*Window, *canvas.Canvas, error) {
|
|||
wnd := &Window{
|
||||
Window: window,
|
||||
canvas: cv,
|
||||
scalex: float64(fbw) / float64(w),
|
||||
scaley: float64(fbh) / float64(h),
|
||||
}
|
||||
|
||||
var mx, my int
|
||||
|
@ -93,7 +89,7 @@ func CreateWindow(w, h int, title string) (*Window, *canvas.Canvas, error) {
|
|||
}
|
||||
})
|
||||
window.SetCursorPosCallback(func(w *glfw.Window, xpos, ypos float64) {
|
||||
mx, my = int(math.Round(xpos*wnd.scalex)), int(math.Round(ypos*wnd.scaley))
|
||||
mx, my = int(math.Round(xpos)), int(math.Round(ypos))
|
||||
if wnd.MouseMove != nil {
|
||||
wnd.MouseMove(mx, my)
|
||||
}
|
||||
|
@ -116,12 +112,10 @@ func CreateWindow(w, h int, title string) (*Window, *canvas.Canvas, error) {
|
|||
}
|
||||
})
|
||||
window.SetSizeCallback(func(w *glfw.Window, width, height int) {
|
||||
fbw, fbh := window.GetFramebufferSize()
|
||||
wnd.scalex = float64(fbw) / float64(width)
|
||||
wnd.scaley = float64(fbh) / float64(height)
|
||||
if wnd.SizeChange != nil {
|
||||
wnd.SizeChange(width, height)
|
||||
} else {
|
||||
fbw, fbh := window.GetFramebufferSize()
|
||||
backend.SetBounds(0, 0, fbw, fbh)
|
||||
}
|
||||
})
|
||||
|
@ -168,25 +162,23 @@ func (wnd *Window) FinishFrame() {
|
|||
func (wnd *Window) MainLoop(run func()) {
|
||||
for !wnd.close {
|
||||
wnd.StartFrame()
|
||||
if wnd.scalex != 1 || wnd.scaley != 1 {
|
||||
wnd.canvas.Save()
|
||||
wnd.canvas.Scale(wnd.scalex, wnd.scaley)
|
||||
}
|
||||
run()
|
||||
if wnd.scalex != 1 || wnd.scaley != 1 {
|
||||
wnd.canvas.Restore()
|
||||
}
|
||||
wnd.FinishFrame()
|
||||
}
|
||||
}
|
||||
|
||||
// Size returns the current width and height of the window
|
||||
// Size returns the current width and height of the window.
|
||||
// Note that this size may not be the same as the size of the
|
||||
// framebuffer, since some operating systems scale the window.
|
||||
// Use the Width/Height/Size function on Canvas to determine
|
||||
// the drawing size
|
||||
func (wnd *Window) Size() (int, int) {
|
||||
return wnd.Window.GetSize()
|
||||
}
|
||||
|
||||
// FramebufferSize returns the current width and height of
|
||||
// the framebuffer
|
||||
// the framebuffer, which is also the internal size of the
|
||||
// canvas
|
||||
func (wnd *Window) FramebufferSize() (int, int) {
|
||||
return wnd.Window.GetFramebufferSize()
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import (
|
|||
_ "image/gif" // Imported here so that applications based on this package support these formats by default
|
||||
_ "image/jpeg"
|
||||
_ "image/png"
|
||||
"math"
|
||||
"runtime"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
|
@ -39,8 +38,6 @@ type Window struct {
|
|||
KeyUp func(scancode int, rn rune, name string)
|
||||
KeyChar func(rn rune)
|
||||
SizeChange func(w, h int)
|
||||
scalex float64
|
||||
scaley float64
|
||||
}
|
||||
|
||||
// CreateWindow creates a window using SDL and initializes the OpenGL context
|
||||
|
@ -108,8 +105,6 @@ func CreateWindow(w, h int, title string) (*Window, *canvas.Canvas, error) {
|
|||
Backend: backend,
|
||||
canvas: cv,
|
||||
events: make([]sdl.Event, 0, 100),
|
||||
scalex: float64(fbw) / float64(w),
|
||||
scaley: float64(fbh) / float64(h),
|
||||
}
|
||||
|
||||
return wnd, cv, nil
|
||||
|
@ -150,27 +145,23 @@ func (wnd *Window) StartFrame() error {
|
|||
case *sdl.MouseButtonEvent:
|
||||
if e.Type == sdl.MOUSEBUTTONDOWN {
|
||||
if wnd.MouseDown != nil {
|
||||
mx, my := wnd.mpos(e.X, e.Y)
|
||||
wnd.MouseDown(int(e.Button), mx, my)
|
||||
wnd.MouseDown(int(e.Button), int(e.X), int(e.Y))
|
||||
handled = true
|
||||
}
|
||||
} else if e.Type == sdl.MOUSEBUTTONUP {
|
||||
if wnd.MouseUp != nil {
|
||||
mx, my := wnd.mpos(e.X, e.Y)
|
||||
wnd.MouseUp(int(e.Button), mx, my)
|
||||
wnd.MouseUp(int(e.Button), int(e.X), int(e.Y))
|
||||
handled = true
|
||||
}
|
||||
}
|
||||
case *sdl.MouseMotionEvent:
|
||||
if wnd.MouseMove != nil {
|
||||
mx, my := wnd.mpos(e.X, e.Y)
|
||||
wnd.MouseMove(mx, my)
|
||||
wnd.MouseMove(int(e.X), int(e.Y))
|
||||
handled = true
|
||||
}
|
||||
case *sdl.MouseWheelEvent:
|
||||
if wnd.MouseWheel != nil {
|
||||
mx, my := wnd.mpos(e.X, e.Y)
|
||||
wnd.MouseWheel(mx, my)
|
||||
wnd.MouseWheel(int(e.X), int(e.Y))
|
||||
handled = true
|
||||
}
|
||||
case *sdl.KeyboardEvent:
|
||||
|
@ -195,8 +186,6 @@ func (wnd *Window) StartFrame() error {
|
|||
if e.WindowID == wnd.WindowID {
|
||||
if e.Event == sdl.WINDOWEVENT_SIZE_CHANGED {
|
||||
fbw, fbh := wnd.Window.GLGetDrawableSize()
|
||||
wnd.scalex = float64(fbw) / float64(e.Data1)
|
||||
wnd.scaley = float64(fbh) / float64(e.Data2)
|
||||
if wnd.SizeChange != nil {
|
||||
wnd.SizeChange(int(e.Data1), int(e.Data2))
|
||||
handled = true
|
||||
|
@ -220,12 +209,6 @@ func (wnd *Window) StartFrame() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (wnd *Window) mpos(x, y int32) (int, int) {
|
||||
mx := int(math.Round(float64(x) * wnd.scalex))
|
||||
my := int(math.Round(float64(y) * wnd.scaley))
|
||||
return mx, my
|
||||
}
|
||||
|
||||
// FinishFrame updates the FPS count and displays the frame
|
||||
func (wnd *Window) FinishFrame() {
|
||||
now := time.Now()
|
||||
|
@ -267,27 +250,25 @@ func (wnd *Window) MainLoop(run func()) {
|
|||
}
|
||||
}
|
||||
|
||||
if wnd.scalex != 1 || wnd.scaley != 1 {
|
||||
wnd.canvas.Save()
|
||||
wnd.canvas.Scale(wnd.scalex, wnd.scaley)
|
||||
}
|
||||
run()
|
||||
if wnd.scalex != 1 || wnd.scaley != 1 {
|
||||
wnd.canvas.Restore()
|
||||
}
|
||||
|
||||
wnd.FinishFrame()
|
||||
}
|
||||
}
|
||||
|
||||
// Size returns the current width and height of the window
|
||||
// Size returns the current width and height of the window.
|
||||
// Note that this size may not be the same as the size of the
|
||||
// framebuffer, since some operating systems scale the window.
|
||||
// Use the Width/Height/Size function on Canvas to determine
|
||||
// the drawing size
|
||||
func (wnd *Window) Size() (int, int) {
|
||||
w, h := wnd.Window.GetSize()
|
||||
return int(w), int(h)
|
||||
}
|
||||
|
||||
// FramebufferSize returns the current width and height of
|
||||
// the framebuffer
|
||||
// the framebuffer, which is also the internal size of the
|
||||
// canvas
|
||||
func (wnd *Window) FramebufferSize() (int, int) {
|
||||
w, h := wnd.Window.GLGetDrawableSize()
|
||||
return int(w), int(h)
|
||||
|
|
Loading…
Reference in a new issue