goxjs / glfw

Go cross-platform glfw library for creating an OpenGL context and receiving events.
MIT License
82 stars 26 forks source link

Implement SetSize #8

Closed Omustardo closed 8 years ago

Omustardo commented 8 years ago

Move existing code for setting canvas size to SetSize(). Maintains existing behavior of filling the browser window by default.

I'm not sure how to test this besides running it with a demo. It works for a tetris demo: https://github.com/Omustardo/tetris/tree/master/webgl-tetris

dmitshur commented 8 years ago

Hi @Omustardo, thanks for the PR!

The code looks reasonable. But let's discuss the idea of what it means to implement SetSize in a browser on a higher level first.

First, I can see in your webgl-tetris code you currently have:

window, err := glfw.CreateWindow(*windowWidth, *windowHeight, "Tetris", nil, nil)
if err != nil {
    panic(err)
}
// glfw.CreateWindow ignores input size for WebGL/HTML canvas so set it here.
window.SetSize(*windowWidth, *windowHeight)

I would like to keep the API of this package as close to the desktop GLFW as possible, so if we're going to implement SetSize, then CreateWindow should do it too.

I can see in the commit message you tried to preserve current behavior... But I don't think that's neccessary. If we have a good solution for setting size other than fullscreen, then it should be available everywhere.

However, let's talk about what it means to have a GLFW window size that's smaller (or larger) than the browser window it's inside of.

As you know, the current implementation takes a "hacky" alternative solution - it starts to treat the window width and height as optional "hints" and simply discards them, opting to let the browser window act as the proxy for the GLFW window size. So when user resizes the browser window, it resizes the GLFW window.

I've tried your implementation on webgl-tetris (which is quite nice btw!), here it is with current GLFW code, stretched to fullscreen:

image

And with your patch:

image

I have the following high level questions about your proposed behavior:

  1. What happens to the space not covered by the GLFW window? Currently, it seems to be just white background. Should user have a way to control it?
  2. Should the GLFW window be centered in browser window, or in the top left corner (as it is in your implementation)?
  3. What should happen if user resizes the browser window?

Let me know what your thoughts are. :)

Omustardo commented 8 years ago

Hi shurcooL, Thanks for getting to this so quickly. These are some good points that I hadn't entirely thought out.

The basis for all of the questions relies on what exactly is the GopherJS/HTML equivalent of the GLFW window. I'd consider it to be the canvas element alone, since that's all that we render into. It's not entirely accurate, since input handling affects the rest of the page (e.g. you can't right click in the whitespace in the tetris demo), but perhaps it's as close to a standard desktop GLFW window as can be expected. If that's not a good assumption, then the rest of this logic is going to be wrong, but it's a starting point.

  1. What happens to the space not covered by the GLFW window? Currently, it seems to be just white background. Should user have a way to control it? If the GLFW window is just the canvas, then it shouldn't affect other elements. If users want to do so, they can modify the js/html.
  2. Should the GLFW window be centered in browser window, or in the top left corner (as it is in your implementation)? Like in the previous point, if the canvas is the glfw window, then its position is something the user should deal with through js/html. A visually pleasing default seems reasonable though. Subjectively I'd go with centered or top center. I don't do much web programming so I'm not sure if there's a technical advantage for either.
  3. What should happen if user resizes the browser window? I didn't realize the canvas was expanding to fill the browser window, even with the SetSize change. That definitely shouldn't happen. It seems that there are three situations: Fixed: set resolution. Based on the premise that the canvas is the GLFW window, resizing the browser window shouldn't affect canvas size. Fullscreen: fills entire monitor, browser size is irrelevant Full Window: fills entire browser window, resizing browser window resizes canvas Fixed and fullscreen wouldn't be an issue, but the "full window" browser-filling behavior may be tricky to implement since desktop GLFW windows don't have a counterpart of some intermediate bounding window as far as I know. I'll think about it more, but I haven't yet found of a good solution.
dmitshur commented 8 years ago

Actually, @Omustardo, let's move the high level discussion into an issue. I've made #9 for it.