ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
opengl_utils.cc
Go to the documentation of this file.
1 // Copyright (c) 2018, ETH Zurich and UNC Chapel Hill.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are met:
6 //
7 // * Redistributions of source code must retain the above copyright
8 // notice, this list of conditions and the following disclaimer.
9 //
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 //
14 // * Neither the name of ETH Zurich and UNC Chapel Hill nor the names of
15 // its contributors may be used to endorse or promote products derived
16 // from this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
22 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 // POSSIBILITY OF SUCH DAMAGE.
29 //
30 // Author: Johannes L. Schoenberger (jsch-at-demuc-dot-de)
31 
32 #include "util/opengl_utils.h"
33 
34 #include "util/logging.h"
35 
36 namespace colmap {
37 
38 #ifdef GUI_ENABLED
39 OpenGLContextManager::OpenGLContextManager(int opengl_major_version,
40  int opengl_minor_version)
41  : parent_thread_(QThread::currentThread()),
42  current_thread_(nullptr),
43  make_current_action_(new QAction(this)) {
44  CHECK_NOTNULL(QCoreApplication::instance());
45  CHECK_EQ(QCoreApplication::instance()->thread(), QThread::currentThread());
46 
47  QSurfaceFormat format;
48  format.setDepthBufferSize(24);
49  format.setMajorVersion(opengl_major_version);
50  format.setMinorVersion(opengl_minor_version);
51  format.setSamples(4);
52  format.setProfile(QSurfaceFormat::CompatibilityProfile);
53  context_.setFormat(format);
54 
55  surface_.create();
56  CHECK(context_.create());
57  context_.makeCurrent(&surface_);
58  CHECK(context_.isValid()) << "Could not create valid OpenGL context";
59 
60  connect(
61  make_current_action_, &QAction::triggered, this,
62  [this]() {
63  CHECK_NOTNULL(current_thread_);
64  context_.doneCurrent();
65  context_.moveToThread(current_thread_);
66  },
67  Qt::BlockingQueuedConnection);
68 }
69 
70 void OpenGLContextManager::MakeCurrent() {
71  current_thread_ = QThread::currentThread();
72  make_current_action_->trigger();
73  context_.makeCurrent(&surface_);
74  CHECK(context_.isValid()) << "Could not make current valid OpenGL context";
75 }
76 
77 bool OpenGLContextManager::HasOpenGL() {
78 #ifdef OPENGL_ENABLED
79  QOffscreenSurface surface;
80  QOpenGLContext context;
81  surface.create();
82  context.create();
83  return surface.isValid() && context.isValid();
84 #else // OPENGL_ENABLED
85  return false;
86 #endif // OPENGL_ENABLED
87 }
88 
89 void RunThreadWithOpenGLContext(Thread* thread) {
90  std::thread opengl_thread([thread]() {
91  thread->Start();
92  thread->Wait();
93  CHECK_NOTNULL(QCoreApplication::instance())->exit();
94  });
95  CHECK_NOTNULL(QCoreApplication::instance())->exec();
96  opengl_thread.join();
97  // Make sure that all triggered OpenGLContextManager events are processed in
98  // case the application exits before the contexts were made current.
99  QCoreApplication::processEvents();
100 }
101 
102 void GLError(const char* file, const int line) {
103  GLenum error_code(glGetError());
104  while (error_code != GL_NO_ERROR) {
105  std::string error_name;
106  switch (error_code) {
107  case GL_INVALID_OPERATION:
108  error_name = "INVALID_OPERATION";
109  break;
110  case GL_INVALID_ENUM:
111  error_name = "INVALID_ENUM";
112  break;
113  case GL_INVALID_VALUE:
114  error_name = "INVALID_VALUE";
115  break;
116  case GL_OUT_OF_MEMORY:
117  error_name = "OUT_OF_MEMORY";
118  break;
119  case GL_INVALID_FRAMEBUFFER_OPERATION:
120  error_name = "INVALID_FRAMEBUFFER_OPERATION";
121  break;
122  default:
123  error_name = "UNKNOWN_ERROR";
124  break;
125  }
126  fprintf(stderr, "OpenGL error [%s, line %i]: GL_%s", file, line,
127  error_name.c_str());
128  error_code = glGetError();
129  }
130 }
131 
132 #endif
133 
134 } // namespace colmap
filament::Texture::InternalFormat format
OpenGLContextManager(int opengl_major_version=2, int opengl_minor_version=1)
Definition: opengl_utils.h:75
ImGuiContext * context
Definition: Window.cpp:76
void GLError(const char *file, const int line)
Definition: opengl_utils.h:83
void RunThreadWithOpenGLContext(Thread *thread)
Definition: opengl_utils.h:81