Qt5.6: alto soporte de DPI y OpenGL (OpenSceneGraph)

Tengo una aplicación mínima que usaQOpenGLWidget que integra una biblioteca de contenedor OpenGL (OpenSceneGraph). Estoy tratando de descubrir cómo usar correctamente el soporte Qt5.6 para pantallas de DPI alto cuando trato con contenido OpenGL como el que uso.

Mimain() La función tiene el siguiente código:

int main(int argc, char** argv)
{
    // DPI support is on
    QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QApplication app(argc, argv);
    QMainWindow window;

    // QOpenGLWidget with OpenSceneGraph content
    QtOSGWidget* widget = new QtOSGWidget();

    window.setCentralWidget(widget);
    window.show();
    return app.exec();
}

losQtOSGWidget se deriva deQOpenGLWidget con contenido OpenSceneGraph: yo usoosgViewer::GraphicsWindowEmbedded para representar mi escena simple

Para fusionar OSG con Qt, redefiní el*GL() métodos:paintGL(), resizeGL() yinitializeGL(). Sigo los documentos de Qt sobre cada uno de los*GL() los métodos deben contener, es decir:

paintGL() se asegura de que el visor esté actualizadoresizeGL() se asegura de que la ventana gráfica se redimensione correctamente (junto con la cámara y la ventana gráfica);initializeGL() se asegura de que el estado de OpenGL esté inicializado.También redefiní los eventos del mouse Qt para pasar los eventos a OSG

Cuando ejecuto mi ejemplo en la pantalla de resolución normal, o conQApplication::setAttribute(Qt::AA_DisableHighDpiScaling);, la escena parece que debería:

Además, cuando manipulo la vista de la cámara, las coordenadas del mouse se capturan correctamente.

Sin embargo, cuando configuro la opción de DPI alto, esto es lo que obtengo:

Las coordenadas del mouse para los eventos también se escalan y no se pasan correctamente al controlador de eventos de OpenSceneGraph.

Como puede ver, Qt no escala el tamaño de la ventana de gráficos. Probablemente se deba a la forma en que configuré el tamaño:

virtual void resizeGL( int width, int height ) 
{
    // resize event is passed to OSG
    this->getEventQueue()->windowResize(this->x(), this->y(), width, height);

    // graphics window resize
    m_graphicsWindow->resized(this->x(), this->y(), width, height);

    // camera viewport
    osg::Camera* camera = m_viewer->getCamera();
    camera->setViewport(0, 0, this->width(), this->height());
}

Ese tamaño no está escalado por Qt. Lo mismo sucede con las coordenadas de eventos del mouse.

Mi pregunta: ¿hay alguna manera de saber a qué tamaño se realizará el escalado para hacerlo?resizeGL() ¿correctamente? ¿O cuál es la forma correcta de lidiar con el problema?

Actualización / Solución usando el escalado a mano: gracias a la respuesta de @AlexanderVX, descubrí la solución de escala. Al principio, necesito conocer algunos valores de referencia de DPI en las dimensiones X e Y. Luego calculo las coordenadas de escala en función de eso y las paso a mi widgetQtOSGWidget. Entonces, el código de lamain() tiene que contener:

QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication app(argc, argv);

int x = QApplication::desktop()->physicalDpiX();
int y = QApplication::desktop()->physicalDpiY();
// values 284 and 285 are the reference values
double scaleX = 284.0/double(x);
double scaleY = 285.0/double(y);

QMainWindow window;
QtOSGWidget* widget = new QtOSGWidget(scaleX, scaleY, &window);
// etc.

Luego, cada vez que me refiero a las funciones de tamaño que debían pasarse al contenido de OpenSceneGraph (OpenGL), tengo que escalar, por ejemplo:

// resizeGL example
this->getEventQueue()->windowResize(this->x()*m_scaleX, this->y() * m_scaleY, width*m_scaleX, height*m_scaleY);

// mouse event example
this->getEventQueue()->mouseButtonPress(event->x()*m_scaleX, event->y()*m_scaleY, button);

Actualización final: dado que la plataforma de destino de mi aplicación es Windows 7-10, tiene mucho más sentido seguir con la respuesta propuesta de @AlexanderV (segunda parte), es decir, usarSetProcessDPIAware() función.

Respuestas a la pregunta(1)

Su respuesta a la pregunta