1 /*========================================================================= 2 3 Program: Visualization Toolkit 4 Module: QVTKOpenGLWindow.h 5 6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 7 All rights reserved. 8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details. 9 10 This software is distributed WITHOUT ANY WARRANTY; without even 11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 12 PURPOSE. See the above copyright notice for more information. 13 14 =========================================================================*/ 15 /** 16 * @class QVTKOpenGLWindow 17 * @brief display a vtkGenericOpenGLRenderWindow in a Qt QOpenGLWindow. 18 * 19 * QVTKOpenGLWindow is one of the mechanisms for displaying VTK rendering 20 * results in a Qt application. QVTKOpenGLWindow extends QOpenGLWindow to 21 * display the rendering results of a vtkGenericOpenGLRenderWindow. 22 * 23 * Since QVTKOpenGLWindow is based on QOpenGLWindow it is intended for 24 * rendering in a top-level window. QVTKOpenGLWindow can be embedded in a 25 * another QWidget using `QWidget::createWindowContainer` or by using 26 * QVTKOpenGLStereoWidget instead. However, developers are encouraged to check 27 * Qt documentation for `QWidget::createWindowContainer` idiosyncrasies. 28 * Using QVTKOpenGLNativeWidget instead is generally a better choice for causes 29 * where you want to embed VTK rendering results in a QWidget. QVTKOpenGLWindow 30 * or QVTKOpenGLStereoWidget is still preferred for applications that want to support 31 * quad-buffer based stereo rendering. 32 * 33 * To request a specific configuration for the context, use 34 * `QWindow::setFormat()` like for any other QWindow. This allows, among others, 35 * requesting a given OpenGL version and profile. Use 36 * `QOpenGLWindow::defaultFormat()` to obtain a QSurfaceFormat with appropriate 37 * OpenGL version configuration. To enable quad-buffer stereo, you'll need to 38 * call `QSurfaceFormat::setStereo(true)`. 39 * 40 * VTK Rendering features like multi-sampling, double buffering etc. 41 * are enabled/disabled by directly setting the corresponding attributes on 42 * vtkGenericOpenGLRenderWindow and not when specifying the OpenGL context 43 * format in `setFormat`. If not specified, then `QSurfaceFormat::defaultFormat` 44 * will be used. 45 * 46 * @note QVTKOpenGLWindow requires Qt version 5.9 and above. 47 * @sa QVTKOpenGLStereoWidget QVTKOpenGLNativeWidget 48 */ 49 #ifndef QVTKOpenGLWindow_h 50 #define QVTKOpenGLWindow_h 51 52 #include <QOpenGLWindow> 53 #include <QScopedPointer> // for QScopedPointer. 54 55 #include "QVTKInteractor.h" // needed for QVTKInteractor 56 #include "vtkDeprecation.h" // For VTK_DEPRECATED_IN_9_0_0 57 #include "vtkGUISupportQtModule.h" // for export macro 58 #include "vtkNew.h" // needed for vtkNew 59 #include "vtkSmartPointer.h" // needed for vtkSmartPointer 60 61 class QVTKInteractor; 62 class QVTKInteractorAdapter; 63 class QVTKRenderWindowAdapter; 64 class vtkGenericOpenGLRenderWindow; 65 66 class VTKGUISUPPORTQT_EXPORT QVTKOpenGLWindow : public QOpenGLWindow 67 { 68 Q_OBJECT 69 typedef QOpenGLWindow Superclass; 70 71 public: 72 QVTKOpenGLWindow( 73 QOpenGLWindow::UpdateBehavior updateBehavior = NoPartialUpdate, QWindow* parent = nullptr); 74 QVTKOpenGLWindow(QOpenGLContext* shareContext, 75 QOpenGLWindow::UpdateBehavior updateBehavior = NoPartialUpdate, QWindow* parent = nullptr); 76 QVTKOpenGLWindow(vtkGenericOpenGLRenderWindow* renderWindow, 77 QOpenGLWindow::UpdateBehavior updateBehavior = NoPartialUpdate, QWindow* parent = nullptr); 78 QVTKOpenGLWindow(vtkGenericOpenGLRenderWindow* renderWindow, QOpenGLContext* shareContext, 79 QOpenGLWindow::UpdateBehavior updateBehavior = NoPartialUpdate, QWindow* parent = nullptr); 80 ~QVTKOpenGLWindow() override; 81 82 ///@{ 83 /** 84 * Set a render window to use. It a render window was already set, it will be 85 * finalized and all of its OpenGL resource released. If the \c win is 86 * non-null and it has no interactor set, then a QVTKInteractor instance will 87 * be created as set on the render window as the interactor. 88 */ 89 void setRenderWindow(vtkGenericOpenGLRenderWindow* win); 90 void setRenderWindow(vtkRenderWindow* win); 91 ///@} 92 93 /** 94 * Returns the render window that is being shown in this widget. 95 */ 96 vtkRenderWindow* renderWindow() const; 97 98 /** 99 * Get the QVTKInteractor that was either created by default or set by the user. 100 */ 101 QVTKInteractor* interactor() const; 102 103 /** 104 * @copydoc QVTKRenderWindowAdapter::defaultFormat(bool) 105 */ 106 static QSurfaceFormat defaultFormat(bool stereo_capable = false); 107 108 ///@{ 109 /** 110 * Enable or disable support for HiDPI displays. When enabled, this enabled 111 * DPI scaling i.e. `vtkWindow::SetDPI` will be called with a DPI value scaled 112 * by the device pixel ratio every time the widget is resized. The unscaled 113 * DPI value can be specified by using `setUnscaledDPI`. 114 */ 115 void setEnableHiDPI(bool enable); enableHiDPI()116 bool enableHiDPI() const { return this->EnableHiDPI; } 117 ///@} 118 119 ///@{ 120 /** 121 * Set/Get unscaled DPI value. Defaults to 72, which is also the default value 122 * in vtkWindow. 123 */ 124 void setUnscaledDPI(int); unscaledDPI()125 int unscaledDPI() const { return this->UnscaledDPI; } 126 ///@} 127 128 ///@{ 129 /** 130 * Set/Get a custom device pixel ratio to use to map Qt sizes to VTK (or 131 * OpenGL) sizes. Thus, when the QWidget is resized, it called 132 * `vtkRenderWindow::SetSize` on the internal vtkRenderWindow after 133 * multiplying the QWidget's size by this scale factor. 134 * 135 * By default, this is set to 0. Which means that `devicePixelRatio` obtained 136 * from Qt will be used. Set this to a number greater than 0 to override this 137 * behaviour and use the custom scale factor instead. 138 * 139 * `effectiveDevicePixelRatio` can be used to obtain the device-pixel-ratio 140 * that will be used given the value for customDevicePixelRatio. 141 */ 142 void setCustomDevicePixelRatio(double cdpr); customDevicePixelRatio()143 double customDevicePixelRatio() const { return this->CustomDevicePixelRatio; } 144 double effectiveDevicePixelRatio() const; 145 ///@} 146 147 ///@{ 148 /** 149 * Set/get the default cursor to use for this widget. 150 */ 151 void setDefaultCursor(const QCursor& cursor); defaultCursor()152 const QCursor& defaultCursor() const { return this->DefaultCursor; } 153 ///@} 154 155 ///@{ 156 /** 157 * @deprecated in VTK 9.0. Use `setRenderWindow` instead. 158 */ 159 VTK_DEPRECATED_IN_9_0_0("Use QVTKOpenGLWindow::setRenderWindow") 160 void SetRenderWindow(vtkGenericOpenGLRenderWindow* win); 161 VTK_DEPRECATED_IN_9_0_0("Use QVTKOpenGLWindow::setRenderWindow") 162 void SetRenderWindow(vtkRenderWindow* win); 163 ///@} 164 165 ///@{ 166 /** 167 * These methods have be deprecated to fix naming style. Since 168 * QVTKOpenGLWindow is QObject subclass, we follow Qt naming conventions 169 * rather than VTK's. 170 */ 171 VTK_DEPRECATED_IN_9_0_0("Use QVTKOpenGLWindow::renderWindow") 172 vtkRenderWindow* GetRenderWindow(); 173 VTK_DEPRECATED_IN_9_0_0("Use QVTKOpenGLWindow::interactor") 174 QVTKInteractor* GetInteractor(); 175 ///@} 176 177 /** 178 * @deprecated in VTK 9.0 179 * QVTKInteractorAdapter is an internal helper. Hence the API was removed. 180 */ 181 VTK_DEPRECATED_IN_9_0_0("Removed in 9.0.0 (internal)") 182 QVTKInteractorAdapter* GetInteractorAdapter(); 183 184 /** 185 * @deprecated in VTK 9.0. Simply use `QWidget::setCursor` API to change 186 * cursor. 187 */ 188 VTK_DEPRECATED_IN_9_0_0("Use QWidget::setCursor") 189 void setQVTKCursor(const QCursor& cursor); 190 191 /** 192 * @deprecated in VTK 9.0. Use `setDefaultCursor` instead. 193 */ 194 VTK_DEPRECATED_IN_9_0_0("Use QWidget::setDefaultCursor") 195 void setDefaultQVTKCursor(const QCursor& cursor); 196 197 Q_SIGNALS: 198 /** 199 * Signal emitted when any event has been receive, with the corresponding 200 * event as argument. 201 */ 202 void windowEvent(QEvent* e); 203 204 protected Q_SLOTS: 205 /** 206 * Called as a response to `QOpenGLContext::aboutToBeDestroyed`. This may be 207 * called anytime during the widget lifecycle. We need to release any OpenGL 208 * resources allocated in VTK work in this method. 209 */ 210 void cleanupContext(); 211 212 void updateSize(); 213 214 /** 215 * QVTKOpenGLStereoWidget is given friendship so it can call `cleanupContext` in its 216 * destructor to ensure that OpenGL state is proporly cleaned up before the 217 * widget goes away. 218 */ 219 friend class QVTKOpenGLStereoWidget; 220 221 protected: 222 bool event(QEvent* evt) override; 223 void initializeGL() override; 224 void paintGL() override; 225 void resizeGL(int w, int h) override; 226 227 protected: 228 vtkSmartPointer<vtkGenericOpenGLRenderWindow> RenderWindow; 229 QScopedPointer<QVTKRenderWindowAdapter> RenderWindowAdapter; 230 231 private: 232 Q_DISABLE_COPY(QVTKOpenGLWindow); 233 bool EnableHiDPI; 234 int UnscaledDPI; 235 double CustomDevicePixelRatio; 236 QCursor DefaultCursor; 237 }; 238 239 #endif 240