Add CamSim::Context class to provide a suitable OpenGL context
authorMartin Lambers <marlam@marlam.de>
Fri, 14 Dec 2018 14:22:38 +0000 (15:22 +0100)
committerMartin Lambers <marlam@marlam.de>
Fri, 14 Dec 2018 14:22:38 +0000 (15:22 +0100)
libcamsim/simulator.cpp
libcamsim/simulator.hpp

index f97801a..23fca74 100644 (file)
@@ -30,6 +30,8 @@
 #include <QtMath>
 #include <QString>
 #include <QFile>
+#include <QOffscreenSurface>
+#include <QOpenGLContext>
 
 #include "simulator.hpp"
 #include "gl.hpp"
@@ -197,6 +199,59 @@ Output::Output() :
 {
 }
 
+static void glDebugMessageCallback(
+        GLenum /* source */,
+        GLenum type,
+        GLuint /* id */,
+        GLenum severity,
+        GLsizei /* length */,
+        const GLchar* message,
+        const void* /* userParam */)
+{
+    qDebug("GL%s: type=0x%x severity=0x%x: %s",
+            (type == GL_DEBUG_TYPE_ERROR ? " ERROR" : ""),
+            type, severity, message);
+}
+
+
+Context::Context(bool enableOpenGLDebugging)
+{
+    _surface = new QOffscreenSurface;
+    _surface->create();
+    QSurfaceFormat format;
+    format.setProfile(QSurfaceFormat::CoreProfile);
+    format.setVersion(4, 5);
+    if (enableOpenGLDebugging)
+        format.setOption(QSurfaceFormat::DebugContext);
+    _context = new QOpenGLContext;
+    _context->setFormat(format);
+    _context->create();
+    if (!_context->isValid()) {
+        qFatal("Cannot create a valid OpenGL context");
+    }
+    if (_context->format().majorVersion() < 4
+            || (_context->format().majorVersion() == 4 && _context->format().minorVersion() < 5)) {
+        qFatal("Cannot create OpenGL context of version >= 4.5");
+    }
+    makeCurrent();
+    if (enableOpenGLDebugging) {
+        if (!_context->format().testOption(QSurfaceFormat::DebugContext)) {
+            qWarning("OpenGL debugging not available");
+        }
+        auto gl = getGlFunctionsFromCurrentContext(Q_FUNC_INFO);
+        gl->glEnable(GL_DEBUG_OUTPUT);
+        gl->glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
+        gl->glDebugMessageCallback(glDebugMessageCallback, 0);
+    }
+}
+
+void Context::makeCurrent()
+{
+    if (!_context->makeCurrent(_surface)) {
+        qFatal("Cannot make OpenGL context current");
+    }
+}
+
 Simulator::Simulator() :
     _recreateTimestamps(true),
     _recreateShaders(true),
index a483934..1f7beb6 100644 (file)
@@ -33,6 +33,9 @@
 #include <QVector2D>
 #include <QOpenGLShaderProgram>
 
+class QOffscreenSurface;
+class QOpenGLContext;
+
 #include "scene.hpp"
 #include "animation.hpp"
 #include "texdata.hpp"
@@ -323,6 +326,26 @@ public:
 };
 
 /**
+ * \brief Provides a suitable OpenGL context for the simulator and related classes
+ */
+class Context {
+private:
+    // Our private OpenGL context handling
+    QOffscreenSurface* _surface;
+    QOpenGLContext* _context;
+
+public:
+    /*! \brief Constructor */
+    Context(bool enableOpenGLDebugging = false);
+
+    /*! \brief Return the OpenGL context */
+    QOpenGLContext* getOpenGLContext() { return _context; }
+
+    /*! \brief Make this context current */
+    void makeCurrent();
+};
+
+/**
  * \brief Simulates a camera frame
  */
 class Simulator {