Make the OpenGL display look good on retina displays. #318

Closed
wants to merge 3 commits into
from

2 participants

@nico

DO NOT MERGE: This breaks "save as image" (this now only saves the lower left 1/4th of the viewport), and may have other issues. It's useful as a proof-of-concept though.

Qt doesn't support an official API for opting in to retina mode for GL
views yet. Behind the scenes, a QGLView uses an NSOpenGLView, which
needs a call to -setWantsBestResolutionOpenGLSurface:YES to opt in to
this mode.

This CL pokes at Qt internals to do this call -- due to QGLView.cc only
allowing C++ code, this is done by explicitly calling out to the
Objective-C runtime.

The reason this mode needs an explicit opt-in is because it requires
expicit code to support retina mode in OpenGL. OpenGL is pixel-based,
while Cocoa (and possibly Qt) use logical view coordinates, where one
coordinate corresponds to two physical pixels on retina displays.
Because of this, several parameters passed to OpenGL need to explicitly
be scaled by the view scale factor.

I did this in the visually obvious places in this patch, but I fairly
certainly missed a few places. I also didn't test image saving, which
might be broken to. (I also didn't test with a 32 bit build, which has
to use a slightly different Obj-C API, but that part has a chance of
being correct.)

Another thing this patch doesn't handle is dynamic scale factor changes,
which happen when dragging an OpenSCAD window from a retina display to
an external display. It's possible that it happens to work, but I
haven't tested it.

@nico nico Make the OpenGL display look good on retina displays.
Qt doesn't support an official API for opting in to retina mode for GL
views yet. Behind the scenes, a QGLView uses an NSOpenGLView, which
needs a call to -setWantsBestResolutionOpenGLSurface:YES to opt in to
this mode.

This CL pokes at Qt internals to do this call -- due to QGLView.cc only
allowing C++ code, this is done by explicitly calling out to the
Objective-C runtime.

The reason this mode needs an explicit opt-in is because it requires
expicit code to support retina mode in OpenGL. OpenGL is pixel-based,
while Cocoa (and possibly Qt) use logical view coordinates, where one
coordinate corresponds to two physical pixels on retina displays.
Because of this, several parameters passed to OpenGL need to explicitly
be scaled by the view scale factor.

I did this in the visually obvious places in this patch, but I fairly
certainly missed a few places. I also didn't test image saving, which
might be broken to. (I also didn't test with a 32 bit build, which has
to use a slightly different Obj-C API, but that part has a chance of
being correct.)

Another thing this patch doesn't handle is dynamic scale factor changes,
which happen when dragging an OpenSCAD window from a retina display to
an external display. It's possible that it happens to work, but I
haven't tested it.
bbc6167
nico added some commits Mar 23, 2013
@nico nico Don't draw axis labels at half size in retina mode. dd17a60
@nico nico Fix 'Export as Image' in retina mode.
QGLWidget::grabFrameBuffer() doesn't do the right thing if it's tricked
into retina mode.

Most of the code in this patch was taken from Qt's qgl.cpp.
09f3b2a
@kintel
openscad member

Thanks a lot for looking into this!
I want a retina Mac, but my conscience tells me to wait a bit before upgrading :/

@kintel
openscad member

hey nico!

Did you get a chance to look into this further?
Still not having a retina Mac to test with ...

@nico

I've been using OpenSCAD with this patch for the last month. It seems to work fine with the two additional fixes. If you want, I can remove the "DO NOT MERGE" line from the description.

There are two theoretical issues with this patch:
1.) Qt 4 doesn't officially support retina drawing, so this patch does some stuff that uses private Qt apis in a way that's not supported.
2.) It adds a "scale factor" variable, and all GL code needs to remember to scale pixel-sized stuff (such as line widths) by that. (Geometry is fine, as the pixel scale factor is already embedded in the viewport transform). I think I updated all calling sites that needed changing.

If you can live with these two points, go ahead and merge :-)

@nico

Oh, and I still didn't test if dragging a window from a retina screen to a normal screen and back (for lack of external monitor).

@kintel
openscad member

I wasn't ready to merge the Qt-4.8 hack, but I've enabled the equivalent functionality for Qt5 builds

@kintel kintel closed this Feb 5, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment