# HG changeset patch # User Teemu Piippo # Date 1582836399 -7200 # Node ID 4585d8d7a7eced1318baab7274ff6ab723159992 # Parent 0f221121849b5621dc5fd027bfc914594a69da53 moved GridProgram to Canvas diff -r 0f221121849b -r 4585d8d7a7ec src/gl/partrenderer.cpp --- a/src/gl/partrenderer.cpp Thu Feb 27 14:38:58 2020 +0200 +++ b/src/gl/partrenderer.cpp Thu Feb 27 22:46:39 2020 +0200 @@ -34,8 +34,7 @@ model{model}, documents{documents}, colorTable{colorTable}, - compiler{new gl::Compiler{this->colorTable, this}}, - gridProgram{this} + compiler{new gl::Compiler{this->colorTable, this}} { this->setMouseTracking(true); } @@ -46,7 +45,11 @@ static QVector3D vec3FromQColor(const QColor& color) { - return {(float)color.redF(), (float)color.greenF(), (float)color.blueF()}; + return { + toFloat(color.redF()), + toFloat(color.greenF()), + toFloat(color.blueF()), + }; } void PartRenderer::initializeGL() @@ -56,8 +59,6 @@ { abort(); } - this->gridProgram.emplace(this); - this->gridProgram->initialize(); this->compiler->initialize(); this->compiler->build(this->model, this->documents, this->renderPreferences); this->initialized = true; @@ -79,7 +80,7 @@ 0.1f, 10000.f); this->compiler->setUniformMatrix("projectionMatrix", this->projectionMatrix); - this->gridProgram->setProjectionMatrix(this->projectionMatrix); + emit projectionMatrixChanged(); } static GLenum getGlTypeForArrayClass(const gl::ArrayClass vboClass) @@ -173,10 +174,6 @@ this->renderAllArrays(); break; } - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - this->gridProgram->draw(); - glDisable(GL_BLEND); glDisable(GL_POLYGON_OFFSET_FILL); } @@ -195,24 +192,19 @@ const double z = 2 * std::exp(this->zoom) * (1 + this->compiler->modelDistance()); this->viewMatrix = glm::lookAt(glm::vec3{0, 0, z}, {0, 0, 0}, {0, -1, 0}); this->compiler->setUniformMatrix("viewMatrix", this->viewMatrix); - this->gridProgram->setViewMatrix(this->viewMatrix); + emit this->viewMatrixChanged(); } void PartRenderer::updateModelMatrix() { - const glm::mat4 modelMatrix = glm::mat4_cast(this->modelQuaternion); + this->modelMatrix = glm::mat4_cast(this->modelQuaternion); this->compiler->setUniformMatrix("modelMatrix", modelMatrix); - this->gridProgram->setModelMatrix(modelMatrix); + emit this->modelMatrixChanged(); this->update(); } void PartRenderer::setupBackgroundColor() { - if (this->gridProgram.has_value()) - { - const bool isDark = luma(this->renderPreferences.backgroundColor) < 0.25; - this->gridProgram->setGridColor(isDark ? Qt::white : Qt::black); - } } void PartRenderer::renderVao(const gl::ArrayClass arrayClass) @@ -255,7 +247,7 @@ void PartRenderer::mouseMoveEvent(QMouseEvent* event) { const bool left = event->buttons() & Qt::LeftButton; - const QPointF move = pointToPointF(event->pos()) - this->lastMousePosition; + const QPoint move = event->pos() - this->lastMousePosition; if (left and not move.isNull()) { // q_x is the rotation of the brick along the vertical y-axis, because turning the @@ -269,7 +261,7 @@ this->modelQuaternion = q_x * q_y * this->modelQuaternion; this->updateModelMatrix(); } - this->lastMousePosition = pointToPointF(event->pos()); + this->lastMousePosition = event->pos(); } void PartRenderer::wheelEvent(QWheelEvent* event) @@ -281,11 +273,6 @@ this->update(); } -glm::vec3 PartRenderer::viewport(const glm::vec3& point) -{ - return viewport(point, this->width(), this->height()); -} - /** * @brief Converts the specified on the screen into the 3D world. The point is unprojected twice into 3D and the * intersection of the resulting line with the specified plane is returned. If the intersection point lies behind @@ -296,9 +283,9 @@ */ std::optional PartRenderer::screenToModelCoordinates(const QPoint& point, const geom::Plane& plane) { - auto p1 = this->unproject({point.x(), point.y(), 0}); - auto p2 = this->unproject({point.x(), point.y(), 1}); - geom::Line line = geom::lineFromPoints(p1, p2); + const glm::vec3 p1 = this->unproject({point.x(), point.y(), 0}); + const glm::vec3 p2 = this->unproject({point.x(), point.y(), 1}); + const geom::Line line = geom::lineFromPoints(p1, p2); std::optional result; result = geom::linePlaneIntersection(line, plane, 0.01f); // If the point lies behind the camera, do not return a result. @@ -376,14 +363,6 @@ this->compiler->build(this->model, this->documents, this->renderPreferences); this->setupBackgroundColor(); } + emit this->renderPreferencesChanged(); this->update(); } - -glm::vec3 PartRenderer::viewport(const glm::vec3& point, float width, float height) -{ - return { - width * 0.5 * (point.x + 1), - height * 0.5 * (-point.y + 1), - 0 - }; -} diff -r 0f221121849b -r 4585d8d7a7ec src/gl/partrenderer.h --- a/src/gl/partrenderer.h Thu Feb 27 14:38:58 2020 +0200 +++ b/src/gl/partrenderer.h Thu Feb 27 22:46:39 2020 +0200 @@ -10,7 +10,6 @@ #include "main.h" #include "gl/common.h" #include "gl/compiler.h" -#include "gl/gridprogram.h" class PartRenderer : public QOpenGLWidget, protected QOpenGLFunctions { @@ -23,8 +22,6 @@ QWidget* parent = nullptr); ~PartRenderer() override; void setRenderPreferences(const gl::RenderPreferences& newPreferences); - static glm::vec3 viewport(const glm::vec3& point, float width, float height); - static glm::vec3 antiviewport(const glm::vec3& point, float width, float height); protected: ldraw::Id pick(const QPoint& where); void initializeGL() override; @@ -32,7 +29,6 @@ void paintGL() override; void mouseMoveEvent(QMouseEvent* event) override; void wheelEvent(QWheelEvent* event) override; - glm::vec3 viewport(const glm::vec3& point); Model* const model; DocumentManager* const documents; const ldraw::ColorTable& colorTable; @@ -41,6 +37,18 @@ std::optional screenToModelCoordinates(const QPoint& point, const geom::Plane& plane); QPointF modelToScreenCoordinates(const glm::vec3& point); glm::vec3 unproject(const glm::vec3& win); + glm::mat4 projectionMatrix; + glm::mat4 viewMatrix; + glm::mat4 modelMatrix; + glm::vec4 viewportVector; + glm::quat modelQuaternion; + QPoint lastMousePosition; + gl::RenderPreferences renderPreferences; +signals: + void projectionMatrixChanged(); + void modelMatrixChanged(); + void viewMatrixChanged(); + void renderPreferencesChanged(); private: void setFragmentStyle(gl::FragmentStyle fragStyle); void renderAllArrays(); @@ -48,13 +56,6 @@ void updateViewMatrix(); void updateModelMatrix(); void setupBackgroundColor(); - QPointF lastMousePosition; - gl::RenderPreferences renderPreferences; - glm::mat4 projectionMatrix; - glm::mat4 viewMatrix; - glm::vec4 viewportVector; - glm::quat modelQuaternion; - std::optional gridProgram; static constexpr double MIN_ZOOM = 0.0; static constexpr double MAX_ZOOM = 3.0; double zoom = 1.0; diff -r 0f221121849b -r 4585d8d7a7ec src/ui/canvas.cpp --- a/src/ui/canvas.cpp Thu Feb 27 14:38:58 2020 +0200 +++ b/src/ui/canvas.cpp Thu Feb 27 22:46:39 2020 +0200 @@ -7,7 +7,8 @@ DocumentManager* documents, const ldraw::ColorTable& colorTable, QWidget* parent) : - PartRenderer{model, documents, colorTable, parent} + PartRenderer{model, documents, colorTable, parent}, + gridProgram{this} { this->setMouseTracking(true); } @@ -21,13 +22,20 @@ this->update(); } +QString vectorToString(const glm::vec3& vec) +{ + return "(%1, %2, %3)"_q + .arg(toDouble(vec.x)) + .arg(toDouble(vec.y)) + .arg(toDouble(vec.z)); +} + void Canvas::mouseMoveEvent(QMouseEvent* event) { const ldraw::Id id = this->pick(event->pos()); this->highlighted = id; this->totalMouseMove += (event->pos() - this->lastMousePosition).manhattanLength(); - this->lastMousePosition = event->pos(); - this->worldPosition = this->screenToModelCoordinates(this->lastMousePosition, geom::XY); + this->worldPosition = this->screenToModelCoordinates(event->pos(), geom::XY); if (this->worldPosition.has_value()) { this->worldPosition = glm::round(*this->worldPosition); @@ -35,9 +43,9 @@ if (this->worldPosition.has_value()) { this->newStatusText("Position: (%1, %2, %3)"_q - .arg(this->worldPosition->x) - .arg(this->worldPosition->y) - .arg(this->worldPosition->z)); + .arg(toDouble(this->worldPosition->x)) + .arg(toDouble(this->worldPosition->y)) + .arg(toDouble(this->worldPosition->z))); } else { @@ -72,15 +80,51 @@ PartRenderer::mouseReleaseEvent(event); } +void Canvas::initializeGL() +{ + // We first create the grid program and connect everything and only then call the part renderer's initialization + // functions so that when initialization sets up, the signals also set up the matrices on our side. + this->gridProgram.emplace(this); + this->gridProgram->initialize(); + connect(this, &PartRenderer::projectionMatrixChanged, [&]() + { + this->gridProgram->setProjectionMatrix(this->projectionMatrix); + }); + connect(this, &PartRenderer::modelMatrixChanged, [&]() + { + this->gridProgram->setModelMatrix(this->modelMatrix); + }); + connect(this, &PartRenderer::viewMatrixChanged, [&]() + { + this->gridProgram->setViewMatrix(this->viewMatrix); + }); + connect(this, &PartRenderer::renderPreferencesChanged, [&]() + { + if (this->gridProgram.has_value()) + { + const bool isDark = luma(this->renderPreferences.backgroundColor) < 0.25; + this->gridProgram->setGridColor(isDark ? Qt::white : Qt::black); + } + }); + PartRenderer::initializeGL(); +} + void Canvas::paintGL() { PartRenderer::paintGL(); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + this->gridProgram->draw(); + glDisable(GL_BLEND); if (this->worldPosition.has_value()) { QPainter painter{this}; painter.setRenderHint(QPainter::Antialiasing); painter.setPen(Qt::black); painter.setBrush(Qt::green); - painter.drawEllipse(this->modelToScreenCoordinates(*this->worldPosition), 10, 10); + const QPointF pos = this->modelToScreenCoordinates(*this->worldPosition); + painter.drawEllipse(pos, 5, 5); + painter.setPen(Qt::white); + painter.drawText(pos + QPointF{5, 5}, vectorToString(*this->worldPosition)); } } diff -r 0f221121849b -r 4585d8d7a7ec src/ui/canvas.h --- a/src/ui/canvas.h Thu Feb 27 14:38:58 2020 +0200 +++ b/src/ui/canvas.h Thu Feb 27 22:46:39 2020 +0200 @@ -1,5 +1,6 @@ #pragma once #include "gl/partrenderer.h" +#include "gl/gridprogram.h" class Canvas : public PartRenderer { @@ -16,12 +17,13 @@ void mouseMoveEvent(QMouseEvent* event) override; void mousePressEvent(QMouseEvent* event) override; void mouseReleaseEvent(QMouseEvent* event) override; + void initializeGL() override; void paintGL() override; signals: void newStatusText(const QString& newStatusText); void selectionChanged(const QSet& newSelection); private: - QPoint lastMousePosition; + std::optional gridProgram; std::optional worldPosition; int totalMouseMove = 0; QSet selection;