From 59be110c100df4ab8c4aa35cea9def0e43f30e18 Mon Sep 17 00:00:00 2001 From: Dan Paulat Date: Fri, 23 Jul 2021 21:30:51 -0500 Subject: [PATCH] Creating OpenGL utility class, consolidating number of OpenGL function objects --- scwx-qt/scwx-qt.cmake | 3 +- scwx-qt/source/scwx/qt/map/map_widget.cpp | 76 ++++++++++++------- scwx-qt/source/scwx/qt/map/map_widget.hpp | 11 +-- scwx-qt/source/scwx/qt/map/radar_layer.cpp | 28 ++++--- scwx-qt/source/scwx/qt/map/radar_layer.hpp | 4 +- scwx-qt/source/scwx/qt/map/triangle_layer.cpp | 21 ++--- scwx-qt/source/scwx/qt/map/triangle_layer.hpp | 8 +- scwx-qt/source/scwx/qt/util/gl.hpp | 23 ++++++ .../source/scwx/qt/util/shader_program.cpp | 15 ++-- .../source/scwx/qt/util/shader_program.hpp | 8 +- 10 files changed, 124 insertions(+), 73 deletions(-) create mode 100644 scwx-qt/source/scwx/qt/util/gl.hpp diff --git a/scwx-qt/scwx-qt.cmake b/scwx-qt/scwx-qt.cmake index bf1a19d8..57d1d123 100644 --- a/scwx-qt/scwx-qt.cmake +++ b/scwx-qt/scwx-qt.cmake @@ -59,7 +59,8 @@ set(SRC_MAP source/scwx/qt/map/map_widget.cpp source/scwx/qt/map/radar_layer.cpp source/scwx/qt/map/radar_range_layer.cpp source/scwx/qt/map/triangle_layer.cpp) -set(HDR_UTIL source/scwx/qt/util/shader_program.hpp) +set(HDR_UTIL source/scwx/qt/util/gl.hpp + source/scwx/qt/util/shader_program.hpp) set(SRC_UTIL source/scwx/qt/util/shader_program.cpp) set(RESOURCE_FILES scwx-qt.qrc) diff --git a/scwx-qt/source/scwx/qt/map/map_widget.cpp b/scwx-qt/source/scwx/qt/map/map_widget.cpp index 67b7b928..4f75673f 100644 --- a/scwx-qt/source/scwx/qt/map/map_widget.cpp +++ b/scwx-qt/source/scwx/qt/map/map_widget.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -31,7 +32,27 @@ static const MapStyle satelliteStreets { "mapbox://styles/mapbox/satellite-stree static const std::array mapboxStyles_ = { {streets, outdoors, light, dark, satellite, satelliteStreets}}; -MapWidget::MapWidget(const QMapboxGLSettings& settings) : settings_(settings) +class MapWidgetImpl +{ +public: + explicit MapWidgetImpl(const QMapboxGLSettings& settings) : + gl_(), settings_(settings), map_(), lastPos_(), frameDraws_(0) + { + } + ~MapWidgetImpl() = default; + + OpenGLFunctions gl_; + + QMapboxGLSettings settings_; + std::shared_ptr map_; + + QPointF lastPos_; + + uint64_t frameDraws_; +}; + +MapWidget::MapWidget(const QMapboxGLSettings& settings) : + p(std::make_unique(settings)) { setFocusPolicy(Qt::StrongFocus); } @@ -54,7 +75,7 @@ void MapWidget::changeStyle() auto& styles = mapboxStyles_; - map_->setStyleUrl(styles[currentStyleIndex].first.c_str()); + p->map_->setStyleUrl(styles[currentStyleIndex].first.c_str()); setWindowTitle(QString("Mapbox GL: ") + styles[currentStyleIndex].second.c_str()); @@ -68,11 +89,11 @@ void MapWidget::AddLayers() { // QMapboxGL::addCustomLayer will take ownership of the QScopedPointer QScopedPointer pHost( - new RadarLayer(map_)); + new RadarLayer(p->map_, p->gl_)); QString before = "ferry"; - for (const QString& layer : map_->layerIds()) + for (const QString& layer : p->map_->layerIds()) { // Draw below tunnels, ferries and roads if (layer.startsWith("tunnel") || layer.startsWith("ferry") || @@ -83,8 +104,8 @@ void MapWidget::AddLayers() } } - map_->addCustomLayer("radar", pHost, before); - RadarRangeLayer::Add(map_, before); + p->map_->addCustomLayer("radar", pHost, before); + RadarRangeLayer::Add(p->map_, before); } void MapWidget::keyPressEvent(QKeyEvent* ev) @@ -94,7 +115,7 @@ void MapWidget::keyPressEvent(QKeyEvent* ev) case Qt::Key_S: changeStyle(); break; case Qt::Key_L: { - for (const QString& layer : map_->layerIds()) + for (const QString& layer : p->map_->layerIds()) { qDebug() << "Layer: " << layer; } @@ -108,7 +129,7 @@ void MapWidget::keyPressEvent(QKeyEvent* ev) void MapWidget::mousePressEvent(QMouseEvent* ev) { - lastPos_ = ev->position(); + p->lastPos_ = ev->position(); if (ev->type() == QEvent::MouseButtonPress) { @@ -122,11 +143,11 @@ void MapWidget::mousePressEvent(QMouseEvent* ev) { if (ev->buttons() == Qt::LeftButton) { - map_->scaleBy(2.0, lastPos_); + p->map_->scaleBy(2.0, p->lastPos_); } else if (ev->buttons() == Qt::RightButton) { - map_->scaleBy(0.5, lastPos_); + p->map_->scaleBy(0.5, p->lastPos_); } } @@ -135,26 +156,26 @@ void MapWidget::mousePressEvent(QMouseEvent* ev) void MapWidget::mouseMoveEvent(QMouseEvent* ev) { - QPointF delta = ev->position() - lastPos_; + QPointF delta = ev->position() - p->lastPos_; if (!delta.isNull()) { if (ev->buttons() == Qt::LeftButton && ev->modifiers() & Qt::ShiftModifier) { - map_->pitchBy(delta.y()); + p->map_->pitchBy(delta.y()); } else if (ev->buttons() == Qt::LeftButton) { - map_->moveBy(delta); + p->map_->moveBy(delta); } else if (ev->buttons() == Qt::RightButton) { - map_->rotateBy(lastPos_, ev->position()); + p->map_->rotateBy(p->lastPos_, ev->position()); } } - lastPos_ = ev->position(); + p->lastPos_ = ev->position(); ev->accept(); } @@ -171,18 +192,21 @@ void MapWidget::wheelEvent(QWheelEvent* ev) factor = factor > -1 ? factor : 1 / factor; } - map_->scaleBy(1 + factor, ev->position()); + p->map_->scaleBy(1 + factor, ev->position()); ev->accept(); } void MapWidget::initializeGL() { - map_.reset(new QMapboxGL(nullptr, settings_, size(), pixelRatio())); - connect(map_.get(), SIGNAL(needsRendering()), this, SLOT(update())); + makeCurrent(); + p->gl_.initializeOpenGLFunctions(); + + p->map_.reset(new QMapboxGL(nullptr, p->settings_, size(), pixelRatio())); + connect(p->map_.get(), SIGNAL(needsRendering()), this, SLOT(update())); // Set default location to KLSX. - map_->setCoordinateZoom(QMapbox::Coordinate(38.6986, -90.6828), 11); + p->map_->setCoordinateZoom(QMapbox::Coordinate(38.6986, -90.6828), 11); QString styleUrl = qgetenv("MAPBOX_STYLE_URL"); if (styleUrl.isEmpty()) @@ -191,20 +215,20 @@ void MapWidget::initializeGL() } else { - map_->setStyleUrl(styleUrl); + p->map_->setStyleUrl(styleUrl); setWindowTitle(QString("Mapbox GL: ") + styleUrl); } - connect(map_.get(), &QMapboxGL::mapChanged, this, &MapWidget::mapChanged); + connect(p->map_.get(), &QMapboxGL::mapChanged, this, &MapWidget::mapChanged); } void MapWidget::paintGL() { - frameDraws_++; - map_->resize(size()); - map_->setFramebufferObject(defaultFramebufferObject(), - size() * pixelRatio()); - map_->render(); + p->frameDraws_++; + p->map_->resize(size()); + p->map_->setFramebufferObject(defaultFramebufferObject(), + size() * pixelRatio()); + p->map_->render(); } void MapWidget::mapChanged(QMapboxGL::MapChange mapChange) diff --git a/scwx-qt/source/scwx/qt/map/map_widget.hpp b/scwx-qt/source/scwx/qt/map/map_widget.hpp index 43837088..6d7f5cb5 100644 --- a/scwx-qt/source/scwx/qt/map/map_widget.hpp +++ b/scwx-qt/source/scwx/qt/map/map_widget.hpp @@ -17,12 +17,14 @@ namespace scwx namespace qt { +class MapWidgetImpl; + class MapWidget : public QOpenGLWidget { Q_OBJECT public: - MapWidget(const QMapboxGLSettings&); + explicit MapWidget(const QMapboxGLSettings&); ~MapWidget(); private: @@ -41,12 +43,7 @@ private: void AddLayers(); - QPointF lastPos_; - - QMapboxGLSettings settings_; - std::shared_ptr map_; - - uint64_t frameDraws_ = 0; + std::unique_ptr p; private slots: void mapChanged(QMapboxGL::MapChange); diff --git a/scwx-qt/source/scwx/qt/map/radar_layer.cpp b/scwx-qt/source/scwx/qt/map/radar_layer.cpp index 39c2357e..6be1840a 100644 --- a/scwx-qt/source/scwx/qt/map/radar_layer.cpp +++ b/scwx-qt/source/scwx/qt/map/radar_layer.cpp @@ -3,8 +3,6 @@ #include -#include - #include #include #include @@ -30,10 +28,11 @@ LatLongToScreenCoordinate(const QMapbox::Coordinate& coordinate); class RadarLayerImpl { public: - explicit RadarLayerImpl(std::shared_ptr map) : + explicit RadarLayerImpl(std::shared_ptr map, + OpenGLFunctions& gl) : map_(map), - gl_(), - shaderProgram_(), + gl_(gl), + shaderProgram_(gl), uMVPMatrixLocation_(GL_INVALID_INDEX), uMapScreenCoordLocation_(GL_INVALID_INDEX), vbo_ {GL_INVALID_INDEX}, @@ -42,13 +41,12 @@ public: bearing_ {0.0}, numVertices_ {0} { - gl_.initializeOpenGLFunctions(); } ~RadarLayerImpl() = default; std::shared_ptr map_; - QOpenGLFunctions_3_3_Core gl_; + OpenGLFunctions& gl_; ShaderProgram shaderProgram_; GLint uMVPMatrixLocation_; @@ -62,8 +60,8 @@ public: GLsizeiptr numVertices_; }; -RadarLayer::RadarLayer(std::shared_ptr map) : - p(std::make_unique(map)) +RadarLayer::RadarLayer(std::shared_ptr map, OpenGLFunctions& gl) : + p(std::make_unique(map, gl)) { } RadarLayer::~RadarLayer() = default; @@ -75,7 +73,7 @@ void RadarLayer::initialize() { BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "initialize()"; - QOpenGLFunctions_3_3_Core& gl = p->gl_; + OpenGLFunctions& gl = p->gl_; boost::timer::cpu_timer timer; @@ -134,7 +132,7 @@ void RadarLayer::initialize() }); timer.stop(); BOOST_LOG_TRIVIAL(debug) - << "Coordinates calculated in " << timer.format(6, "%ws"); + << logPrefix_ << "Coordinates calculated in " << timer.format(6, "%ws"); // Calculate vertices static std::array @@ -185,7 +183,7 @@ void RadarLayer::initialize() } timer.stop(); BOOST_LOG_TRIVIAL(debug) - << "Vertices calculated in " << timer.format(6, "%ws"); + << logPrefix_ << "Vertices calculated in " << timer.format(6, "%ws"); // Generate a vertex buffer object gl.glGenBuffers(1, &p->vbo_); @@ -205,7 +203,7 @@ void RadarLayer::initialize() GL_STATIC_DRAW); timer.stop(); BOOST_LOG_TRIVIAL(debug) - << "Vertices buffered in " << timer.format(6, "%ws"); + << logPrefix_ << "Vertices buffered in " << timer.format(6, "%ws"); // Set the vertex attributes pointers gl.glVertexAttribPointer( @@ -218,7 +216,7 @@ void RadarLayer::initialize() void RadarLayer::render(const QMapbox::CustomLayerRenderParameters& params) { - QOpenGLFunctions_3_3_Core& gl = p->gl_; + OpenGLFunctions& gl = p->gl_; p->shaderProgram_.Use(); @@ -249,7 +247,7 @@ void RadarLayer::render(const QMapbox::CustomLayerRenderParameters& params) void RadarLayer::deinitialize() { - QOpenGLFunctions_3_3_Core& gl = p->gl_; + OpenGLFunctions& gl = p->gl_; BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "deinitialize()"; diff --git a/scwx-qt/source/scwx/qt/map/radar_layer.hpp b/scwx-qt/source/scwx/qt/map/radar_layer.hpp index c8c3eac0..dce792dc 100644 --- a/scwx-qt/source/scwx/qt/map/radar_layer.hpp +++ b/scwx-qt/source/scwx/qt/map/radar_layer.hpp @@ -1,5 +1,7 @@ #pragma once +#include + #include namespace scwx @@ -12,7 +14,7 @@ class RadarLayerImpl; class RadarLayer : public QMapbox::CustomLayerHostInterface { public: - explicit RadarLayer(std::shared_ptr map); + explicit RadarLayer(std::shared_ptr map, OpenGLFunctions& gl); ~RadarLayer(); RadarLayer(const RadarLayer&) = delete; diff --git a/scwx-qt/source/scwx/qt/map/triangle_layer.cpp b/scwx-qt/source/scwx/qt/map/triangle_layer.cpp index 79c0d191..5b52c342 100644 --- a/scwx-qt/source/scwx/qt/map/triangle_layer.cpp +++ b/scwx-qt/source/scwx/qt/map/triangle_layer.cpp @@ -1,7 +1,5 @@ #include -#include - #include namespace scwx @@ -9,13 +7,13 @@ namespace scwx namespace qt { -static const std::string logPrefix_ = "[scwx::map::triangle_layer] "; +static const std::string logPrefix_ = "[scwx::qt::map::triangle_layer] "; class TriangleLayerImpl { public: - explicit TriangleLayerImpl() : - gl_(), + explicit TriangleLayerImpl(OpenGLFunctions& gl) : + gl_(gl), shaderProgram_ {GL_INVALID_INDEX}, vbo_ {GL_INVALID_INDEX}, vao_ {GL_INVALID_INDEX} @@ -24,14 +22,17 @@ public: } ~TriangleLayerImpl() = default; - QOpenGLFunctions_3_3_Core gl_; + OpenGLFunctions& gl_; GLuint shaderProgram_; GLuint vbo_; GLuint vao_; }; -TriangleLayer::TriangleLayer() : p(std::make_unique()) {} +TriangleLayer::TriangleLayer(OpenGLFunctions& gl) : + p(std::make_unique(gl)) +{ +} TriangleLayer::~TriangleLayer() = default; TriangleLayer::TriangleLayer(TriangleLayer&&) noexcept = default; @@ -39,7 +40,7 @@ TriangleLayer& TriangleLayer::operator=(TriangleLayer&&) noexcept = default; void TriangleLayer::initialize() { - QOpenGLFunctions_3_3_Core& gl = p->gl_; + OpenGLFunctions& gl = p->gl_; static const char* vertexShaderSource = "#version 330 core\n" @@ -141,7 +142,7 @@ void TriangleLayer::initialize() void TriangleLayer::render(const QMapbox::CustomLayerRenderParameters&) { - QOpenGLFunctions_3_3_Core& gl = p->gl_; + OpenGLFunctions& gl = p->gl_; gl.glUseProgram(p->shaderProgram_); gl.glBindVertexArray(p->vao_); @@ -150,7 +151,7 @@ void TriangleLayer::render(const QMapbox::CustomLayerRenderParameters&) void TriangleLayer::deinitialize() { - QOpenGLFunctions_3_3_Core& gl = p->gl_; + OpenGLFunctions& gl = p->gl_; BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "deinitialize()"; diff --git a/scwx-qt/source/scwx/qt/map/triangle_layer.hpp b/scwx-qt/source/scwx/qt/map/triangle_layer.hpp index 7020f4b7..e62701c3 100644 --- a/scwx-qt/source/scwx/qt/map/triangle_layer.hpp +++ b/scwx-qt/source/scwx/qt/map/triangle_layer.hpp @@ -1,4 +1,8 @@ -#include +#pragma once + +#include + +#include namespace scwx { @@ -10,7 +14,7 @@ class TriangleLayerImpl; class TriangleLayer : public QMapbox::CustomLayerHostInterface { public: - explicit TriangleLayer(); + explicit TriangleLayer(OpenGLFunctions& gl); ~TriangleLayer(); TriangleLayer(const TriangleLayer&) = delete; diff --git a/scwx-qt/source/scwx/qt/util/gl.hpp b/scwx-qt/source/scwx/qt/util/gl.hpp new file mode 100644 index 00000000..26e11ef5 --- /dev/null +++ b/scwx-qt/source/scwx/qt/util/gl.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include + +#define SCWX_GL_CHECK_ERROR() \ + { \ + GLenum err; \ + while ((err = p->gl_.glGetError()) != GL_NO_ERROR) \ + { \ + BOOST_LOG_TRIVIAL(warning) << logPrefix_ << "GL Error: " << err \ + << ", " __FILE__ << ":" << __LINE__; \ + } \ + } + +namespace scwx +{ +namespace qt +{ + +using OpenGLFunctions = QOpenGLFunctions_3_3_Core; + +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/util/shader_program.cpp b/scwx-qt/source/scwx/qt/util/shader_program.cpp index 7c00d824..1b707360 100644 --- a/scwx-qt/source/scwx/qt/util/shader_program.cpp +++ b/scwx-qt/source/scwx/qt/util/shader_program.cpp @@ -1,7 +1,6 @@ #include #include -#include #include @@ -15,10 +14,9 @@ static const std::string logPrefix_ = "[scwx::qt::util::shader_program] "; class ShaderProgramImpl { public: - explicit ShaderProgramImpl() : gl_(), id_ {GL_INVALID_INDEX} + explicit ShaderProgramImpl(OpenGLFunctions& gl) : + gl_(gl), id_ {GL_INVALID_INDEX} { - gl_.initializeOpenGLFunctions(); - // Create shader program id_ = gl_.glCreateProgram(); } @@ -29,12 +27,15 @@ public: gl_.glDeleteProgram(id_); } - QOpenGLFunctions_3_3_Core gl_; + OpenGLFunctions& gl_; GLuint id_; }; -ShaderProgram::ShaderProgram() : p(std::make_unique()) {} +ShaderProgram::ShaderProgram(OpenGLFunctions& gl) : + p(std::make_unique(gl)) +{ +} ShaderProgram::~ShaderProgram() = default; ShaderProgram::ShaderProgram(ShaderProgram&&) noexcept = default; @@ -50,7 +51,7 @@ bool ShaderProgram::Load(const std::string& vertexPath, { BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "Load()"; - QOpenGLFunctions_3_3_Core& gl = p->gl_; + OpenGLFunctions& gl = p->gl_; GLint glSuccess; bool success = true; diff --git a/scwx-qt/source/scwx/qt/util/shader_program.hpp b/scwx-qt/source/scwx/qt/util/shader_program.hpp index 0703ed68..a10a6f12 100644 --- a/scwx-qt/source/scwx/qt/util/shader_program.hpp +++ b/scwx-qt/source/scwx/qt/util/shader_program.hpp @@ -1,14 +1,14 @@ #pragma once +#include + #ifdef _WIN32 -#include +# include #endif #include #include -#include - namespace scwx { namespace qt @@ -19,7 +19,7 @@ class ShaderProgramImpl; class ShaderProgram { public: - explicit ShaderProgram(); + explicit ShaderProgram(OpenGLFunctions& gl); ~ShaderProgram(); ShaderProgram(const ShaderProgram&) = delete;