QtOSG
QtOSG copied to clipboard
Adjust for Retina and High DPI screens
When you set viewports, you need to multiply the sizes with devicePixelRatio()
to ensure the view is not "half the size". This happens in many other OSG/Qt examples as well. This is only a problem when running on Retina Resolution (= double the resolution). When I switch to a non-retina resolution, the problem is gone.
This has to be repeated a few times. I did adjust it inside the OSGWidget::onResize()
handler, but it happens in a few other places too.
void OSGWidget::onResize( int width, int height )
{
std::vector<osg::Camera*> cameras;
viewer_->getCameras( cameras );
assert( cameras.size() == 2 );
cameras[0]->setViewport( 0, 0, width / 2 * this->devicePixelRatio(), height * this->devicePixelRatio());
cameras[1]->setViewport( width / 2 * this->devicePixelRatio(), 0, width / 2 * this->devicePixelRatio(), height * this->devicePixelRatio());
}
However, when doing this, the Pickhandler is not working anymore. I guess this is related to the problem above, since the Pickhandler runs OK on a non-retina resolution.
Thanks for reporting this! I will take a look at this. Since I do not have access to a retina display, would you kindly be available for testing?
By the way: is this something time-critical for you? I am presently quite swamped with other work, so I cannot guarantee that I will find the time to address this rapidly.
Not time critical. It's a side project, but as I bump into the same problems in many examples, I can as well contribute a bit.
Thanks for your patience! I started to implement support for high-DPI screens as you suggested. I have added devicePixelRatio()
at multiple places. Would you like to test with the current revision?
Current revision has solved the retina problems for me.
While viewport display is now correct and the errors (mentioned in other case) are gone, the "pickhandler" code is not working correctly, yet. I can pick a point above the "sphere" in the viewport and picks at the bottom half seem not to be recognised. I guess you have to compensate a bit for hiDPI usage.
To me it seems that the picks are happening half a window upwards (but horizontally they seem correct).
Selection handling has been fixed in commit b0ea8eddce3ce14287a1bf292be0a9ef50a4e296. Pick handling still needs some attention, though.
I am observing something strange: do you get negative coordinates in the pick handler as well on a high-DPI display? I temporarily added the following code in the handle()
function:
std::cout << ea.getX() << "," << ea.getY() << "," << devicePixelRatio_ << "\n";
Under Linux, the minimum value is achieved in the bottom left corner of the window with (0,0). Under Mac OS X with a high-DPI display, I obtain negative y-values. Can you confirm this behaviour? If so, this may be the reason why pick handling does not work correctly.
I can confirm. In high-DPI, the "y=0" is in the middle of the view. On normal DPI, "y=0" is at the bottom. Maybe done the pixel ratio mapping once too much? Could be trivial to remap, but I'm a bit lost in the different mappings done already (between OS/qt/osg).
Selection handling (the rectangle selection) seems to work correct.
OK, thank you! I will try to prepare a small example program in order to figure out whether this is an issue of OSG or not. Did this work prior to the pixel ratio mappings? Since I am only multiplying values here, I do not yet see how this offset could be created, to be honest.
I will get back to you if I have something to report :smile: