| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | #include "util/opengl_utils.h" |
| |
|
| | #include "util/logging.h" |
| |
|
| | namespace colmap { |
| |
|
| | #ifdef GUI_ENABLED |
| | OpenGLContextManager::OpenGLContextManager(int opengl_major_version, |
| | int opengl_minor_version) |
| | : parent_thread_(QThread::currentThread()), |
| | current_thread_(nullptr), |
| | make_current_action_(new QAction(this)) { |
| | CHECK_NOTNULL(QCoreApplication::instance()); |
| | CHECK_EQ(QCoreApplication::instance()->thread(), QThread::currentThread()); |
| |
|
| | QSurfaceFormat format; |
| | format.setDepthBufferSize(24); |
| | format.setMajorVersion(opengl_major_version); |
| | format.setMinorVersion(opengl_minor_version); |
| | format.setSamples(4); |
| | format.setProfile(QSurfaceFormat::CompatibilityProfile); |
| | context_.setFormat(format); |
| |
|
| | surface_.create(); |
| | CHECK(context_.create()); |
| | context_.makeCurrent(&surface_); |
| | CHECK(context_.isValid()) << "Could not create valid OpenGL context"; |
| |
|
| | connect( |
| | make_current_action_, &QAction::triggered, this, |
| | [this]() { |
| | CHECK_NOTNULL(current_thread_); |
| | context_.doneCurrent(); |
| | context_.moveToThread(current_thread_); |
| | }, |
| | Qt::BlockingQueuedConnection); |
| | } |
| |
|
| | void OpenGLContextManager::MakeCurrent() { |
| | current_thread_ = QThread::currentThread(); |
| | make_current_action_->trigger(); |
| | context_.makeCurrent(&surface_); |
| | CHECK(context_.isValid()) << "Could not make current valid OpenGL context"; |
| | } |
| |
|
| | bool OpenGLContextManager::HasOpenGL() { |
| | #ifdef OPENGL_ENABLED |
| | QOffscreenSurface surface; |
| | QOpenGLContext context; |
| | surface.create(); |
| | context.create(); |
| | return surface.isValid() && context.isValid(); |
| | #else |
| | return false; |
| | #endif |
| | } |
| |
|
| | void RunThreadWithOpenGLContext(Thread* thread) { |
| | std::thread opengl_thread([thread]() { |
| | thread->Start(); |
| | thread->Wait(); |
| | CHECK_NOTNULL(QCoreApplication::instance())->exit(); |
| | }); |
| | CHECK_NOTNULL(QCoreApplication::instance())->exec(); |
| | opengl_thread.join(); |
| | |
| | |
| | QCoreApplication::processEvents(); |
| | } |
| |
|
| | void GLError(const char* file, const int line) { |
| | GLenum error_code(glGetError()); |
| | while (error_code != GL_NO_ERROR) { |
| | std::string error_name; |
| | switch (error_code) { |
| | case GL_INVALID_OPERATION: |
| | error_name = "INVALID_OPERATION"; |
| | break; |
| | case GL_INVALID_ENUM: |
| | error_name = "INVALID_ENUM"; |
| | break; |
| | case GL_INVALID_VALUE: |
| | error_name = "INVALID_VALUE"; |
| | break; |
| | case GL_OUT_OF_MEMORY: |
| | error_name = "OUT_OF_MEMORY"; |
| | break; |
| | case GL_INVALID_FRAMEBUFFER_OPERATION: |
| | error_name = "INVALID_FRAMEBUFFER_OPERATION"; |
| | break; |
| | default: |
| | error_name = "UNKNOWN_ERROR"; |
| | break; |
| | } |
| | fprintf(stderr, "OpenGL error [%s, line %i]: GL_%s", file, line, |
| | error_name.c_str()); |
| | error_code = glGetError(); |
| | } |
| | } |
| |
|
| | #endif |
| |
|
| | } |
| |
|