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:
Thomas Friedel 2020-02-11 11:28:18 +01:00
parent 259bb9e598
commit a80e3778fd
3 changed files with 34 additions and 47 deletions

View file

@ -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)

View file

@ -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()
}

View file

@ -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)