From 0de1493de3f23a5f2efc9b89649e84d0f9c53e0a Mon Sep 17 00:00:00 2001 From: hidefuku Date: Wed, 12 Apr 2017 06:20:37 +0900 Subject: [PATCH] Fixed scaling bug on a HiDPI display. --- src/core/CameraInfo.cpp | 12 ++++++++++-- src/core/CameraInfo.h | 7 ++++++- src/core/LayerNode.cpp | 4 ++-- src/ctrl/Exporter.cpp | 2 +- src/gui/Main.cpp | 1 + src/gui/MainDisplayWidget.cpp | 29 +++++++++++++++++++---------- src/gui/MainDisplayWidget.h | 2 ++ 7 files changed, 41 insertions(+), 16 deletions(-) diff --git a/src/core/CameraInfo.cpp b/src/core/CameraInfo.cpp index 0189e890..87176cf6 100644 --- a/src/core/CameraInfo.cpp +++ b/src/core/CameraInfo.cpp @@ -6,7 +6,8 @@ namespace core { CameraInfo::CameraInfo() - : mScreenSize() + : mDevicePixelRatio(1.0) + , mScreenSize() , mImageSize() , mCenter() , mLeftTopPos() @@ -15,8 +16,10 @@ CameraInfo::CameraInfo() { } -void CameraInfo::reset(const QSize& aScreenSize, const QSize& aImageSize, const QPoint& aLeftTopPos) +void CameraInfo::reset(const QSize& aScreenSize, double aDpr, + const QSize& aImageSize, const QPoint& aLeftTopPos) { + mDevicePixelRatio = aDpr; mScreenSize = aScreenSize; mImageSize = aImageSize; mScale = 1.0f; @@ -25,6 +28,11 @@ void CameraInfo::reset(const QSize& aScreenSize, const QSize& aImageSize, const mCenter = mLeftTopPos + centerOffset(); } +void CameraInfo::setDevicePixelRatio(double aRatio) +{ + mDevicePixelRatio = aRatio; +} + void CameraInfo::setLeftTopPos(const QVector2D& aPos) { mLeftTopPos = aPos; diff --git a/src/core/CameraInfo.h b/src/core/CameraInfo.h index ae442a4e..ca5afbd8 100644 --- a/src/core/CameraInfo.h +++ b/src/core/CameraInfo.h @@ -17,8 +17,10 @@ class CameraInfo public: CameraInfo(); - void reset(const QSize& aScreenSize, const QSize& aImageSize, const QPoint& aLeftTopPos); + void reset(const QSize& aScreenSize, double aDpr, + const QSize& aImageSize, const QPoint& aLeftTopPos); + void setDevicePixelRatio(double aRatio); inline void setScreenWidth(int aWidth) { mScreenSize.setWidth(aWidth); } inline void setScreenHeight(int aHeight) { mScreenSize.setHeight(aHeight); } inline void setScreenSize(const QSize& aSize) { mScreenSize = aSize; } @@ -28,9 +30,11 @@ class CameraInfo void setScale(float aScale); void setRotate(float aRadian); + inline double devicePixelRatio() const { return mDevicePixelRatio; } inline int screenWidth() const { return mScreenSize.width(); } inline int screenHeight() const { return mScreenSize.height(); } inline QSize screenSize() const { return mScreenSize; } + inline QSize deviceScreenSize() const { return mScreenSize * mDevicePixelRatio; } QVector2D screenCenter() const; inline QSize imageSize() const { return mImageSize; } @@ -69,6 +73,7 @@ class CameraInfo return 0.5f * QVector2D(mImageSize.width(), mImageSize.height()); } + double mDevicePixelRatio; QSize mScreenSize; QSize mImageSize; QVector2D mCenter; diff --git a/src/core/LayerNode.cpp b/src/core/LayerNode.cpp index 42318c43..17b4f4f8 100644 --- a/src/core/LayerNode.cpp +++ b/src/core/LayerNode.cpp @@ -248,7 +248,7 @@ void LayerNode::renderClipper( shader.setAttributeArray("inTexCoord", mCurrentMesh->texCoords(), mCurrentMesh->vertexCount()); shader.setUniformValue("uViewMatrix", viewMatrix); - shader.setUniformValue("uScreenSize", QSizeF(aInfo.camera.screenSize())); + shader.setUniformValue("uScreenSize", QSizeF(aInfo.camera.deviceScreenSize())); shader.setUniformValue("uImageSize", QSizeF(textureSize)); shader.setUniformValue("uTexCoordOffset", texCoordOffset); shader.setUniformValue("uColor", color); @@ -388,7 +388,7 @@ void LayerNode::renderShape( shader.setAttributeArray("inTexCoord", mCurrentMesh->texCoords(), mCurrentMesh->vertexCount()); shader.setUniformValue("uViewMatrix", viewMatrix); - shader.setUniformValue("uScreenSize", QSizeF(aInfo.camera.screenSize())); + shader.setUniformValue("uScreenSize", QSizeF(aInfo.camera.deviceScreenSize())); shader.setUniformValue("uImageSize", QSizeF(textureSize)); shader.setUniformValue("uTexCoordOffset", texCoordOffset); shader.setUniformValue("uColor", color); diff --git a/src/ctrl/Exporter.cpp b/src/ctrl/Exporter.cpp index 800ba6bd..9e305eff 100644 --- a/src/ctrl/Exporter.cpp +++ b/src/ctrl/Exporter.cpp @@ -568,7 +568,7 @@ bool Exporter::update() // render core::RenderInfo renderInfo; - renderInfo.camera.reset(originSize, originSize, QPoint()); + renderInfo.camera.reset(originSize, 1.0, originSize, QPoint()); renderInfo.time = timeInfo; renderInfo.framebuffer = mFramebuffers.front()->handle(); renderInfo.dest = mFramebuffers.front()->texture(); diff --git a/src/gui/Main.cpp b/src/gui/Main.cpp index 64738098..743286f3 100644 --- a/src/gui/Main.cpp +++ b/src/gui/Main.cpp @@ -102,6 +102,7 @@ int entryPoint(int argc, char *argv[]) // create qt application QApplication app(argc, argv); XC_DEBUG_REPORT() << "exe path =" << app.applicationFilePath(); + app.setAttribute(Qt::AA_UseHighDpiPixmaps); // application path #if defined(Q_OS_MAC) diff --git a/src/gui/MainDisplayWidget.cpp b/src/gui/MainDisplayWidget.cpp index cdeb0fca..741eec74 100644 --- a/src/gui/MainDisplayWidget.cpp +++ b/src/gui/MainDisplayWidget.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include "XC.h" #include "util/Finally.h" #include "gl/Util.h" @@ -40,6 +41,7 @@ MainDisplayWidget::MainDisplayWidget(ViaPoint& aViaPoint, QWidget* aParent) , mCanvasMover() , mMovingCanvasByTool(false) , mMovingCanvasByKey(false) + , mDevicePixelRatio(1.0) { #ifdef USE_GL_CORE_PROFILE // setup opengl format @@ -134,6 +136,7 @@ void MainDisplayWidget::setProject(core::Project* aProject) { mProject = aProject->pointee(); mRenderInfo = &(static_cast(mProject->hook())->renderInfo()); + mRenderInfo->camera.setDevicePixelRatio(this->devicePixelRatioF()); mRenderInfo->camera.setScreenSize(this->size()); mRenderInfo->camera.setImageSize(mProject->attribute().imageSize()); mCanvasMover.setCamera(&(mRenderInfo->camera)); @@ -221,16 +224,18 @@ void MainDisplayWidget::initializeGL() mDefaultVAO->bind(); // keep binding #endif + mDevicePixelRatio = this->devicePixelRatioF(); + // create framebuffer for display - mFramebuffer.reset(new QOpenGLFramebufferObject(this->size())); + mFramebuffer.reset(new QOpenGLFramebufferObject(deviceSize())); // create clipping buffer mClippingFrame.reset(new core::ClippingFrame()); - mClippingFrame->resize(this->size()); + mClippingFrame->resize(deviceSize()); // create texturizer for destination colors of the framebuffer mDestinationTexturizer.reset(new core::DestinationTexturizer()); - mDestinationTexturizer->resize(this->size()); + mDestinationTexturizer->resize(deviceSize()); // create texture drawer for copying framebuffer to display mTextureDrawer.reset(new gl::EasyTextureDrawer()); @@ -262,7 +267,7 @@ void MainDisplayWidget::paintGL() } // setup - gl::Util::setViewportAsActualPixels(this->size()); + gl::Util::setViewportAsActualPixels(deviceSize()); gl::Util::clearColorBuffer(0.25f, 0.25f, 0.25f, 1.0f); gl::Util::resetRenderState(); GL_CHECK_ERROR(); @@ -342,25 +347,29 @@ void MainDisplayWidget::paintEvent(QPaintEvent* aEvent) void MainDisplayWidget::resizeGL(int w, int h) { - const QSize newSize(w, h); + // currrent device pixel ratio (Attention that it is variable.) + mDevicePixelRatio = this->devicePixelRatioF(); + const QSize devSize(mDevicePixelRatio * w, mDevicePixelRatio * h); // device pixel size + const QSize absSize(w, h); // abstract pixel size if (mRenderInfo) { - mRenderInfo->camera.setScreenSize(newSize); + mRenderInfo->camera.setDevicePixelRatio(mDevicePixelRatio); + mRenderInfo->camera.setScreenSize(absSize); mCanvasMover.onScreenResized(); } mFramebuffer.reset(); - mFramebuffer.reset(new QOpenGLFramebufferObject(w, h)); + mFramebuffer.reset(new QOpenGLFramebufferObject(devSize.width(), devSize.height())); mClippingFrame.reset(); mClippingFrame.reset(new core::ClippingFrame()); - mClippingFrame->resize(newSize); + mClippingFrame->resize(devSize); - mDestinationTexturizer->resize(newSize); + mDestinationTexturizer->resize(devSize); if (mProjectTabBar) { - mProjectTabBar->updateTabPosition(newSize); + mProjectTabBar->updateTabPosition(absSize); } GL_CHECK_ERROR(); } diff --git a/src/gui/MainDisplayWidget.h b/src/gui/MainDisplayWidget.h index 9cf6d4cf..9f7b3a53 100644 --- a/src/gui/MainDisplayWidget.h +++ b/src/gui/MainDisplayWidget.h @@ -73,6 +73,7 @@ class MainDisplayWidget : public QOpenGLWidget virtual void tabletEvent(QTabletEvent* event); void updateCursor(); + QSize deviceSize() const { return this->size() * mDevicePixelRatio; } ViaPoint& mViaPoint; gl::DeviceInfo mGLDeviceInfo; @@ -95,6 +96,7 @@ class MainDisplayWidget : public QOpenGLWidget CanvasMover mCanvasMover; bool mMovingCanvasByTool; bool mMovingCanvasByKey; + double mDevicePixelRatio; }; } // namespace gui