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

framebuffer size vs. window size #99

Closed
rougier opened this issue Feb 11, 2014 · 17 comments
Closed

framebuffer size vs. window size #99

rougier opened this issue Feb 11, 2014 · 17 comments

Comments

@rougier
Copy link
Contributor

rougier commented Feb 11, 2014

On OSX, with retina display, the actual framebuffer size can be different from the window size. Some backends are aware of this difference (glfw), some others are not (qt,glut,pyglet).

On solution to cope with this situation is to set the size of GL viewport using the framebuffer size. We can add a framebuffer size for all backend and only glfw will report different size and makes OSX users happy. For qt,pyglet,glut, framebuffer size will return window size.

@rougier rougier added the bug label Feb 11, 2014
@campagnola
Copy link
Member

I'm confused about how this works.. can you give an example? Would there be a difference between Canvas.size and glViewport(...) ?

@rougier
Copy link
Contributor Author

rougier commented Feb 11, 2014

It is confusing !

While trying to give explanation, I realized I did not understand it fully...

The point is that using glfw, it is possible to access the true resolution instead of the "public" one.
Currently, all my render are "doubled" (one pixel -> 4 pixels)

On 11 Feb 2014, at 19:55, Luke Campagnola notifications@github.com wrote:

I'm confused about how this works.. can you give an example? Would there be a difference between Canvas.size and glViewport(...) ?


Reply to this email directly or view it on GitHub.

@larsoner
Copy link
Member

My understanding is that, for OSX, they decided to make the framebuffer size different from the apparent window size. I wonder if they are doing something under the hood to make windows "look better" on their displays. In any case, we can all thank Apple for making us jump through hoops that don't exist on other platforms:

http://stackoverflow.com/questions/12821144/how-to-draw-text-in-opengl-on-mac-os-with-retina-display

https://developer.apple.com/library/mac/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/CapturingScreenContents/CapturingScreenContents.html

@rougier
Copy link
Contributor Author

rougier commented Feb 11, 2014

Yes, it's quite bad for us.
Currently, the glfw backend is working nicely and is definitely more sharp (because it uses true resolution).

The "bad" is that you request a window size of 600,600 and end up with a framebuffer of 1200x1200.
However, we can maybe the glfw backend such that the public size ends up being the real one.

On 11 Feb 2014, at 20:35, Eric89GXL notifications@github.com wrote:

My understanding is that, for OSX, they decided to make the framebuffer size different from the apparent window size. I wonder if they are doing something under the hood to make windows "look better" on their displays. In any case, we can all thank Apple for making us jump through hoops that don't exist on other platforms:

http://stackoverflow.com/questions/12821144/how-to-draw-text-in-opengl-on-mac-os-with-retina-display

https://developer.apple.com/library/mac/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/CapturingScreenContents/CapturingScreenContents.html


Reply to this email directly or view it on GitHub.

@larsoner
Copy link
Member

Well I guess the user thinks the screen is half the real size (/number of pixels), correct? So in that sense, it would be best if their set_size or whatever were in "appent" coordinates, and then at our (back)end, we set up the glViewport appropriately to use twice that space. And we'll just have to live with the other backends being grainier.

@rougier
Copy link
Contributor Author

rougier commented Feb 11, 2014

I just discovered in that weird mode, mouse is moving 2 pixels by 2 pixels. I can't believe it...
(and of course, mouse coordinates follow window size, not framebuffer size)

My proposition would be to compute window/framebuffer size ratio first time window is shown and use this ratio to correct window size and mouse coordinates.

On 11 Feb 2014, at 20:43, Eric89GXL notifications@github.com wrote:

Well I guess the user thinks the screen is half the real size (/number of pixels), correct? So in that sense, it would be best if their set_size or whatever were in "appent" coordinates, and then at our (back)end, we set up the glViewport appropriately to use twice that space. And we'll just have to live with the other backends being grainier.


Reply to this email directly or view it on GitHub.

@larsoner
Copy link
Member

And for every other backend (Pyglet/Qt/glut), the FB size == Window size so it effectively wouldn't do anything (ratio=1). This sounds reasonable to me.

@rougier
Copy link
Contributor Author

rougier commented Feb 11, 2014

Or we confined the code within the glfw backend for the time being. I'm surprised qt does handle this and if it doesn't, most probably it will in the near future. Problem is that we don't know how it'll cope with this.

Any qt expert around ?

On 11 Feb 2014, at 20:51, Eric89GXL notifications@github.com wrote:

And for every other backend (Pyglet/Qt/glut), the FB size == Window size so it effectively wouldn't do anything (ratio=1). This sounds reasonable to me.


Reply to this email directly or view it on GitHub.

@rossant
Copy link
Member

rossant commented Feb 11, 2014

https://blog.qt.digia.com/blog/2013/04/25/retina-display-support-for-mac-os-ios-and-x11/
Have you seen the paragraph about opengl here?

Le mardi 11 février 2014, Nicolas P. Rougier notifications@github.com a
écrit :

Or we confined the code within the glfw backend for the time being. I'm
surprised qt does handle this and if it doesn't, most probably it will in
the near future. Problem is that we don't know how it'll cope with this.

Any qt expert around ?

On 11 Feb 2014, at 20:51, Eric89GXL <notifications@github.comjavascript:_e(%7B%7D,'cvml','notifications@github.com');>
wrote:

And for every other backend (Pyglet/Qt/glut), the FB size == Window size
so it effectively wouldn't do anything (ratio=1). This sounds reasonable to
me.

Reply to this email directly or view it on GitHub.

Reply to this email directly or view it on GitHubhttps://github.com//issues/99#issuecomment-34798337
.

@larsoner
Copy link
Member

The problem with that article is that it details what has been done for Qt5, saying about 4.8 that it "backports some of the Qt 5 patches available" -- not exactly definitive language there.

In any case, this is probably the key point for us (about halfway down):

"OpenGL operates in device pixel [i.e., real pixel] space. For example, the width and height passed to glViewport should be in device pixels. QGLWidget::resizeGL() gives the width and height in device pixels.

However, QGLWidget::width() is really QWidget::width() which returns a value in device-independent pixels. Resolve it by multiplying with widget->windowHandle()->devicePixelRatio() if needed."

So essentially @rougier we can also modify our behavior for Qt, just as we will for glfw. I guess we'll know whether or not it's correct via 1) if the devicePixelRatio actually exists, and then 2) testing on your end. This fits in well with your concept for glfw of querying the ratio once and storing it for glfw in any case.

@campagnola
Copy link
Member

What a damned mess. So essentially, as physical pixels shrank, it became much easier to redefine "pixel" as a constant-length unit than to rewrite the entire www to use "cm" instead of "px" in CSS. Looks like one "pixel" is equivalent to 1/96 inches in most contexts, but we'll need to keep track of this across platforms. I want to have the option to specify any sizes using physical units and expect consistent results, and I have been thinking about the foundations of this in my current development.

What do you all think about standardizing on the following definitions to avoid confusion in the future:

  • "pixel" or "px" refers to logical pixels on systems that implement that concept. On other systems (Linux, Windows) it refers to physical pixels
  • "device pixel" or "dpx" refers always to a physical pixel on a display
  • "logical pixel" or "lpx" refers always to a physical unit of measure (usually 1/96 inches) that might be different across platforms. (not sure if this term will be necessary in most cases..)

@rougier
Copy link
Contributor Author

rougier commented Feb 12, 2014

The quick solution is to separate framebuffer size from window size (e.g. using ratio).

For the future however (for example if we target pdf output), we might need some more generic solution.

On 12 Feb 2014, at 06:47, Luke Campagnola notifications@github.com wrote:

What a damned mess. So essentially, as physical pixels shrank, it became much easier to redefine "pixel" as a constant-length unit than to rewrite the entire www to use "cm" instead of "px" in CSS. Looks like one "pixel" is equivalent to 1/96 inches in most contexts, but we'll need to keep track of this across platforms. I want to have the option to specify any sizes using physical units and expect consistent results, and I have been thinking about the foundations of this in my current development.

What do you all think about standardizing on the following definitions to avoid confusion in the future:

• "pixel" or "px" refers to logical pixels on systems that implement that concept. On other systems (Linux, Windows) it refers to physical pixels
• "device pixel" or "dpx" refers always to a physical pixel on a display
• "logical pixel" or "lpx" refers always to a physical unit of measure (usually 1/96 inches) that might be different across platforms. (not sure if this term will be necessary in most cases..)

Reply to this email directly or view it on GitHub.

@larsoner
Copy link
Member

Those definitions make sense to me in the long run @lcampagn, and agree with @rougier that, at least in the near-term, dealing with framebuffer versus window size in appropriate places makes sense. Even on retina displays users have a concept of window size, they are just unwittingly thinking of it in terms of "logical pixels". So as long as we keep window size as being in logical pixels (so it's sane from a user viewpoint) and framebuffer size as in physical pixels (so it's sane from an OpenGL standpoint) then I think we'll be okay.

@larsoner
Copy link
Member

And eventually when we build in unit support, we can have "px" mean whatever they mean on the native system, and have finer-grained definitions for the underlying concepts if users want to use those, as you suggest.

@rossant
Copy link
Member

rossant commented Sep 2, 2014

What is the status of this?

@campagnola
Copy link
Member

The scenegraph currently does provide the necessary transforms to handle this, although not all visuals have been written to take advantage of that. Probably this can be closed and we should open issues on individual visuals as needed.

@campagnola
Copy link
Member

Superseded by #551

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

No branches or pull requests

4 participants