Radium Engine  1.5.20
Loading...
Searching...
No Matches
WindowQt.cpp
1#include "WindowQt.hpp"
2
3#include <QApplication>
4#include <QDebug>
5#include <QOpenGLContext>
6#include <QResizeEvent>
7#include <QScreen>
8#include <QSurfaceFormat>
9
10#include <Core/Utils/Log.hpp>
11
12using namespace Ra::Core::Utils; // log
13
14namespace Ra {
15namespace Gui {
16
17WindowQt* WindowQt::s_getProcAddressHelper = nullptr;
18
19QSurfaceFormat defaultFormat() {
20 QSurfaceFormat format;
21 format.setProfile( QSurfaceFormat::CoreProfile );
22#ifndef NDEBUG
23 format.setOption( QSurfaceFormat::DebugContext );
24#endif
25 return format;
26}
27
28WindowQt::WindowQt( QScreen* screen ) :
29 QWindow( screen ), m_context( nullptr ), m_updatePending( false ), m_glInitialized( false ) {
30
31 setSurfaceType( QWindow::OpenGLSurface );
32 if ( !s_getProcAddressHelper ) { s_getProcAddressHelper = this; }
33
34 // No need to create as this window is used as widget (and actually segfault on Qt 5.12.3)
35 // Surface format set in BaseApplication
36
37 m_context = std::make_unique<QOpenGLContext>( this );
38 m_context->setFormat( QSurfaceFormat::defaultFormat() );
39
40 if ( !m_context->create() ) {
41 LOG( logINFO ) << "Could not create OpenGL context.";
42 QApplication::quit();
43 }
44
45 m_screenObserver = connect(
46 this->screen(), &QScreen::physicalDotsPerInchChanged, this, &WindowQt::physicalDpiChanged );
47 connect( this, &QWindow::screenChanged, this, &WindowQt::screenChanged );
48
49 // cleanup connection is set in BaseApplication
50}
51
52WindowQt::~WindowQt() {
53 // cannot deinitialize OpenGL here as it would require the call of a virtual member function
54}
55
56void WindowQt::screenChanged() {
57 disconnect( m_screenObserver );
58 m_screenObserver = connect(
59 this->screen(), &QScreen::physicalDotsPerInchChanged, this, &WindowQt::physicalDpiChanged );
60 emit dpiChanged();
61 QSize s { size().width(), size().height() };
62 QResizeEvent patchEvent { s, s };
63 resizeInternal( &patchEvent );
64}
65
66void WindowQt::physicalDpiChanged( qreal /*dpi*/ ) {
67 emit dpiChanged();
68#ifdef OS_WINDOWS
69 // on windows, no resize event generated when dpi change, force resize
70 QSize s { size().width(), size().height() };
71 QResizeEvent patchEvent { s, s };
72 resizeInternal( &patchEvent );
73#endif
74}
75
76QOpenGLContext* WindowQt::context() {
77 return m_context.get();
78}
79
80void WindowQt::makeCurrent() {
81 if ( QOpenGLContext::currentContext() != m_context.get() ) {
82 m_context->makeCurrent( this );
83 // reset counter (in case another viewer has broken our context activation counter)
84 m_contextActivationCount = 0;
85 }
86 else { ++m_contextActivationCount; }
87}
88
89void WindowQt::doneCurrent() {
90 if ( m_contextActivationCount == 0 ) { m_context->doneCurrent(); }
91 else { --m_contextActivationCount; }
92}
93
94void WindowQt::resizeEvent( QResizeEvent* event ) {
95 resizeInternal( event );
96}
97
98void WindowQt::exposeEvent( QExposeEvent* ) {
99 initialize();
100}
101
102void WindowQt::initialize() {
103 if ( !m_glInitialized.load() ) {
104 makeCurrent();
105 initializeGL();
106 doneCurrent();
107 }
108}
109
110void WindowQt::showEvent( QShowEvent* /*ev*/ ) {
111 initialize();
112}
113
114void WindowQt::resizeInternal( QResizeEvent* event ) {
115#ifdef OS_MACOS
116 // Ugly patch since Qt seems buggy on this point on macos, raise two resize call the first time.
117 if ( event->size().width() < minimumSize().width() ||
118 event->size().height() < minimumSize().height() ) {
119 QSize size { std::max( event->size().width(), minimumSize().width() ),
120 std::max( event->size().height(), minimumSize().height() ) };
121 QResizeEvent* patchEvent = new QResizeEvent( size, event->oldSize() );
122 event = patchEvent;
123 QWindow::resize( size );
124 }
125#endif
126
127 initialize();
128
129 resizeGL( event );
130}
131
133/*
134bool WindowQt::event( QEvent* event ) {
135 switch ( event->type() )
136 {
137 case QEvent::UpdateRequest:
138 // paint();
139 return true;
140
141 case QEvent::Enter:
142 enterEvent( event );
143 return true;
144
145 case QEvent::Leave:
146 leaveEvent( event );
147 return true;
148
149 default:
150 return QWindow::event( event );
151 }
152}*/
153
154bool WindowQt::initializeGL() {
155 // this simple window do not init GL
156 m_glInitialized = false;
157 return m_glInitialized;
158}
159
160void WindowQt::cleanupGL() {
161 if ( m_glInitialized.load() ) {
162 makeCurrent();
163
164 deinitializeGL();
165
166 doneCurrent();
167 }
168}
169
170void WindowQt::deinitializeGL() {}
171
172void WindowQt::resizeGL( QResizeEvent* ) {}
173
175
176void WindowQt::enterEvent( QEvent* ) {}
177
178void WindowQt::leaveEvent( QEvent* ) {}
179
180glbinding::ProcAddress WindowQt::getProcAddress( const char* name ) {
181 if ( !s_getProcAddressHelper || name == nullptr ) { return nullptr; }
182
183 const auto symbol = std::string( name );
184
185 const auto qtSymbol = QByteArray::fromStdString( symbol );
186
187 return s_getProcAddressHelper->m_context->getProcAddress( qtSymbol );
188}
189
190} // namespace Gui
191} // namespace Ra
Base class for OpenGL widgets, compatble with Qt and globjects/glbindings.
Definition WindowQt.hpp:28
T max(T... args)
hepler function to manage enum as underlying types in VariableSet
Definition Cage.cpp:3