HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RE_Visual.h
Go to the documentation of this file.
1 #ifndef __RE_Visual_h__
2 #define __RE_Visual_h__
3 
4 #include "RE_API.h"
5 #include "RE_Types.h"
6 
7 #include <UT/UT_Lock.h>
9 
10 // Include this before including any QOpenGL files.
11 // This ensures that our OpenGL core profile API is included
12 // instead of the one shipped with Qt.
13 // TODO: We should look into moving over to Qt's OpenGL API
14 // (i.e. include QtGui/qopengl.h or maybe QtGui/QOpenGLFunctions.h
15 // instead of glcorearb.h)
16 #include "RE_OGL.h"
17 
18 #include <QtGui/QOpenGLContext>
19 #include <QtGui/QWindow>
20 #include <QtWidgets/QWidget>
21 #undef emit
22 
23 // Object names for QWidget and QWindow (drawable surface) objects used
24 // for OpenGL rendering. Note that the drawable surface name must be exactly
25 // equal to the drawable name plus "Window" as the suffix. This is a
26 // restriction of the QWidgetWindow class.
27 #define RE_GL_DRAWABLE_OBJ_NAME "RE_GLDrawable"
28 #define RE_GL_DRAWABLE_SURFACE_OBJ_NAME RE_GL_DRAWABLE_OBJ_NAME "Window"
29 
30 #define RE_GL_DRAWABLE_WRAPPER_OBJ_NAME RE_GL_DRAWABLE_OBJ_NAME "Wrapper"
31 
32 class RE_Server;
33 class RE_Window;
34 
35 class RE_GLDrawable;
36 class QGLFormat;
37 class QSurfaceFormat;
38 
39 class RE_GLContext : public QOpenGLContext
40 {
41 public:
43  myDrawable(NULL)
44  {}
45 
47 
48  RE_GLDrawable *drawable() const { return myDrawable; }
49  void setDrawable(RE_GLDrawable *drawable) { myDrawable = drawable; }
50 
51 private:
52  RE_GLDrawable *myDrawable;
53 };
54 
55 /// GL drawable for Qt5.
56 /// It's basically a plain Qt widget that manages a GL context.
57 class RE_GLDrawable : public QWidget
58 {
59 public:
60  RE_GLDrawable(const QSurfaceFormat &format)
61  : QWidget()
62  {
63  myContext.setDrawable(this);
64  myContext.setFormat(format);
65 
66  init_();
67  }
68 
70  const QSurfaceFormat &format, QWidget *parent,
71  QOpenGLContext *sharedContext)
72  : QWidget(parent)
73  {
74  myContext.setDrawable(this);
75  myContext.setFormat(format);
76  if (sharedContext)
77  myContext.setShareContext(sharedContext);
78 
79  init_();
80  }
81 
82  virtual ~RE_GLDrawable() {}
83 
84  RE_GLContext *context() { return &myContext; }
85 
86  virtual QPaintEngine *paintEngine() const { return nullptr; };
87  static const char *widgetTag() { return RE_GL_DRAWABLE_OBJ_NAME; }
88 
89  /// Return the string tag used to identify whether a QWindow
90  /// is used a drawable surface for Houdini.
91  static const char * drawableSurfaceTag()
93 
94  /// Return the string tag used to identify whether a QWidget
95  /// is the wrapper widget of a GL drawable in Houdini.
96  static const char *widgetWrapperTag()
98 
99 protected:
100  virtual void paintEvent(QPaintEvent *event) {}
101  virtual void resizeEvent(QResizeEvent *event) {}
102  virtual void mousePressEvent(QMouseEvent *event)
103  {
104  setFocus();
105  QWidget::mousePressEvent(event);
106  }
107 
108 private:
109  void init_()
110  {
111  // Neat little trick to force Qt to create the platform drawable without
112  // showing it. We need the platform drawable to exist before doing
113  // any OpenGL rendering.
114  //
115  // Note that we have to resize the window handle (surface) to keep its
116  // geometry in sync with the GL widget. This must be done *before* the
117  // call to winId() or else the underlying platform window (surface)
118  // will be initialized with a default size assigned by Qt.
119  (void)winId();
120  UT_ASSERT(windowHandle());
121  windowHandle()->resize(size());
122  (void)windowHandle()->winId();
123 
124  // Tag the drawable surface.
125  windowHandle()->setObjectName(RE_GLDrawable::drawableSurfaceTag());
126 
127  // Set these attributes to prevent Qt from trying to fill in the
128  // background with either black or white (system-dependent).
129  setAttribute(Qt::WA_PaintOnScreen);
130  setAttribute(Qt::WA_NoSystemBackground);
131 
132  UT_IF_ASSERT(bool created =) myContext.create();
133  UT_ASSERT(created && myContext.isValid());
134 
135  // Tag ourself so that we can be identified in the event loop.
136  setObjectName(widgetTag());
137  setAcceptDrops(true);
138  }
139 
140  RE_GLContext myContext;
141 };
142 
144 {
145 public:
146  RE_Visual(RE_DisplayMode newmode);
147  ~RE_Visual();
148 
149  RE_OGLContext createContext(RE_Window *win) const;
150  void deleteContext(RE_OGLContext) const;
151 
152  RE_OGLContext grabContext(RE_Window *win, bool attach = true);
153  void returnContext(RE_Window *win, RE_OGLContext ctx);
154 
155  // isMode() returns true on an exact match. isCompatibleWithMode() returns
156  // true if this visual is equal to or a superset of the features in 'match'
157  bool isMode(RE_DisplayMode match) const;
158  bool isCompatibleWithMode(RE_DisplayMode match) const;
159 
160  bool isRGB() const;
161 
162  /// Returns the display mode used for the request to create this visual.
163  RE_DisplayMode getMode() const { return myVisualMode; }
164 
165  const QSurfaceFormat * getPixelFormat() const;
166  static QOpenGLContext * getSharedGLContext();
167  static void initDefaultGLFormat();
168 
169  static bool isDetachedContext(RE_OGLContext);
170 
171  /// Return the tag we use to identify our GL widgets.
172  /// This is useful when handling events in the event loop.
173  static const char * glWidgetTag();
174 
175  /// Return the tag we use to identify our GL widget wrappers.
176  /// This is useful when handling events in the event loop.
177  static const char * glWidgetWrapperTag();
178 
179  /// Return the window widget that is bound to the specified GL widget.
180  static QWidget * ownerWindowWidget(QWidget *gl_widget);
181 
182  bool canSupportQuadBufferStereo(OGLDrawable drawable);
183 
184 private:
185  void initPixelFormat_(RE_DisplayMode mode);
186  void createSharedGLWidget_();
187  void testGLVersions_();
188  bool canCreateGLContext_(
189  int gl_major, int gl_minor,
190  bool use_core_profile);
191 
192  RE_DisplayMode myVisualMode;
193 
194  UT_Lock myContextLock;
195  UT_Array<RE_OGLContext> myVisibleContexts;
196 
197  // This widget is for stashing away returned GL widgets by containing them
198  // as children. This causes the GL widgets to be parented at all times so
199  // that their window flags do not change.
200  QWidget *myStashWidget;
201 
202  QSurfaceFormat * myPixelFormat;
203 };
204 
205 #endif
virtual ~RE_GLDrawable()
Definition: RE_Visual.h:82
RE_GLDrawable(const QSurfaceFormat &format)
Definition: RE_Visual.h:60
void setDrawable(RE_GLDrawable *drawable)
Definition: RE_Visual.h:49
static const char * drawableSurfaceTag()
Definition: RE_Visual.h:91
#define RE_API
Definition: RE_API.h:10
#define RE_GL_DRAWABLE_WRAPPER_OBJ_NAME
Definition: RE_Visual.h:30
virtual QPaintEngine * paintEngine() const
Definition: RE_Visual.h:86
static const char * widgetWrapperTag()
Definition: RE_Visual.h:96
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
#define UT_IF_ASSERT(ZZ)
Definition: UT_Assert.h:144
virtual void mousePressEvent(QMouseEvent *event)
Definition: RE_Visual.h:102
GLsizeiptr size
Definition: glcorearb.h:663
struct _cl_event * event
Definition: glcorearb.h:2960
#define RE_GL_DRAWABLE_SURFACE_OBJ_NAME
Definition: RE_Visual.h:28
RE_GLContext * context()
Definition: RE_Visual.h:84
static const char * widgetTag()
Definition: RE_Visual.h:87
RE_DisplayMode
Definition: RE_Types.h:536
RE_GLDrawable * drawable() const
Definition: RE_Visual.h:48
RE_DisplayMode getMode() const
Returns the display mode used for the request to create this visual.
Definition: RE_Visual.h:163
GLenum mode
Definition: glcorearb.h:98
GLint GLint GLsizei GLint GLenum format
Definition: glcorearb.h:107
virtual void paintEvent(QPaintEvent *event)
Definition: RE_Visual.h:100
virtual void resizeEvent(QResizeEvent *event)
Definition: RE_Visual.h:101
#define RE_GL_DRAWABLE_OBJ_NAME
Definition: RE_Visual.h:27
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:126
QOpenGLContext * RE_OGLContext
Definition: RE_Types.h:891
RE_GLDrawable(const QSurfaceFormat &format, QWidget *parent, QOpenGLContext *sharedContext)
Definition: RE_Visual.h:69