diff --git a/examples/sdl/sdl.go b/examples/sdl/sdl.go index cad4fa0..a1014de 100644 --- a/examples/sdl/sdl.go +++ b/examples/sdl/sdl.go @@ -34,12 +34,12 @@ func main() { // create window const title = "SDL Test" - window, err := sdl.CreateWindow(title, sdl.WINDOWPOS_CENTERED, sdl.WINDOWPOS_CENTERED, 1280, 720, sdl.WINDOW_RESIZABLE|sdl.WINDOW_OPENGL) + window, err := sdl.CreateWindow(title, sdl.WINDOWPOS_CENTERED, sdl.WINDOWPOS_CENTERED, 1280, 720, sdl.WINDOW_RESIZABLE|sdl.WINDOW_OPENGL|sdl.WINDOW_ALLOW_HIGHDPI) if err != nil { // fallback in case multisample is not available sdl.GLSetAttribute(sdl.GL_MULTISAMPLEBUFFERS, 0) sdl.GLSetAttribute(sdl.GL_MULTISAMPLESAMPLES, 0) - window, err = sdl.CreateWindow(title, sdl.WINDOWPOS_CENTERED, sdl.WINDOWPOS_CENTERED, 1280, 720, sdl.WINDOW_RESIZABLE|sdl.WINDOW_OPENGL) + window, err = sdl.CreateWindow(title, sdl.WINDOWPOS_CENTERED, sdl.WINDOWPOS_CENTERED, 1280, 720, sdl.WINDOW_RESIZABLE|sdl.WINDOW_OPENGL|sdl.WINDOW_ALLOW_HIGHDPI) if err != nil { log.Fatalf("Error creating window: %v", err) } @@ -78,6 +78,12 @@ func main() { continue } + // find window size and scaling + ww, wh := window.GetSize() + fbw, fbh := window.GLGetDrawableSize() + sx := float64(fbw) / float64(ww) + sy := float64(fbh) / float64(wh) + // handle events for { event := sdl.PollEvent() @@ -91,7 +97,7 @@ func main() { running = false } case *sdl.MouseMotionEvent: - mx, my = float64(e.X), float64(e.Y) + mx, my = float64(e.X)*sx, float64(e.Y)*sy case *sdl.QuitEvent: running = false case *sdl.WindowEvent: @@ -102,11 +108,10 @@ func main() { } // set canvas size - ww, wh := window.GetSize() - backend.SetBounds(0, 0, int(ww), int(wh)) + backend.SetBounds(0, 0, int(fbw), int(fbh)) // call the run function to do all the drawing - run(cv, float64(ww), float64(wh)) + run(cv, float64(fbw), float64(fbh)) // swap back and front buffer window.GLSwap() diff --git a/go.mod b/go.mod index ac60148..bfa6927 100644 --- a/go.mod +++ b/go.mod @@ -5,9 +5,9 @@ require ( github.com/go-gl/glfw v0.0.0-20181014061658-691ee1b84c51 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72 github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 - github.com/veandco/go-sdl2 v0.3.3 + github.com/veandco/go-sdl2 v0.4.0 golang.org/x/exp v0.0.0-20181106170214-d68db9428509 - golang.org/x/image v0.0.0-20181109002202-aa35264064ba + golang.org/x/image v0.0.0-20200119044424-58c23975cae1 golang.org/x/mobile v0.0.0-20181026062114-a27dd33d354d golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35 // indirect ) diff --git a/go.sum b/go.sum index 84b9261..eec14a1 100644 --- a/go.sum +++ b/go.sum @@ -8,11 +8,14 @@ github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF0 github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/veandco/go-sdl2 v0.3.3 h1:4/TirgB2MQ7oww3pM3Yfgf1YbChMlAQAmiCPe5koK0I= github.com/veandco/go-sdl2 v0.3.3/go.mod h1:FB+kTpX9YTE+urhYiClnRzpOXbiWgaU3+5F2AB78DPg= +github.com/veandco/go-sdl2 v0.4.0 h1:l9q6K+Dvpd/VlZdw2ufApKnWhAQqx9UL8Zrvbjtm3Lw= +github.com/veandco/go-sdl2 v0.4.0/go.mod h1:FB+kTpX9YTE+urhYiClnRzpOXbiWgaU3+5F2AB78DPg= golang.org/x/exp v0.0.0-20181106170214-d68db9428509 h1:k21GX33vzpH/syMF7TgrLxe8ILtvwbyuHtEO3ebR82E= golang.org/x/exp v0.0.0-20181106170214-d68db9428509/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/image v0.0.0-20181109002202-aa35264064ba h1:tKfAeDKyjJZwxAJ8TPBZaf6LpvauubUHT8wwpdz+OMM= -golang.org/x/image v0.0.0-20181109002202-aa35264064ba/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= +golang.org/x/image v0.0.0-20200119044424-58c23975cae1 h1:5h3ngYt7+vXCDZCup/HkCQgW5XwmSvR/nA2JmJ0RErg= +golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/mobile v0.0.0-20181026062114-a27dd33d354d h1:DuZZDdMFwDrzmycNhCaWSve7Vh+BIrjm7ttgb4fD3Os= golang.org/x/mobile v0.0.0-20181026062114-a27dd33d354d/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35 h1:YAFjXN64LMvktoUZH9zgY4lGc/msGN7HQfoSuKCgaDU= golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/sdlcanvas/sdlcanvas.go b/sdlcanvas/sdlcanvas.go index 211d632..11d9bae 100644 --- a/sdlcanvas/sdlcanvas.go +++ b/sdlcanvas/sdlcanvas.go @@ -5,6 +5,7 @@ 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" @@ -38,6 +39,8 @@ 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 @@ -61,11 +64,11 @@ func CreateWindow(w, h int, title string) (*Window, *canvas.Canvas, error) { sdl.GLSetAttribute(sdl.GL_MULTISAMPLESAMPLES, 4) // create window - window, err := sdl.CreateWindow(title, sdl.WINDOWPOS_CENTERED, sdl.WINDOWPOS_CENTERED, int32(w), int32(h), sdl.WINDOW_RESIZABLE|sdl.WINDOW_OPENGL) + window, err := sdl.CreateWindow(title, sdl.WINDOWPOS_CENTERED, sdl.WINDOWPOS_CENTERED, int32(w), int32(h), sdl.WINDOW_RESIZABLE|sdl.WINDOW_OPENGL|sdl.WINDOW_ALLOW_HIGHDPI) if err != nil { sdl.GLSetAttribute(sdl.GL_MULTISAMPLEBUFFERS, 0) sdl.GLSetAttribute(sdl.GL_MULTISAMPLESAMPLES, 0) - window, err = sdl.CreateWindow(title, sdl.WINDOWPOS_CENTERED, sdl.WINDOWPOS_CENTERED, int32(w), int32(h), sdl.WINDOW_RESIZABLE|sdl.WINDOW_OPENGL) + window, err = sdl.CreateWindow(title, sdl.WINDOWPOS_CENTERED, sdl.WINDOWPOS_CENTERED, int32(w), int32(h), sdl.WINDOW_RESIZABLE|sdl.WINDOW_OPENGL|sdl.WINDOW_ALLOW_HIGHDPI) if err != nil { return nil, nil, fmt.Errorf("Error creating window: %v", err) } @@ -88,7 +91,8 @@ func CreateWindow(w, h int, title string) (*Window, *canvas.Canvas, error) { } // load canvas GL backend - backend, err := goglbackend.New(0, 0, w, h, nil) + fbw, fbh := window.GLGetDrawableSize() + backend, err := goglbackend.New(0, 0, int(fbw), int(fbh), nil) if err != nil { return nil, nil, fmt.Errorf("Error loading GoGL backend: %v", err) } @@ -104,6 +108,8 @@ 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 @@ -144,23 +150,27 @@ func (wnd *Window) StartFrame() error { case *sdl.MouseButtonEvent: if e.Type == sdl.MOUSEBUTTONDOWN { if wnd.MouseDown != nil { - wnd.MouseDown(int(e.Button), int(e.X), int(e.Y)) + mx, my := wnd.mpos(e.X, e.Y) + wnd.MouseDown(int(e.Button), mx, my) handled = true } } else if e.Type == sdl.MOUSEBUTTONUP { if wnd.MouseUp != nil { - wnd.MouseUp(int(e.Button), int(e.X), int(e.Y)) + mx, my := wnd.mpos(e.X, e.Y) + wnd.MouseUp(int(e.Button), mx, my) handled = true } } case *sdl.MouseMotionEvent: if wnd.MouseMove != nil { - wnd.MouseMove(int(e.X), int(e.Y)) + mx, my := wnd.mpos(e.X, e.Y) + wnd.MouseMove(mx, my) handled = true } case *sdl.MouseWheelEvent: if wnd.MouseWheel != nil { - wnd.MouseWheel(int(e.X), int(e.Y)) + mx, my := wnd.mpos(e.X, e.Y) + wnd.MouseWheel(mx, my) handled = true } case *sdl.KeyboardEvent: @@ -184,6 +194,9 @@ func (wnd *Window) StartFrame() error { case *sdl.WindowEvent: 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 @@ -207,6 +220,12 @@ 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() @@ -259,3 +278,10 @@ 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 +func (wnd *Window) FramebufferSize() (int, int) { + w, h := wnd.Window.GLGetDrawableSize() + return int(w), int(h) +}