Qt5.6: поддержка высокого разрешения и OpenGL (OpenSceneGraph)

У меня есть минимальное приложение, которое используетQOpenGLWidget это интегрирует библиотеку оболочки OpenGL (OpenSceneGraph). Я пытаюсь понять, как правильно использовать поддержку Qt5.6 для экранов с высоким DPI при работе с контентом OpenGL, как я использую.

мойmain() Функция имеет следующий код:

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();
}

QtOSGWidget происходит отQOpenGLWidget с контентом OpenSceneGraph: я используюosgViewer::GraphicsWindowEmbedded сделать мою простую сцену

Чтобы объединить OSG с Qt, я переопределяю*GL() методы:paintGL(), resizeGL() а такжеinitializeGL(), Я следую документации Qt о том, что каждый из*GL() методы должны содержать, т.е.

paintGL() гарантирует, что зритель обновленresizeGL() обеспечивает правильное изменение размера графического окна (вместе с камерой и окном просмотра);initializeGL() гарантирует, что состояние OpenGL инициализировано.Я также переопределил события мыши Qt, чтобы передавать события в OSG

Когда я запускаю свой пример на экране с нормальным разрешением или сQApplication::setAttribute(Qt::AA_DisableHighDpiScaling);сцена выглядит так, как должна:

Кроме того, когда я манипулирую видом камеры, координаты мыши фиксируются правильно.

Тем не менее, когда я включаю параметр высокого разрешения, это то, что я получаю:

Координаты мыши для событий также масштабируются и не передаются в обработчик событий OpenSceneGraph правильно.

Как вы можете видеть, размер графического окна не масштабируется Qt. Вероятно, из-за способа, которым я настроил размер:

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());
}

Этот размер не масштабируется Qt. То же самое происходит с координатами событий мыши.

Мой вопрос: есть ли способ узнать, до какого размера будет выполнено масштабирование, чтобы сделатьresizeGL() правильно? Или как правильно решить проблему?

Обновление / Решение с использованием масштабирования вручную: благодаря ответу @AlexanderVX я разобрался с решением для масштабирования. Во-первых, мне нужно знать некоторые эталонные значения DPI в измерениях X и Y. Затем я вычисляю координаты масштабирования на основе этого и передаю их в мой виджетQtOSGWidget, Итак, кодmain() должен содержать:

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.

Затем, всякий раз, когда я ссылаюсь на функции определения размера, которые необходимо передать содержимому OpenSceneGraph (OpenGL), я должен выполнять масштабирование, например:

// 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);

Окончательное обновление: поскольку целевой платформой моего приложения является Windows 7-10, гораздо разумнее придерживаться предложенного ответа @AlexanderV (вторая часть), то есть использоватьSetProcessDPIAware() функция.

Ответы на вопрос(1)

Ваш ответ на вопрос