src/gl/axesprogram.cpp

changeset 234
87ee9824210b
parent 216
c7241f504117
child 245
a41ccc6924e3
equal deleted inserted replaced
233:5509bec02c81 234:87ee9824210b
14 * 14 *
15 * You should have received a copy of the GNU General Public License 15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */ 17 */
18 18
19 #include <QPainter>
20 #include <QPainterPath>
19 #include "axesprogram.h" 21 #include "axesprogram.h"
22 #include "gl/partrenderer.h"
20 23
21 static constexpr char vertexShaderSource[] = R"( 24 static constexpr char vertexShaderSource[] = R"(
22 #version 330 core 25 #version 330 core
23 26
24 layout (location = 0) in vec3 in_position; 27 layout (location = 0) in vec3 in_position;
85 }, 88 },
86 }); 89 });
87 this->shader.bufferData(&data[0], countof(data), sizeof data[0]); 90 this->shader.bufferData(&data[0], countof(data), sizeof data[0]);
88 } 91 }
89 92
93 void drawBorderedText(QPainter* painter, const QPointF& point, const QFont& font, const QString& text)
94 {
95 QPainterPath path;
96 path.addText(point, font, text);
97 painter->save();
98 painter->setBrush(Qt::white);
99 painter->setPen({Qt::black, 0.1 * font.pointSizeF()});
100 painter->drawPath(path);
101 painter->restore();
102 }
103
104 void AxesLayer::overpaint(QPainter* painter)
105 {
106 QFont font;
107 font.setStyle(QFont::StyleItalic);
108 font.setBold(true);
109 painter->setFont(font);
110 QFontMetrics fontMetrics{font};
111 const auto renderText = [&](const QString& text, const PointOnRectagle& intersection)
112 {
113 QPointF position = toQPointF(intersection.position);
114 const RectangleSide side = intersection.side;
115 switch (side)
116 {
117 case RectangleSide::Top:
118 position += QPointF{0, static_cast<qreal>(fontMetrics.ascent())};
119 break;
120 case RectangleSide::Left:
121 break;
122 case RectangleSide::Bottom:
123 position += QPointF{0, static_cast<qreal>(-fontMetrics.descent())};
124 break;
125 case RectangleSide::Right:
126 position += QPointF{static_cast<qreal>(-fontMetrics.horizontalAdvance(text)), 0};
127 break;
128 }
129 drawBorderedText(painter, position, font, text);
130 };
131 const QRectF box {QPointF{0, 0}, sizeToSizeF(this->renderer->size())};
132 const QPointF p1 = this->renderer->modelToScreenCoordinates(glm::vec3{0, 0, 0});
133 static const struct
134 {
135 QString text;
136 glm::vec3 direction;
137 } directions[] =
138 {
139 {"+x", {1, 0, 0}},
140 {"-x", {-1, 0, 0}},
141 {"+y", {0, 1, 0}},
142 {"-y", {0, -1, 0}},
143 {"+z", {0, 0, 1}},
144 {"-z", {0, 0, -1}},
145 };
146 for (const auto& axis : directions)
147 {
148 const QPointF x_p = this->renderer->modelToScreenCoordinates(axis.direction);
149 const auto intersection = rayRectangleIntersection(
150 rayFromPoints(toVec2(p1), toVec2(x_p)),
151 box);
152 if (intersection.has_value())
153 {
154 renderText(axis.text, *intersection);
155 }
156 }
157 }
158
90 void AxesLayer::paintGL() 159 void AxesLayer::paintGL()
91 { 160 {
92 glLineWidth(5); 161 glLineWidth(5);
93 glEnable(GL_LINE_SMOOTH); 162 glEnable(GL_LINE_SMOOTH);
94 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); 163 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);

mercurial