diff -r dc33f8a707c4 -r 59b6027b9843 src/layers/axeslayer.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/layers/axeslayer.cpp Sun Jun 26 21:00:06 2022 +0300
@@ -0,0 +1,162 @@
+/*
+ * LDForge: LDraw parts authoring CAD
+ * Copyright (C) 2020 Teemu Piippo
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include "gl/partrenderer.h"
+#include
+#include
+#include "axeslayer.h"
+
+static constexpr char vertexShaderSource[] = R"(
+#version 330 core
+
+layout (location = 0) in vec3 in_position;
+layout (location = 1) in vec3 in_color;
+uniform mat4 mvp;
+smooth out vec3 ex_color;
+
+void main()
+{
+ gl_Position = mvp * vec4(in_position, 1.0);
+ ex_color = in_color;
+}
+)";
+
+static constexpr char fragmentShaderSource[] = R"(
+#version 330 core
+
+out vec4 color;
+smooth in vec3 ex_color;
+
+void main(void)
+{
+ color = vec4(ex_color, 1);
+}
+)";
+
+void AxesLayer::initializeGL()
+{
+ constexpr struct VertexType
+ {
+ glm::vec3 position;
+ glm::vec3 color;
+ } data[] = {
+ {{10000, 0, 0}, {1, 0, 0}},
+ {{0, 0, 0}, {1, 0, 0}},
+ {{-10000, 0, 0}, {0.5, 0, 0}},
+ {{0, 0, 0}, {0.5, 0, 0}},
+ {{0, 10000, 0}, {0, 1, 0}},
+ {{0, 0, 0}, {0, 1, 0}},
+ {{0, -10000, 0}, {0, 0.5, 0}},
+ {{0, 0, 0}, {0, 0.5, 0}},
+ {{0, 0, 10000}, {0, 0, 1}},
+ {{0, 0, 0}, {0, 0, 1}},
+ {{0, 0, -10000}, {0, 0, 0.5}},
+ {{0, 0, 0}, {0, 0, 0.5}},
+ };
+ constexpr int stride = sizeof(VertexType);
+ this->shader.initialize(
+ ::vertexShaderSource,
+ ::fragmentShaderSource,
+ QOpenGLBuffer::StaticDraw,
+ {
+ GLAttributeSpec{
+ .type = GL_FLOAT,
+ .offset = offsetof(VertexType, position),
+ .tuplesize = 3,
+ .stride = stride,
+ },
+ {
+ .type = GL_FLOAT,
+ .offset = offsetof(VertexType, color),
+ .tuplesize = 3,
+ .stride = stride,
+ },
+ });
+ this->shader.bufferData(&data[0], countof(data), sizeof data[0]);
+}
+
+void AxesLayer::overpaint(QPainter* painter)
+{
+ painter->save();
+ 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);
+ }
+ }
+ painter->restore();
+}
+
+void AxesLayer::paintGL()
+{
+ glLineWidth(5);
+ glEnable(GL_LINE_SMOOTH);
+ glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
+ this->shader.draw(GL_LINES);
+ glDisable(GL_LINE_SMOOTH);
+}
+
+void AxesLayer::mvpMatrixChanged(const glm::mat4& mvpMatrix)
+{
+ this->shader.setMvpMatrix(mvpMatrix);
+}