Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HiDPI broken, possible workaround inside #159

Open
burner-account opened this issue Jan 3, 2020 · 2 comments
Open

HiDPI broken, possible workaround inside #159

burner-account opened this issue Jan 3, 2020 · 2 comments

Comments

@burner-account
Copy link

I had a look at g3n/engine and it made a good impression on me, so i tried to evaluate it.

Problem, visible with g3nd:
Using a 4K resolution monitor with 200% UI DPI scale resulted in broken GUI element scaling. The GUI is assembled correctly on startup and ignores UI DPI scale after window resizing (halfing the element size in this case).

Workaround:
With glfw version 3.3 it is possible to use the window hint
glfw.WindowHint(glfw.ScaleToMonitor, glfw.True)

Collateral:
With this window hint, the width and height reported to window event callbacks on HiDPI devices are equal to the frame buffer dimensions. So it is no longer possible to calculate the scaling factor by a division "frame buffer W" / "reported W".

Scale can now be retrieved via (*glfw.Window).GetContentScale(). Minor tweaks to g3n/engine/window/glfw.go are required in order to get scaling and raycasting GUI elements to work:

window struct members

// GlfwWindow describes one glfw window
type GlfwWindow struct {
	// ...........
	scaleX float32
	scaleY float32
}

window initialization:

// Init initializes the GlfwWindow singleton with the specified width, height, and title.
func Init(width, height int, title string) error {
	// ...
	glfw.WindowHint(glfw.ScaleToMonitor, glfw.True)
	// ...
	w.scaleX, w.scaleY = w.GetContentScale()
	// ...
}

and the callbacks:

// Set up window size callback to dispatch event
w.SetSizeCallback(func(x *glfw.Window, width int, height int) {
	scx, scy := x.GetContentScale()
	// scale down from high DPI values
	w.sizeEv.Width = int(float32(width) / scx)
	w.sizeEv.Height = int(float32(height) / scy)
	w.scaleX = scx
	w.scaleY = scy
	w.Dispatch(OnWindowSize, &w.sizeEv)
})

// Set up window cursor position callback to dispatch event
w.SetCursorPosCallback(func(x *glfw.Window, xpos float64, ypos float64) {
	scx, scy := x.GetContentScale()
	// scale down from high DPI values
	w.cursorEv.Xpos = float32(xpos) / scx
	w.cursorEv.Ypos = float32(ypos) / scy
	w.cursorEv.Mods = w.mods
	w.Dispatch(OnCursor, &w.cursorEv)
})

These changes work great for me as the GUI now renders correctly. But i have absolutely no idea if i broke something in another area which is not obvious to the eye while glancing at the g3nd on a linux desktop. "It looked nice" is no real test.

Are there arguments against using glfw 3.3?

@burner-account
Copy link
Author

// Set up mouse button callback to dispatch event
w.SetMouseButtonCallback(func(x *glfw.Window, button glfw.MouseButton, action glfw.Action, mods glfw.ModifierKey) {
	xpos, ypos := x.GetCursorPos()
	w.mouseEv.Button = MouseButton(button)
	w.mouseEv.Mods = ModifierKey(mods)
	// scale down from high DPI values
	scx, scy := x.GetContentScale()
	w.mouseEv.Xpos = float32(xpos) / scx
	w.mouseEv.Ypos = float32(ypos) / scy
	if action == glfw.Press {
		w.Dispatch(OnMouseDown, &w.mouseEv)
	} else if action == glfw.Release {
		w.Dispatch(OnMouseUp, &w.mouseEv)
	}
})

This one needs to be patched, too.

This was referenced Jan 17, 2020
@danaugrs
Copy link
Member

Hi @burner-account ! Could you try the latest version of G3N and see if your changes are still necessary? If so, please open a new PR. Thanks, and sorry for the delay!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants