diff --git a/scwx-qt/source/scwx/qt/gl/draw/draw_item.cpp b/scwx-qt/source/scwx/qt/gl/draw/draw_item.cpp index f4b37fd0..23ddbc8a 100644 --- a/scwx-qt/source/scwx/qt/gl/draw/draw_item.cpp +++ b/scwx-qt/source/scwx/qt/gl/draw/draw_item.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #pragma warning(pop) namespace scwx @@ -46,6 +47,49 @@ void DrawItem::UseDefaultProjection( uMVPMatrixLocation, 1, GL_FALSE, glm::value_ptr(projection)); } +// TODO: Refactor to utility class +static glm::vec2 +LatLongToScreenCoordinate(const QMapbox::Coordinate& coordinate) +{ + double latitude = std::clamp( + coordinate.first, -mbgl::util::LATITUDE_MAX, mbgl::util::LATITUDE_MAX); + glm::vec2 screen { + mbgl::util::LONGITUDE_MAX + coordinate.second, + -(mbgl::util::LONGITUDE_MAX - + mbgl::util::RAD2DEG * + std::log(std::tan(M_PI / 4.0 + + latitude * M_PI / mbgl::util::DEGREES_MAX)))}; + return screen; +} + +void DrawItem::UseMapProjection( + const QMapbox::CustomLayerRenderParameters& params, + GLint uMVPMatrixLocation, + GLint uMapScreenCoordLocation) +{ + OpenGLFunctions& gl = p->gl_; + + // TODO: Refactor to utility class + const float scale = std::pow(2.0, params.zoom) * 2.0f * + mbgl::util::tileSize / mbgl::util::DEGREES_MAX; + const float xScale = scale / params.width; + const float yScale = scale / params.height; + + glm::mat4 uMVPMatrix(1.0f); + uMVPMatrix = glm::scale(uMVPMatrix, glm::vec3(xScale, yScale, 1.0f)); + uMVPMatrix = glm::rotate(uMVPMatrix, + glm::radians(params.bearing), + glm::vec3(0.0f, 0.0f, 1.0f)); + + gl.glUniform2fv(uMapScreenCoordLocation, + 1, + glm::value_ptr(LatLongToScreenCoordinate( + {params.latitude, params.longitude}))); + + gl.glUniformMatrix4fv( + uMVPMatrixLocation, 1, GL_FALSE, glm::value_ptr(uMVPMatrix)); +} + } // namespace draw } // namespace gl } // namespace qt diff --git a/scwx-qt/source/scwx/qt/gl/draw/draw_item.hpp b/scwx-qt/source/scwx/qt/gl/draw/draw_item.hpp index 32a221eb..02086c45 100644 --- a/scwx-qt/source/scwx/qt/gl/draw/draw_item.hpp +++ b/scwx-qt/source/scwx/qt/gl/draw/draw_item.hpp @@ -34,6 +34,9 @@ public: protected: void UseDefaultProjection(const QMapbox::CustomLayerRenderParameters& params, GLint uMVPMatrixLocation); + void UseMapProjection(const QMapbox::CustomLayerRenderParameters& params, + GLint uMVPMatrixLocation, + GLint uMapScreenCoordLocation); private: class Impl; diff --git a/scwx-qt/source/scwx/qt/gl/draw/geo_line.cpp b/scwx-qt/source/scwx/qt/gl/draw/geo_line.cpp index 9b5d1ebd..2ab6047f 100644 --- a/scwx-qt/source/scwx/qt/gl/draw/geo_line.cpp +++ b/scwx-qt/source/scwx/qt/gl/draw/geo_line.cpp @@ -36,6 +36,7 @@ public: modulateColor_ {std::nullopt}, shaderProgram_ {nullptr}, uMVPMatrixLocation_(GL_INVALID_INDEX), + uMapScreenCoordLocation_(GL_INVALID_INDEX), vao_ {GL_INVALID_INDEX}, vbo_ {GL_INVALID_INDEX} { @@ -57,6 +58,7 @@ public: std::shared_ptr shaderProgram_; GLint uMVPMatrixLocation_; + GLint uMapScreenCoordLocation_; GLuint vao_; GLuint vbo_; @@ -88,6 +90,13 @@ void GeoLine::Initialize() logger_->warn("Could not find uMVPMatrix"); } + p->uMapScreenCoordLocation_ = + gl.glGetUniformLocation(p->shaderProgram_->id(), "uMapScreenCoord"); + if (p->uMapScreenCoordLocation_ == -1) + { + logger_->warn("Could not find uMapScreenCoord"); + } + gl.glGenVertexArrays(1, &p->vao_); gl.glGenBuffers(1, &p->vbo_); @@ -146,7 +155,8 @@ void GeoLine::Render(const QMapbox::CustomLayerRenderParameters& params) p->Update(); p->shaderProgram_->Use(); - UseDefaultProjection(params, p->uMVPMatrixLocation_); + UseMapProjection( + params, p->uMVPMatrixLocation_, p->uMapScreenCoordLocation_); // Draw line gl.glDrawArrays(GL_TRIANGLES, 0, 6);