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()
функция.