QT OpenGLWidget高分屏適配時出現的問題

參考官方文檔,爲了解決4K屏幕顯示QT界面時出現窗口變小分辨率不匹配的問題,咱們能夠在 QApplication a(argc, argv); 這句以前添加:html

#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
	QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
Constant Value Description
Qt::AA_EnableHighDpiScaling 20 Enables high-DPI scaling in Qt on supported platforms (see also High DPI Displays). Supported platforms are X11, Windows and Android. Enabling makes Qt scale the main (device independent) coordinate system according to display scale factors provided by the operating system. This corresponds to setting the QT_AUTO_SCREEN_SCALE_FACTOR environment variable to 1. This attribute must be set before QGuiApplication is constructed. This value was added in Qt 5.6.

運行結果顯示其餘界面均運行正常,可是在 QOpenGLWidget 內,渲染的圖像只顯示在左下角,佔整個渲染區域的 1/4 左右。c++

其緣由是啓用 AA_EnableHighDpiScaling 後,QOpenGLWidget 內部的 OpenGL 不歸屬於 QT 的縮放範圍,因此咱們須要本身縮放 QOpenGLWidget 內的像素尺寸。app

解決方案

解決的方法就是自行獲取 devicePixelRatio,手動進行縮放。實現的方式大體有兩種,具體取決於你 QOpenGLWidget 裁剪的方式。ratio 能夠經過 QApplication::desktop()->devicePixelRatio(); 獲取。ide

若是是經過 resizeGL(int width, int height) 裁剪,縮放就應寫在其中。
如下代碼參考了博文 https://blog.csdn.net/genispan/article/details/107864829ui

void QOpenGLWidget::resizeGL(int width, int height)
{
	makeCurrent();
	//參數X,Y指定了視見區域的左下角在窗口中的位置,通常狀況下爲(0,0),Width和Height指定了視見區域的寬度和高度。
    int ratio = QApplication::desktop()->devicePixelRatio();
	glViewport(0, 0, (GLint)width*ratio, (GLint)height*ratio);
	/*
	glMatrixMode設置當前矩陣模式:
	GL_MODEVIEW,對模型視景矩陣堆棧應用隨後的矩陣操做。
	GL_PROJECTION,對投影矩陣應用隨後的矩陣操做。
	GLTEXTURE,對紋理矩陣堆棧應用隨後的矩陣操做。
	*/
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	//glOrtho 參數分別表明(左下角x座標,右上角x座標,左下角y座標,右上角y座標)——座標全相對於窗口左下角--原點)
	glOrtho(0, width*ratio, -height*ratio, 0, 0, 1); ///防止圖像上下翻轉
	glMatrixMode(GL_MODELVIEW);
	recalculatePosition();
	emit imageSizeChanged(mRenderWidth, mRenderHeight);
	updateScene();
}

裁剪實如今對輸入紋理的處理的話,相應的代碼應該寫到 paintGL() 內:spa

void QOpenGLWidget::initializeGL(){
    ...
    QScreen *pScreen = QApplication::desktop()->screen(screenNum)->screen();
	static const qreal NORMAL_DPI = 95.863739404014453;
	auto xFactor = pScreen->logicalDotsPerInchX() / NORMAL_DPI;
	auto yFactor = pScreen->logicalDotsPerInchY() / NORMAL_DPI;
	auto ratio = pScreen->devicePixelRatio();
	_xRatio = xFactor * ratio;
	_yRatio = yFactor * ratio;
}
void QOpenGLWidget::paintGL() {
    ...
    widgetWidth *= _xRatio;
	widgetHeight *= _yRatio;
    //QImage對象img即爲輸入紋理
    auto img = currImg;
	if (!currImg.isNull()) {
		img = img.scaled(widgetWidth, widgetHeight, Qt::KeepAspectRatio);
		img = img.copy((img.width() - widgetWidth) / 2, (img.height() - widgetHeight) / 2, widgetWidth, widgetHeight);
    }
    ...
}

裁剪事後QOpenGLWidget應該就能正常顯示了。.net

相關文章
相關標籤/搜索