--- 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)); } }