Skip to content

Commit 9f39b81

Browse files
committed
Enable Qt::AA_EnableHighDpiScaling attribute
1 parent 9224eda commit 9f39b81

8 files changed

Lines changed: 167 additions & 106 deletions

File tree

occt-qopenglwidget/OcctQOpenGLWidgetViewer.cpp

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
#include <AIS_Shape.hxx>
2121
#include <AIS_ViewCube.hxx>
2222
#include <Aspect_DisplayConnection.hxx>
23-
#include <Aspect_NeutralWindow.hxx>
2423
#include <BRepPrimAPI_MakeBox.hxx>
2524
#include <Message.hxx>
2625
#include <OpenGl_GraphicDriver.hxx>
@@ -78,7 +77,7 @@ OcctQOpenGLWidgetViewer::OcctQOpenGLWidgetViewer(QWidget* theParent)
7877
Graphic3d_RenderingParams::PerfCounters_FrameRate | Graphic3d_RenderingParams::PerfCounters_Triangles);
7978

8079
// Qt widget setup
81-
setAttribute(Qt::WA_AcceptTouchEvents); // necessary to recieve QTouchEvent events
80+
setAttribute(Qt::WA_AcceptTouchEvents); // necessary to receive QTouchEvent events
8281
setMouseTracking(true);
8382
setBackgroundRole(QPalette::NoRole); // or NoBackground
8483
setFocusPolicy(Qt::StrongFocus); // set focus policy to threat QContextMenuEvent from keyboard
@@ -150,13 +149,14 @@ void OcctQOpenGLWidgetViewer::initializeGL()
150149
const Graphic3d_Vec2i aViewSize(rect().right() - rect().left(), rect().bottom() - rect().top());
151150

152151
const bool isFirstInit = myView->Window().IsNull();
153-
if (!OcctGlTools::InitializeGlWindow(myView, aNativeWin, aViewSize))
152+
if (!OcctGlTools::InitializeGlWindow(myView, aNativeWin, aViewSize, devicePixelRatioF()))
154153
{
155154
QMessageBox::critical(0, "Failure", "OpenGl_Context is unable to wrap OpenGL context");
156155
QApplication::exit(1);
157156
return;
158157
}
159158

159+
makeCurrent(); // restore Qt framebuffer
160160
dumpGlInfo(true, true);
161161
if (isFirstInit)
162162
{
@@ -188,7 +188,8 @@ bool OcctQOpenGLWidgetViewer::event(QEvent* theEvent)
188188
for (const QTouchEvent::TouchPoint& aQTouch : aQTouchEvent->touchPoints())
189189
{
190190
const Standard_Size aTouchId = aQTouch.id();
191-
const Graphic3d_Vec2d aNewPos2d(aQTouch.pos().x(), aQTouch.pos().y());
191+
const Graphic3d_Vec2d aNewPos2d =
192+
myView->Window()->ConvertPointToBacking(Graphic3d_Vec2d(aQTouch.pos().x(), aQTouch.pos().y()));
192193
const Graphic3d_Vec2i aNewPos2i = Graphic3d_Vec2i(aNewPos2d + Graphic3d_Vec2d(0.5));
193194
if (aQTouch.state() == Qt::TouchPointPressed
194195
&& aNewPos2i.minComp() >= 0)
@@ -262,10 +263,11 @@ void OcctQOpenGLWidgetViewer::mousePressEvent(QMouseEvent* theEvent)
262263
return; // skip mouse events emulated by system from screen touches
263264

264265
theEvent->accept();
265-
const Graphic3d_Vec2i aPnt(theEvent->pos().x(), theEvent->pos().y());
266+
const Graphic3d_Vec2d aPnt2d(theEvent->pos().x(), theEvent->pos().y());
267+
const Graphic3d_Vec2i aPnt2i(myView->Window()->ConvertPointToBacking(aPnt2d) + Graphic3d_Vec2d(0.5));
266268
const Aspect_VKeyMouse aButtons = OcctQtTools::qtMouseButtons2VKeys(theEvent->buttons());
267269
const Aspect_VKeyFlags aFlags = OcctQtTools::qtMouseModifiers2VKeys(theEvent->modifiers());
268-
if (AIS_ViewController::UpdateMouseButtons(aPnt, aButtons, aFlags, false))
270+
if (AIS_ViewController::UpdateMouseButtons(aPnt2i, aButtons, aFlags, false))
269271
updateView();
270272
}
271273

@@ -279,10 +281,11 @@ void OcctQOpenGLWidgetViewer::mouseReleaseEvent(QMouseEvent* theEvent)
279281
return;
280282

281283
theEvent->accept();
282-
const Graphic3d_Vec2i aPnt(theEvent->pos().x(), theEvent->pos().y());
284+
const Graphic3d_Vec2d aPnt2d(theEvent->pos().x(), theEvent->pos().y());
285+
const Graphic3d_Vec2i aPnt2i(myView->Window()->ConvertPointToBacking(aPnt2d) + Graphic3d_Vec2d(0.5));
283286
const Aspect_VKeyMouse aButtons = OcctQtTools::qtMouseButtons2VKeys(theEvent->buttons());
284287
const Aspect_VKeyFlags aFlags = OcctQtTools::qtMouseModifiers2VKeys(theEvent->modifiers());
285-
if (AIS_ViewController::UpdateMouseButtons(aPnt, aButtons, aFlags, false))
288+
if (AIS_ViewController::UpdateMouseButtons(aPnt2i, aButtons, aFlags, false))
286289
updateView();
287290
}
288291

@@ -299,10 +302,11 @@ void OcctQOpenGLWidgetViewer::mouseMoveEvent(QMouseEvent* theEvent)
299302
return; // skip mouse events emulated by system from screen touches
300303

301304
theEvent->accept();
302-
const Graphic3d_Vec2i aNewPos(theEvent->pos().x(), theEvent->pos().y());
305+
const Graphic3d_Vec2d aPnt2d(theEvent->pos().x(), theEvent->pos().y());
306+
const Graphic3d_Vec2i aPnt2i(myView->Window()->ConvertPointToBacking(aPnt2d) + Graphic3d_Vec2d(0.5));
303307
const Aspect_VKeyMouse aButtons = OcctQtTools::qtMouseButtons2VKeys(theEvent->buttons());
304308
const Aspect_VKeyFlags aFlags = OcctQtTools::qtMouseModifiers2VKeys(theEvent->modifiers());
305-
if (AIS_ViewController::UpdateMousePosition(aNewPos, aButtons, aFlags, false))
309+
if (AIS_ViewController::UpdateMousePosition(aPnt2i, aButtons, aFlags, false))
306310
updateView();
307311
}
308312

@@ -317,15 +321,16 @@ void OcctQOpenGLWidgetViewer::wheelEvent(QWheelEvent* theEvent)
317321

318322
theEvent->accept();
319323
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
320-
const Graphic3d_Vec2i aPos(Graphic3d_Vec2d(theEvent->position().x(), theEvent->position().y()));
324+
const Graphic3d_Vec2d aPnt2d(theEvent->position().x(), theEvent->position().y());
321325
#else
322-
const Graphic3d_Vec2i aPos(theEvent->pos().x(), theEvent->pos().y());
326+
const Graphic3d_Vec2d aPnt2d(theEvent->pos().x(), theEvent->pos().y());
323327
#endif
328+
const Graphic3d_Vec2i aPnt2i(myView->Window()->ConvertPointToBacking(aPnt2d) + Graphic3d_Vec2d(0.5));
324329

325330
#if (OCC_VERSION_HEX >= 0x070700)
326331
if (!myView->Subviews().IsEmpty())
327332
{
328-
Handle(V3d_View) aPickedView = myView->PickSubview(aPos);
333+
Handle(V3d_View) aPickedView = myView->PickSubview(aPnt2i);
329334
if (!aPickedView.IsNull() && aPickedView != myFocusView)
330335
{
331336
// switch input focus to another subview
@@ -336,7 +341,7 @@ void OcctQOpenGLWidgetViewer::wheelEvent(QWheelEvent* theEvent)
336341
}
337342
#endif
338343

339-
if (AIS_ViewController::UpdateZoom(Aspect_ScrollDelta(aPos, double(theEvent->angleDelta().y()) / 8.0)))
344+
if (AIS_ViewController::UpdateZoom(Aspect_ScrollDelta(aPnt2i, double(theEvent->angleDelta().y()) / 8.0)))
340345
updateView();
341346
}
342347

@@ -357,16 +362,19 @@ void OcctQOpenGLWidgetViewer::paintGL()
357362
if (myView.IsNull() || myView->Window().IsNull())
358363
return;
359364

360-
Graphic3d_Vec2i aViewSizeOld; myView->Window()->Size(aViewSizeOld.x(), aViewSizeOld.y());
361-
362-
const Aspect_Drawable aNativeWin = OcctGlTools::GetGlNativeWindow((Aspect_Drawable)winId());
363-
if (myView->Window()->NativeHandle() != aNativeWin)
365+
const double aDevPixelRatioOld = myView->Window()->DevicePixelRatio();
366+
if (myView->Window()->NativeHandle() != OcctGlTools::GetGlNativeWindow((Aspect_Drawable)winId()))
364367
{
365368
// workaround window recreation done by Qt on monitor (QScreen) disconnection
366369
Message::SendWarning() << "Native window handle has changed by QOpenGLWidget!";
367370
initializeGL();
368-
return;
369371
}
372+
else if (devicePixelRatioF() != aDevPixelRatioOld)
373+
{
374+
initializeGL();
375+
}
376+
377+
Graphic3d_Vec2i aViewSizeOld; myView->Window()->Size(aViewSizeOld.x(), aViewSizeOld.y());
370378

371379
// wrap FBO created by QOpenGLFramebufferObject
372380
if (!OcctGlTools::InitializeGlFbo(myView))
@@ -377,7 +385,7 @@ void OcctQOpenGLWidgetViewer::paintGL()
377385
}
378386

379387
Graphic3d_Vec2i aViewSizeNew; myView->Window()->Size(aViewSizeNew.x(), aViewSizeNew.y());
380-
if (aViewSizeNew != aViewSizeOld)
388+
if (aViewSizeNew != aViewSizeOld || myView->Window()->DevicePixelRatio() != aDevPixelRatioOld)
381389
dumpGlInfo(true, false);
382390

383391
// reset global GL state from Qt before redrawing OCCT

occt-qt-tools/OcctGlTools.cpp

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
#include "OcctGlTools.h"
88

9-
#include <Aspect_NeutralWindow.hxx>
109
#include <OpenGl_GraphicDriver.hxx>
1110
#include <OpenGl_GlCore20.hxx>
1211
#include <OpenGl_FrameBuffer.hxx>
@@ -74,7 +73,8 @@ Aspect_Drawable OcctGlTools::GetGlNativeWindow(Aspect_Drawable theNativeWin)
7473
// ================================================================
7574
bool OcctGlTools::InitializeGlWindow(const Handle(V3d_View)& theView,
7675
const Aspect_Drawable theNativeWin,
77-
const Graphic3d_Vec2i& theSize)
76+
const Graphic3d_Vec2i& theSize,
77+
const double thePixelRatio)
7878
{
7979
const Aspect_Drawable aNativeWin = GetGlNativeWindow(theNativeWin);
8080

@@ -86,21 +86,25 @@ bool OcctGlTools::InitializeGlWindow(const Handle(V3d_View)& theView,
8686
return false;
8787
}
8888

89-
Handle(Aspect_NeutralWindow) aWindow = Handle(Aspect_NeutralWindow)::DownCast(theView->Window());
90-
if (!aWindow.IsNull())
89+
Handle(OcctNeutralWindow) aWindow = Handle(OcctNeutralWindow)::DownCast(theView->Window());
90+
if (aWindow.IsNull())
9191
{
92-
aWindow->SetNativeHandle(aNativeWin);
93-
aWindow->SetSize(theSize.x(), theSize.y());
94-
theView->SetWindow(aWindow, aGlCtx->RenderingContext());
92+
aWindow = new OcctNeutralWindow();
93+
aWindow->SetVirtual(true);
9594
}
96-
else
95+
aWindow->SetNativeHandle(aNativeWin);
96+
aWindow->SetSize(theSize.x(), theSize.y());
97+
aWindow->SetDevicePixelRatio(thePixelRatio);
98+
theView->SetWindow(aWindow, aGlCtx->RenderingContext());
99+
theView->MustBeResized();
100+
theView->Invalidate();
101+
#if (OCC_VERSION_HEX >= 0x070700)
102+
for (const Handle(V3d_View)& aSubviewIter : theView->Subviews())
97103
{
98-
aWindow = new Aspect_NeutralWindow();
99-
aWindow->SetVirtual(true);
100-
aWindow->SetNativeHandle(aNativeWin);
101-
aWindow->SetSize(theSize.x(), theSize.y());
102-
theView->SetWindow(aWindow, aGlCtx->RenderingContext());
104+
aSubviewIter->MustBeResized();
105+
aSubviewIter->Invalidate();
103106
}
107+
#endif
104108
return true;
105109
}
106110

@@ -124,8 +128,8 @@ bool OcctGlTools::InitializeGlFbo(const Handle(V3d_View)& theView)
124128
}
125129

126130
Graphic3d_Vec2i aViewSizeOld;
127-
const Graphic3d_Vec2i aViewSizeNew = aDefaultFbo->GetVPSize();
128-
Handle(Aspect_NeutralWindow) aWindow = Handle(Aspect_NeutralWindow)::DownCast(theView->Window());
131+
const Graphic3d_Vec2i aViewSizeNew = aDefaultFbo->GetVPSize();
132+
Handle(OcctNeutralWindow) aWindow = Handle(OcctNeutralWindow)::DownCast(theView->Window());
129133
aWindow->Size(aViewSizeOld.x(), aViewSizeOld.y());
130134
if (aViewSizeNew != aViewSizeOld)
131135
{

occt-qt-tools/OcctGlTools.h

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,30 @@
33
#ifndef _OcctGlTools_HeaderFile
44
#define _OcctGlTools_HeaderFile
55

6+
#include <Aspect_NeutralWindow.hxx>
67
#include <V3d_View.hxx>
78

89
class OpenGl_Context;
910

1011
//! Auxiliary wrapper to avoid OpenGL macros collisions between Qt and OCCT headers.
1112
class OcctGlTools
1213
{
14+
public:
15+
//! Class making DevicePixelRatio() configurable.
16+
class OcctNeutralWindow : public Aspect_NeutralWindow
17+
{
18+
public:
19+
//! Empty constructor.
20+
OcctNeutralWindow() {}
21+
22+
//! Return device pixel ratio (logical to backing store scale factor).
23+
virtual double DevicePixelRatio() const override { return myPixelRatio; }
24+
25+
//! Set device pixel ratio.
26+
void SetDevicePixelRatio(double theRatio) { myPixelRatio = theRatio; }
27+
private:
28+
double myPixelRatio = 1.0;
29+
};
1330
public:
1431
//! Return GL context.
1532
static Handle(OpenGl_Context) GetGlContext(const Handle(V3d_View)& theView);
@@ -20,7 +37,8 @@ class OcctGlTools
2037
//! Initialize native window for OCCT 3D Viewer.
2138
static bool InitializeGlWindow(const Handle(V3d_View)& theView,
2239
const Aspect_Drawable theNativeWin,
23-
const Graphic3d_Vec2i& theSize);
40+
const Graphic3d_Vec2i& theSize,
41+
const double thePixelRatio);
2442

2543
//! Wrap FBO created by QOpenGLFramebufferObject to OCCT 3D Viewer target.
2644
static bool InitializeGlFbo(const Handle(V3d_View)& theView);

occt-qt-tools/OcctQtTools.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <Standard_Version.hxx>
88

99
#include <QCoreApplication>
10+
#include <QGuiApplication>
1011

1112
// ================================================================
1213
// Function : qtColorToOcct
@@ -69,6 +70,13 @@ void OcctQtTools::qtGlPlatformSetup()
6970
aQsgLoop.SetValue("basic");
7071
aQsgLoop.Build();
7172
}*/
73+
74+
// enable auto-scaling for high-density screens
75+
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
76+
#if (QT_VERSION_MAJOR == 5 && QT_VERSION_MINOR >= 14)
77+
// this is default since Qt6 (for fractional scale factors)
78+
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
79+
#endif
7280
}
7381

7482
// ================================================================

0 commit comments

Comments
 (0)