# HG changeset patch # User Teemu Piippo # Date 1655733549 -10800 # Node ID 87ee9824210bbe89a1cf28b56dcaccd00cb0fdad # Parent 5509bec02c81999d95422b52501b11441d6a74bf Readd axis labels, fix antialiasing diff -r 5509bec02c81 -r 87ee9824210b src/gl/axesprogram.cpp --- a/src/gl/axesprogram.cpp Mon Jun 20 16:43:56 2022 +0300 +++ b/src/gl/axesprogram.cpp Mon Jun 20 16:59:09 2022 +0300 @@ -16,7 +16,10 @@ * along with this program. If not, see . */ +#include +#include #include "axesprogram.h" +#include "gl/partrenderer.h" static constexpr char vertexShaderSource[] = R"( #version 330 core @@ -87,6 +90,72 @@ this->shader.bufferData(&data[0], countof(data), sizeof data[0]); } +void drawBorderedText(QPainter* painter, const QPointF& point, const QFont& font, const QString& text) +{ + QPainterPath path; + path.addText(point, font, text); + painter->save(); + painter->setBrush(Qt::white); + painter->setPen({Qt::black, 0.1 * font.pointSizeF()}); + painter->drawPath(path); + painter->restore(); +} + +void AxesLayer::overpaint(QPainter* painter) +{ + QFont font; + font.setStyle(QFont::StyleItalic); + font.setBold(true); + painter->setFont(font); + QFontMetrics fontMetrics{font}; + const auto renderText = [&](const QString& text, const PointOnRectagle& intersection) + { + QPointF position = toQPointF(intersection.position); + const RectangleSide side = intersection.side; + switch (side) + { + case RectangleSide::Top: + position += QPointF{0, static_cast(fontMetrics.ascent())}; + break; + case RectangleSide::Left: + break; + case RectangleSide::Bottom: + position += QPointF{0, static_cast(-fontMetrics.descent())}; + break; + case RectangleSide::Right: + position += QPointF{static_cast(-fontMetrics.horizontalAdvance(text)), 0}; + break; + } + drawBorderedText(painter, position, font, text); + }; + const QRectF box {QPointF{0, 0}, sizeToSizeF(this->renderer->size())}; + const QPointF p1 = this->renderer->modelToScreenCoordinates(glm::vec3{0, 0, 0}); + static const struct + { + QString text; + glm::vec3 direction; + } directions[] = + { + {"+x", {1, 0, 0}}, + {"-x", {-1, 0, 0}}, + {"+y", {0, 1, 0}}, + {"-y", {0, -1, 0}}, + {"+z", {0, 0, 1}}, + {"-z", {0, 0, -1}}, + }; + for (const auto& axis : directions) + { + const QPointF x_p = this->renderer->modelToScreenCoordinates(axis.direction); + const auto intersection = rayRectangleIntersection( + rayFromPoints(toVec2(p1), toVec2(x_p)), + box); + if (intersection.has_value()) + { + renderText(axis.text, *intersection); + } + } +} + void AxesLayer::paintGL() { glLineWidth(5); diff -r 5509bec02c81 -r 87ee9824210b src/gl/axesprogram.h --- a/src/gl/axesprogram.h Mon Jun 20 16:43:56 2022 +0300 +++ b/src/gl/axesprogram.h Mon Jun 20 16:59:09 2022 +0300 @@ -7,6 +7,7 @@ BasicShader shader; public: void initializeGL() override; + void overpaint(QPainter* painter) override; void paintGL() override; void mvpMatrixChanged(const glm::mat4& mvpMatrix) override; }; diff -r 5509bec02c81 -r 87ee9824210b src/gl/partrenderer.cpp --- a/src/gl/partrenderer.cpp Mon Jun 20 16:43:56 2022 +0300 +++ b/src/gl/partrenderer.cpp Mon Jun 20 16:59:09 2022 +0300 @@ -44,6 +44,9 @@ { this->setMouseTracking(true); this->setFocusPolicy(Qt::WheelFocus); + QSurfaceFormat surfaceFormat; + surfaceFormat.setSamples(8); + this->setFormat(surfaceFormat); connect(model, &Model::rowsInserted, [&]{ this->needBuild = true; }); @@ -135,6 +138,7 @@ layer->paintGL(); } QPainter painter{this}; + painter.setRenderHint(QPainter::Antialiasing); for (RenderLayer* layer : this->activeRenderLayers) { layer->overpaint(&painter); }