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.SetFillStyle("#000")
|
||||||
cv.FillRect(0, 0, w, h)
|
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
|
// Draw lines with different colors and line thickness
|
||||||
for x := 1.0; x < 10.5; x += 1.0 {
|
for x := 1.0; x < 10.5; x += 1.0 {
|
||||||
cv.SetStrokeStyle(int(x*25), 255, 255)
|
cv.SetStrokeStyle(int(x*25), 255, 255)
|
||||||
|
|
|
@ -33,8 +33,6 @@ type Window struct {
|
||||||
KeyUp func(scancode int, rn rune, name string)
|
KeyUp func(scancode int, rn rune, name string)
|
||||||
KeyChar func(rn rune)
|
KeyChar func(rn rune)
|
||||||
SizeChange func(w, h int)
|
SizeChange func(w, h int)
|
||||||
scalex float64
|
|
||||||
scaley float64
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateWindow creates a window using SDL and initializes the OpenGL context
|
// 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{
|
wnd := &Window{
|
||||||
Window: window,
|
Window: window,
|
||||||
canvas: cv,
|
canvas: cv,
|
||||||
scalex: float64(fbw) / float64(w),
|
|
||||||
scaley: float64(fbh) / float64(h),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var mx, my int
|
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) {
|
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 {
|
if wnd.MouseMove != nil {
|
||||||
wnd.MouseMove(mx, my)
|
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) {
|
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 {
|
if wnd.SizeChange != nil {
|
||||||
wnd.SizeChange(width, height)
|
wnd.SizeChange(width, height)
|
||||||
} else {
|
} else {
|
||||||
|
fbw, fbh := window.GetFramebufferSize()
|
||||||
backend.SetBounds(0, 0, fbw, fbh)
|
backend.SetBounds(0, 0, fbw, fbh)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -168,25 +162,23 @@ func (wnd *Window) FinishFrame() {
|
||||||
func (wnd *Window) MainLoop(run func()) {
|
func (wnd *Window) MainLoop(run func()) {
|
||||||
for !wnd.close {
|
for !wnd.close {
|
||||||
wnd.StartFrame()
|
wnd.StartFrame()
|
||||||
if wnd.scalex != 1 || wnd.scaley != 1 {
|
|
||||||
wnd.canvas.Save()
|
|
||||||
wnd.canvas.Scale(wnd.scalex, wnd.scaley)
|
|
||||||
}
|
|
||||||
run()
|
run()
|
||||||
if wnd.scalex != 1 || wnd.scaley != 1 {
|
|
||||||
wnd.canvas.Restore()
|
|
||||||
}
|
|
||||||
wnd.FinishFrame()
|
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) {
|
func (wnd *Window) Size() (int, int) {
|
||||||
return wnd.Window.GetSize()
|
return wnd.Window.GetSize()
|
||||||
}
|
}
|
||||||
|
|
||||||
// FramebufferSize returns the current width and height of
|
// 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) {
|
func (wnd *Window) FramebufferSize() (int, int) {
|
||||||
return wnd.Window.GetFramebufferSize()
|
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/gif" // Imported here so that applications based on this package support these formats by default
|
||||||
_ "image/jpeg"
|
_ "image/jpeg"
|
||||||
_ "image/png"
|
_ "image/png"
|
||||||
"math"
|
|
||||||
"runtime"
|
"runtime"
|
||||||
"time"
|
"time"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
@ -39,8 +38,6 @@ type Window struct {
|
||||||
KeyUp func(scancode int, rn rune, name string)
|
KeyUp func(scancode int, rn rune, name string)
|
||||||
KeyChar func(rn rune)
|
KeyChar func(rn rune)
|
||||||
SizeChange func(w, h int)
|
SizeChange func(w, h int)
|
||||||
scalex float64
|
|
||||||
scaley float64
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateWindow creates a window using SDL and initializes the OpenGL context
|
// 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,
|
Backend: backend,
|
||||||
canvas: cv,
|
canvas: cv,
|
||||||
events: make([]sdl.Event, 0, 100),
|
events: make([]sdl.Event, 0, 100),
|
||||||
scalex: float64(fbw) / float64(w),
|
|
||||||
scaley: float64(fbh) / float64(h),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return wnd, cv, nil
|
return wnd, cv, nil
|
||||||
|
@ -150,27 +145,23 @@ func (wnd *Window) StartFrame() error {
|
||||||
case *sdl.MouseButtonEvent:
|
case *sdl.MouseButtonEvent:
|
||||||
if e.Type == sdl.MOUSEBUTTONDOWN {
|
if e.Type == sdl.MOUSEBUTTONDOWN {
|
||||||
if wnd.MouseDown != nil {
|
if wnd.MouseDown != nil {
|
||||||
mx, my := wnd.mpos(e.X, e.Y)
|
wnd.MouseDown(int(e.Button), int(e.X), int(e.Y))
|
||||||
wnd.MouseDown(int(e.Button), mx, my)
|
|
||||||
handled = true
|
handled = true
|
||||||
}
|
}
|
||||||
} else if e.Type == sdl.MOUSEBUTTONUP {
|
} else if e.Type == sdl.MOUSEBUTTONUP {
|
||||||
if wnd.MouseUp != nil {
|
if wnd.MouseUp != nil {
|
||||||
mx, my := wnd.mpos(e.X, e.Y)
|
wnd.MouseUp(int(e.Button), int(e.X), int(e.Y))
|
||||||
wnd.MouseUp(int(e.Button), mx, my)
|
|
||||||
handled = true
|
handled = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case *sdl.MouseMotionEvent:
|
case *sdl.MouseMotionEvent:
|
||||||
if wnd.MouseMove != nil {
|
if wnd.MouseMove != nil {
|
||||||
mx, my := wnd.mpos(e.X, e.Y)
|
wnd.MouseMove(int(e.X), int(e.Y))
|
||||||
wnd.MouseMove(mx, my)
|
|
||||||
handled = true
|
handled = true
|
||||||
}
|
}
|
||||||
case *sdl.MouseWheelEvent:
|
case *sdl.MouseWheelEvent:
|
||||||
if wnd.MouseWheel != nil {
|
if wnd.MouseWheel != nil {
|
||||||
mx, my := wnd.mpos(e.X, e.Y)
|
wnd.MouseWheel(int(e.X), int(e.Y))
|
||||||
wnd.MouseWheel(mx, my)
|
|
||||||
handled = true
|
handled = true
|
||||||
}
|
}
|
||||||
case *sdl.KeyboardEvent:
|
case *sdl.KeyboardEvent:
|
||||||
|
@ -195,8 +186,6 @@ func (wnd *Window) StartFrame() error {
|
||||||
if e.WindowID == wnd.WindowID {
|
if e.WindowID == wnd.WindowID {
|
||||||
if e.Event == sdl.WINDOWEVENT_SIZE_CHANGED {
|
if e.Event == sdl.WINDOWEVENT_SIZE_CHANGED {
|
||||||
fbw, fbh := wnd.Window.GLGetDrawableSize()
|
fbw, fbh := wnd.Window.GLGetDrawableSize()
|
||||||
wnd.scalex = float64(fbw) / float64(e.Data1)
|
|
||||||
wnd.scaley = float64(fbh) / float64(e.Data2)
|
|
||||||
if wnd.SizeChange != nil {
|
if wnd.SizeChange != nil {
|
||||||
wnd.SizeChange(int(e.Data1), int(e.Data2))
|
wnd.SizeChange(int(e.Data1), int(e.Data2))
|
||||||
handled = true
|
handled = true
|
||||||
|
@ -220,12 +209,6 @@ func (wnd *Window) StartFrame() error {
|
||||||
return nil
|
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
|
// FinishFrame updates the FPS count and displays the frame
|
||||||
func (wnd *Window) FinishFrame() {
|
func (wnd *Window) FinishFrame() {
|
||||||
now := time.Now()
|
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()
|
run()
|
||||||
if wnd.scalex != 1 || wnd.scaley != 1 {
|
|
||||||
wnd.canvas.Restore()
|
|
||||||
}
|
|
||||||
|
|
||||||
wnd.FinishFrame()
|
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) {
|
func (wnd *Window) Size() (int, int) {
|
||||||
w, h := wnd.Window.GetSize()
|
w, h := wnd.Window.GetSize()
|
||||||
return int(w), int(h)
|
return int(w), int(h)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FramebufferSize returns the current width and height of
|
// 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) {
|
func (wnd *Window) FramebufferSize() (int, int) {
|
||||||
w, h := wnd.Window.GLGetDrawableSize()
|
w, h := wnd.Window.GLGetDrawableSize()
|
||||||
return int(w), int(h)
|
return int(w), int(h)
|
||||||
|
|
Loading…
Reference in a new issue