From 167d972eede892c9028d42199088fd1a2fa15b4f Mon Sep 17 00:00:00 2001 From: David Linus Briemann Date: Thu, 3 May 2018 20:52:42 +0200 Subject: [PATCH 1/2] adds a community example for the usage of video modes --- examples/community/video-modes/README.md | 12 +++ examples/community/video-modes/main.go | 100 +++++++++++++++++++++++ pixelgl/monitor.go | 24 ++++++ pixelgl/window.go | 6 ++ 4 files changed, 142 insertions(+) create mode 100644 examples/community/video-modes/README.md create mode 100644 examples/community/video-modes/main.go diff --git a/examples/community/video-modes/README.md b/examples/community/video-modes/README.md new file mode 100644 index 0000000..d5fbc0e --- /dev/null +++ b/examples/community/video-modes/README.md @@ -0,0 +1,12 @@ +# Video Modes + +Just a demo on how to retrieve and set video modes with Pixel. + +Made by [David Linus Briemann](https://github.com/dbriemann/). + +## Controls + +ESC - Quit +W - Toggle between fullscreen and windowed. + +Switch video modes with the shown characters. diff --git a/examples/community/video-modes/main.go b/examples/community/video-modes/main.go new file mode 100644 index 0000000..dc70e64 --- /dev/null +++ b/examples/community/video-modes/main.go @@ -0,0 +1,100 @@ +package main + +import ( + "fmt" + + "github.com/faiface/pixel" + "github.com/faiface/pixel/pixelgl" + "github.com/faiface/pixel/text" + "golang.org/x/image/colornames" + "golang.org/x/image/font/basicfont" +) + +var ( + texts []*text.Text + staticText *text.Text + vmodes []*pixelgl.VideoMode + activeMode pixelgl.VideoMode + activeMonitor *pixelgl.Monitor +) + +func run() { + cfg := pixelgl.WindowConfig{ + Title: "Video Modes", + Bounds: pixel.R(0, 0, 800, 600), + } + win, err := pixelgl.NewWindow(cfg) + if err != nil { + panic(err) + } + + atlas := text.NewAtlas(basicfont.Face7x13, text.ASCII) + + // Retrieve all monitors. + monitors := pixelgl.Monitors() + + texts = make([]*text.Text, len(monitors)) + key := byte('0') + for i := 0; i < len(monitors); i++ { + // Retrieve all video modes for a specific monitor. + modes := monitors[i].VideoModes() + + vmodes = append(vmodes, modes...) + texts[i] = text.New(pixel.V(10+250*float64(i), -20), atlas) + texts[i].Color = colornames.Black + texts[i].WriteString(fmt.Sprintf("MONITOR %s\n\n", monitors[i].Name())) + + for _, v := range modes { + texts[i].WriteString(fmt.Sprintf("(%c) %dx%d @ %d hz, %d bpp\n", key, v.Width, v.Height, v.RefreshRate, v.BlueBits+v.RedBits+v.GreenBits)) + key++ + } + } + + staticText = text.New(pixel.V(10, 30), atlas) + staticText.Color = colornames.Black + staticText.WriteString("ESC to exit\nW toggles windowed/fullscreen") + + for !win.Closed() { + win.Clear(colornames.Antiquewhite) + + for _, txt := range texts { + txt.Draw(win, pixel.IM.Moved(pixel.V(0, win.Bounds().H()))) + } + staticText.Draw(win, pixel.IM) + + if win.JustPressed(pixelgl.KeyEscape) { + win.SetClosed(true) + } + + if win.JustPressed(pixelgl.KeyW) { + if activeMode.Monitor != nil { + // Switch to windowed and backup the correct monitor. + activeMonitor = activeMode.Monitor + activeMode.Monitor = nil + win.SetVideoMode(activeMode) + } else { + // Switch to fullscreen. + activeMode.Monitor = activeMonitor + win.SetVideoMode(activeMode) + } + } + + input := win.Typed() + if len(input) > 0 { + key := int(input[0]) - 48 + fmt.Println(key) + if key >= 0 && key < len(vmodes) { + activeMode = *vmodes[key] + activeMonitor = activeMode.Monitor + fmt.Println("change to:", activeMode.Width, activeMode.Height) + win.SetVideoMode(activeMode) + } + } + + win.Update() + } +} + +func main() { + pixelgl.Run(run) +} diff --git a/pixelgl/monitor.go b/pixelgl/monitor.go index 7cf73a9..0d4a6d3 100644 --- a/pixelgl/monitor.go +++ b/pixelgl/monitor.go @@ -10,6 +10,15 @@ type Monitor struct { monitor *glfw.Monitor } +// VideoMode represents all properties of a video mode and is attached +// to a monitor if it is a fullscreen mode. +type VideoMode struct { + *glfw.VidMode + // Monitor is a pointer to the monitor that owns this video mode. + // If Monitor is nil the video mode is windowed. + Monitor *Monitor +} + // PrimaryMonitor returns the main monitor (usually the one with the taskbar and stuff). func PrimaryMonitor() *Monitor { var monitor *glfw.Monitor @@ -95,3 +104,18 @@ func (m *Monitor) RefreshRate() (rate float64) { rate = float64(mode.RefreshRate) return } + +// VideoModes returns all available video modes for the monitor. +func (m *Monitor) VideoModes() (vmodes []*VideoMode) { + var modes []*glfw.VidMode + mainthread.Call(func() { + modes = m.monitor.GetVideoModes() + }) + for _, mode := range modes { + vmodes = append(vmodes, &VideoMode{ + VidMode: mode, + Monitor: m, + }) + } + return +} diff --git a/pixelgl/window.go b/pixelgl/window.go index ddc5426..0668a9b 100644 --- a/pixelgl/window.go +++ b/pixelgl/window.go @@ -424,3 +424,9 @@ func (w *Window) Clear(c color.Color) { func (w *Window) Color(at pixel.Vec) pixel.RGBA { return w.canvas.Color(at) } + +// SetVideoMode applies the given video mode to this window. +func (w *Window) SetVideoMode(vm VideoMode) { + w.SetMonitor(vm.Monitor) + w.SetBounds(pixel.R(0, 0, float64(vm.Width), float64(vm.Height))) +} From 1bbbf26b310eb3df4d2ce1fc6d13585d1b7cd4ee Mon Sep 17 00:00:00 2001 From: David Linus Briemann Date: Fri, 4 May 2018 18:03:25 +0200 Subject: [PATCH 2/2] adjusts VideoMode and associated function to pull request change requests. --- examples/community/video-modes/main.go | 48 +++++++++++++++++--------- pixelgl/monitor.go | 23 ++++++------ pixelgl/window.go | 6 ---- 3 files changed, 45 insertions(+), 32 deletions(-) diff --git a/examples/community/video-modes/main.go b/examples/community/video-modes/main.go index dc70e64..a561c89 100644 --- a/examples/community/video-modes/main.go +++ b/examples/community/video-modes/main.go @@ -10,12 +10,17 @@ import ( "golang.org/x/image/font/basicfont" ) +type setting struct { + mode *pixelgl.VideoMode + monitor *pixelgl.Monitor +} + var ( texts []*text.Text staticText *text.Text - vmodes []*pixelgl.VideoMode - activeMode pixelgl.VideoMode - activeMonitor *pixelgl.Monitor + settings []setting + activeSetting *setting + isFullScreen = false ) func run() { @@ -38,14 +43,19 @@ func run() { for i := 0; i < len(monitors); i++ { // Retrieve all video modes for a specific monitor. modes := monitors[i].VideoModes() + for j := 0; j < len(modes); j++ { + settings = append(settings, setting{ + monitor: monitors[i], + mode: &modes[j], + }) + } - vmodes = append(vmodes, modes...) texts[i] = text.New(pixel.V(10+250*float64(i), -20), atlas) texts[i].Color = colornames.Black texts[i].WriteString(fmt.Sprintf("MONITOR %s\n\n", monitors[i].Name())) for _, v := range modes { - texts[i].WriteString(fmt.Sprintf("(%c) %dx%d @ %d hz, %d bpp\n", key, v.Width, v.Height, v.RefreshRate, v.BlueBits+v.RedBits+v.GreenBits)) + texts[i].WriteString(fmt.Sprintf("(%c) %dx%d @ %d hz\n", key, v.Width, v.Height, v.RefreshRate)) key++ } } @@ -54,6 +64,8 @@ func run() { staticText.Color = colornames.Black staticText.WriteString("ESC to exit\nW toggles windowed/fullscreen") + activeSetting = &settings[0] + for !win.Closed() { win.Clear(colornames.Antiquewhite) @@ -67,27 +79,31 @@ func run() { } if win.JustPressed(pixelgl.KeyW) { - if activeMode.Monitor != nil { + if isFullScreen { // Switch to windowed and backup the correct monitor. - activeMonitor = activeMode.Monitor - activeMode.Monitor = nil - win.SetVideoMode(activeMode) + win.SetMonitor(nil) + isFullScreen = false } else { // Switch to fullscreen. - activeMode.Monitor = activeMonitor - win.SetVideoMode(activeMode) + win.SetMonitor(activeSetting.monitor) + isFullScreen = true } + win.SetBounds(pixel.R(0, 0, float64(activeSetting.mode.Width), float64(activeSetting.mode.Height))) } input := win.Typed() if len(input) > 0 { key := int(input[0]) - 48 fmt.Println(key) - if key >= 0 && key < len(vmodes) { - activeMode = *vmodes[key] - activeMonitor = activeMode.Monitor - fmt.Println("change to:", activeMode.Width, activeMode.Height) - win.SetVideoMode(activeMode) + if key >= 0 && key < len(settings) { + activeSetting = &settings[key] + + if isFullScreen { + win.SetMonitor(activeSetting.monitor) + } else { + win.SetMonitor(nil) + } + win.SetBounds(pixel.R(0, 0, float64(activeSetting.mode.Width), float64(activeSetting.mode.Height))) } } diff --git a/pixelgl/monitor.go b/pixelgl/monitor.go index 0d4a6d3..90ae7cc 100644 --- a/pixelgl/monitor.go +++ b/pixelgl/monitor.go @@ -10,13 +10,15 @@ type Monitor struct { monitor *glfw.Monitor } -// VideoMode represents all properties of a video mode and is attached -// to a monitor if it is a fullscreen mode. +// VideoMode represents all properties of a video mode and is +// associated with a monitor if it is used in fullscreen mode. type VideoMode struct { - *glfw.VidMode - // Monitor is a pointer to the monitor that owns this video mode. - // If Monitor is nil the video mode is windowed. - Monitor *Monitor + // Width is the width of the vide mode in pixels. + Width int + // Height is the height of the video mode in pixels. + Height int + // RefreshRate holds the refresh rate of the associated monitor in Hz. + RefreshRate int } // PrimaryMonitor returns the main monitor (usually the one with the taskbar and stuff). @@ -106,15 +108,16 @@ func (m *Monitor) RefreshRate() (rate float64) { } // VideoModes returns all available video modes for the monitor. -func (m *Monitor) VideoModes() (vmodes []*VideoMode) { +func (m *Monitor) VideoModes() (vmodes []VideoMode) { var modes []*glfw.VidMode mainthread.Call(func() { modes = m.monitor.GetVideoModes() }) for _, mode := range modes { - vmodes = append(vmodes, &VideoMode{ - VidMode: mode, - Monitor: m, + vmodes = append(vmodes, VideoMode{ + Width: mode.Width, + Height: mode.Height, + RefreshRate: mode.RefreshRate, }) } return diff --git a/pixelgl/window.go b/pixelgl/window.go index 0668a9b..ddc5426 100644 --- a/pixelgl/window.go +++ b/pixelgl/window.go @@ -424,9 +424,3 @@ func (w *Window) Clear(c color.Color) { func (w *Window) Color(at pixel.Vec) pixel.RGBA { return w.canvas.Color(at) } - -// SetVideoMode applies the given video mode to this window. -func (w *Window) SetVideoMode(vm VideoMode) { - w.SetMonitor(vm.Monitor) - w.SetBounds(pixel.R(0, 0, float64(vm.Width), float64(vm.Height))) -}