VVISF & VVGL
GLContext.hpp
1 #ifndef VVGL_GLContext_hpp
2 #define VVGL_GLContext_hpp
3 
4 #include "VVGL_Defines.hpp"
5 
6 #include <string>
7 #include <iostream>
8 #if defined(VVGL_SDK_MAC)
9 #pragma clang diagnostic push
10 #pragma clang diagnostic ignored "-W#warnings"
11  #import <OpenGL/OpenGL.h>
12  #import <OpenGL/gl.h>
13  #import <OpenGL/glext.h>
14  #import <OpenGL/gl3.h>
15  #import <OpenGL/gl3ext.h>
16 #pragma clang diagnostic pop
17 #elif defined(VVGL_SDK_IOS)
18  //#ifndef __cplusplus
19  //#import <OpenGLES/EAGL.h>
20  #import <OpenGLES/ES3/glext.h>
21  //#import <GLKit/GLKit.h>
22  //#endif
23 #elif defined(VVGL_SDK_RPI)
24  #include "bcm_host.h"
25  //#include <GLES/gl.h>
26  //#include <GLES/glext.h>
27  #include <GLES2/gl2.h>
28  #include <GLES2/gl2ext.h>
29  #include <EGL/egl.h>
30  #include <EGL/eglext.h>
31 #elif defined(VVGL_SDK_GLFW)
32  //#include <glad/glad.h>
33  #include <GL/glew.h>
34  #include <GLFW/glfw3.h>
35 #elif defined(VVGL_SDK_QT)
36  #include <GL/glew.h>
37  #include <QPointer>
38  #include "GLQtCtxWrapper.hpp"
39  class QOpenGLContext;
40 #endif
41 
42 #include "VVGL_Base.hpp"
43 #include "VVGL_Geom.hpp"
44 
45 
46 
47 
48 namespace VVGL
49 {
50 
51 
52 using namespace std;
53 
54 
55 
56 
57 #if defined(VVGL_SDK_MAC)
58 
62 uint32_t GLDisplayMaskForAllScreens();
67 CGLPixelFormatObj CreateDefaultPixelFormat();
72 CGLPixelFormatObj CreateCompatibilityGLPixelFormat();
77 CGLPixelFormatObj CreateGL3PixelFormat();
82 CGLPixelFormatObj CreateGL4PixelFormat();
83 #elif defined(VVGL_SDK_QT)
84 
88 VVGL_EXPORT QSurfaceFormat CreateDefaultSurfaceFormat();
93 VVGL_EXPORT QSurfaceFormat CreateCompatibilityGLSurfaceFormat();
98 VVGL_EXPORT QSurfaceFormat CreateGL3SurfaceFormat();
103 VVGL_EXPORT QSurfaceFormat CreateGL4SurfaceFormat();
104 #endif
105 
106 
107 
108 
110 
119 class VVGL_EXPORT GLContext {
120  public:
121 
122 #if defined(VVGL_SDK_MAC)
123  CGLContextObj ctx = nullptr;
124  CGLContextObj sharedCtx = nullptr;
125  CGLPixelFormatObj pxlFmt = nullptr;
126 #elif defined(VVGL_SDK_IOS)
127  void *ctx = nullptr; // really an EAGLContext under iOS
128 #elif defined(VVGL_SDK_GLFW)
129  GLFWwindow *win = nullptr;
130  bool initializedFuncs = false; // read some docs that say the GLEW funcs must be initialized once per-context per-thread
131 #elif defined(VVGL_SDK_RPI)
132  EGLDisplay display = EGL_NO_DISPLAY; // weak ref, potentially unsafe
133  EGLSurface winSurface = EGL_NO_SURFACE; // weak ref, potentially unsafe
134  EGLContext sharedCtx = EGL_NO_CONTEXT; // weak ref, potentially unsafe
135  bool ownsTheCtx = false; // set to true when i "own" ctx and must destroy it on my release
136  EGLContext ctx = EGL_NO_CONTEXT; // owned by this object
137 #elif defined(VVGL_SDK_QT)
138  GLQtCtxWrapper *ctx = nullptr; // we have to wrap all the QOpenGL* stuff because if its headers and GLEW's headers are in the same #include paths it breaks compilation
139  QSurfaceFormat sfcFmt = CreateDefaultSurfaceFormat();
140  bool initializedFuncs = false; // read some docs that say the GLEW funcs must be initialized once per-context per-thread
141 #endif
142  GLVersion version = GLVersion_Unknown;
144  std::string _renderer = std::string("");
145 
146 
147  public:
148  // most uses of GLContext are through shared_ptrs, so you should avoid using these constructors wherever possible- there are creation functions defined in this header outside of this class.
149 #if defined(VVGL_SDK_MAC)
150  // this function doesn't create anything- it just retains the passed ctx/share ctx/pxl fmt, leaving them null if that's how they were passed in
151  GLContext(const CGLContextObj & inCtx, const CGLContextObj & inShareCtx, const CGLPixelFormatObj & inPxlFm=CreateDefaultPixelFormat());
152  // this function creates a context using the passed pixel format and share context
153  GLContext(const CGLContextObj & inShareCtx, const CGLPixelFormatObj & inPxlFmt=CreateDefaultPixelFormat());
154 
155  // this function returns the underlying CGLContextObj
156  CGLContextObj contextObj() { return ctx; }
157  // this function returns the underlyihng shared context as a CGLContextObj
158  CGLContextObj sharedContextObj() { return sharedCtx; }
159  // this function returns the pixel format object
160  CGLPixelFormatObj pixelFormatObj() { return pxlFmt; }
161 #elif defined(VVGL_SDK_IOS)
162  // "inCtx" is an EAGLContext! this function doesn't create anything- it just retains the passed ctx
163  GLContext(const void * inEAGLContext);
164  // this function doesn't create a new GL context- it "wraps" (and retains) the passed context
165  //GLContext(const EAGLContext * inCtx);
166  // this function actually creates a new GL context using the passed sharegroup and rendering API
167  //GLContext(const EAGLSharegroup * inSharegroup, const EAGLRenderingAPI & inRenderAPI);
168 #elif defined(VVGL_SDK_GLFW)
169  GLContext(GLFWwindow * inWindow);
170 #elif defined(VVGL_SDK_RPI)
171  // this function doesn't create anything- it just obtains a weak ref to the passed EGL vars
172  GLContext(EGLDisplay inDisplay, EGLSurface inWinSurface, EGLContext inSharedCtx, EGLContext inCtx);
173  // this function creates a new GL context using the passed shared context
174  GLContext(EGLDisplay inDisplay, EGLSurface inWinSurface, EGLContext inSharedCtx);
175 #elif defined(VVGL_SDK_QT)
176  // if 'inTargetSurface' is null, a QOffscreenSurface will be created. if it's non-null (a widget or a window or etc), we just get a weak ref to it.
177  // if 'inCreateCtx' is YES, a new GL context will be created and it will share 'inCtx'.
178  // if 'inCreateCtx' is NO, no GL context will be created and instead a weak ref to 'inCtx' will be established.
179  GLContext(QSurface * inTargetSurface, QOpenGLContext * inCtx, bool inCreateCtx=true, QSurfaceFormat inSfcFmt=CreateDefaultSurfaceFormat());
180  // you probably don't want to use this constructor. this function wraps the passed context in a GLContext instance. it doesn't create a context, nor does it have a surface- i wrote this because i need to wrap contexts in QOpenGLWidgets, which don't like letting you mess with their contexts.
181  GLContext(QOpenGLContext * inCtx);
182 
183  static QOpenGLContext * GetCurrentContext();
184 
185  void setSurface(const QSurface * inTargetSurface);
186  void swap();
187  void moveToThread(QThread * inThread);
188  QOpenGLContext * context();
189  QObject * contextAsObject();
190  QThread * contextThread();
191  QVariant nativeHandle();
192 
193  /*
194  // this function doesn't create anything- it just obtains a weak ref to the passed var
195  GLContext(const QOpenGLContext * inCtx, const QOpenGLContext * inShareCtx);
196  // this function creates a new QOpenGLContext in the backend sharing the passed context
197  GLContext(const QOpenGLContext * inShareCtx);
198  */
199 #endif
200  // this function creates a context using the default pixel format
201  GLContext();
202 
203  // no copy constructors!
204  GLContext(const GLContext &) = delete;
205 
206 
207  public:
208  void generalInit();
209  void calculateVersion();
210 
211  // returned variable MUST BE FREED
212  //GLContext * allocNewContextSharingMe() const;
213  // creates a new GL context, but returned variable doesn't have to be freed
214  //GLContext newContextSharingMe() const;
215 
217  GLContextRef newContextSharingMe() const;
218 
219  ~GLContext();
220 
222  void makeCurrent();
224  void makeCurrentIfNotCurrent();
226  void makeCurrentIfNull();
227 
229  bool sameShareGroupAs(const GLContextRef & inCtx);
230 #if defined(VVGL_SDK_MAC)
231  bool sameShareGroupAs(const CGLContextObj & inCtx);
232 #endif
233 
234  std::string getRenderer() { return _renderer; }
235 
236  GLContext & operator=(const GLContext & n);
237  friend ostream & operator<<(ostream & os, const GLContext & n);
238  friend ostream & operator<<(ostream & os, const GLContext * n);
239 };
240 
241 
242 
243 
244 // these creation functions are the preferred way of making GLContext instances. they're just more human-readable than make_shared<GLContext>(constructor args).
245 #if defined(VVGL_SDK_MAC)
246 
250 inline GLContextRef CreateGLContextRefUsing(const CGLContextObj & inCtx, const CGLContextObj & inShareCtx, const CGLPixelFormatObj & inPxlFmt=CreateDefaultPixelFormat()) { return make_shared<GLContext>(inCtx, inShareCtx, inPxlFmt); }
255 inline GLContextRef CreateNewGLContextRef(const CGLContextObj & inShareCtx, const CGLPixelFormatObj & inPxlFmt=CreateDefaultPixelFormat()) { return make_shared<GLContext>(inShareCtx, inPxlFmt); }
256 #elif defined(VVGL_SDK_IOS)
257 
261 inline GLContextRef CreateGLContextRefUsing(const void * inEAGLContext) { return make_shared<GLContext>(inEAGLContext); }
262 #elif defined(VVGL_SDK_GLFW)
263 
267 inline GLContextRef CreateGLContextRefUsing(GLFWwindow * inWindow) { return make_shared<GLContext>(inWindow); }
268 #elif defined(VVGL_SDK_RPI)
269 
273 inline GLContextRef CreateGLContextRefUsing(EGLDisplay inDisplay, EGLSurface inWinSurface, EGLContext inSharedCtx, EGLContext inCtx) { return make_shared<GLContext>(inDisplay, inWinSurface, inSharedCtx, inCtx); }
278 inline GLContextRef CreateNewGLContextRef(EGLDisplay inDisplay, EGLSurface inWinSurface, EGLContext inSharedCtx) { return make_shared<GLContext>(inDisplay, inWinSurface, inSharedCtx); }
279 #elif defined(VVGL_SDK_QT)
280 
287 inline GLContextRef CreateGLContextRefUsing(QSurface * inTargetSurface, QOpenGLContext * inCtx, QSurfaceFormat inSfcFmt=CreateDefaultSurfaceFormat()) { return make_shared<GLContext>(inTargetSurface, inCtx, false, inSfcFmt); }
295 inline GLContextRef CreateNewGLContextRef(QSurface * inTargetSurface, QOpenGLContext * inShareCtx, QSurfaceFormat inSfcFmt=CreateDefaultSurfaceFormat()) { return make_shared<GLContext>(inTargetSurface, inShareCtx, true, inSfcFmt); }
296 #endif
297 
301 inline GLContextRef CreateNewGLContextRef() { return make_shared<GLContext>(); }
302 
303 
304 
305 
306 }
307 
308 
309 
310 
311 #endif /* VVGL_GLContext_hpp */
GLContextRef CreateGLContextRefUsing(QSurface *inTargetSurface, QOpenGLContext *inCtx, QSurfaceFormat inSfcFmt=CreateDefaultSurfaceFormat())
Doesn&#39;t create any GL resources, just makes a new GLContext instance using the passed resources...
Definition: GLContext.hpp:287
Definition: GLBuffer.hpp:13
GLContext is an attempt to make a platform/SDK-agnostic representation of an OpenGL context...
Definition: GLContext.hpp:119
GLContextRef CreateNewGLContextRef()
Creates a generic OpenGL context and GLContext instance using whatever the default settings are for t...
Definition: GLContext.hpp:301
STL namespace.
GLContextRef CreateNewGLContextRef(QSurface *inTargetSurface, QOpenGLContext *inShareCtx, QSurfaceFormat inSfcFmt=CreateDefaultSurfaceFormat())
Creates a new OpenGL context and GLContext instance.
Definition: GLContext.hpp:295
GLVersion
This enum is used to describe the GL environment of a GL context, which is determined at runtime...
Definition: VVGL_Base.hpp:94
shared_ptr< GLContext > GLContextRef
A GLContextRef is a shared pointer around a GLContext.
Definition: VVGL_Base.hpp:60