152 } |
152 } |
153 |
153 |
154 void Canvas::paintGL() |
154 void Canvas::paintGL() |
155 { |
155 { |
156 PartRenderer::paintGL(); |
156 PartRenderer::paintGL(); |
157 // Render axes |
157 if (this->renderPreferences.style != gl::RenderStyle::PickScene) |
158 { |
158 { |
159 glLineWidth(5); |
159 // Render axes |
160 glEnable(GL_LINE_SMOOTH); |
160 { |
161 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); |
161 glLineWidth(5); |
162 this->axesProgram->draw(); |
162 glEnable(GL_LINE_SMOOTH); |
163 glDisable(GL_LINE_SMOOTH); |
163 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); |
164 } |
164 this->axesProgram->draw(); |
165 // Render grid |
165 glDisable(GL_LINE_SMOOTH); |
166 { |
166 } |
167 glEnable(GL_BLEND); |
167 // Render grid |
168 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
168 { |
169 this->gridProgram->draw(); |
169 glEnable(GL_BLEND); |
170 glDisable(GL_BLEND); |
170 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
171 } |
171 this->gridProgram->draw(); |
172 if (this->worldPosition.has_value()) |
172 glDisable(GL_BLEND); |
173 { |
173 } |
174 QPainter painter{this}; |
174 if (this->worldPosition.has_value()) |
175 painter.setRenderHint(QPainter::Antialiasing); |
175 { |
176 painter.setPen(Qt::black); |
176 QPainter painter{this}; |
177 painter.setBrush(Qt::green); |
177 painter.setRenderHint(QPainter::Antialiasing); |
178 const QPointF pos = this->modelToScreenCoordinates(*this->worldPosition); |
178 painter.setPen(Qt::black); |
179 painter.drawEllipse(pos, 5, 5); |
179 painter.setBrush(Qt::green); |
180 painter.setPen(Qt::white); |
180 const QPointF pos = this->modelToScreenCoordinates(*this->worldPosition); |
181 painter.drawText(pos + QPointF{5, 5}, vectorToString(*this->worldPosition)); |
181 painter.drawEllipse(pos, 5, 5); |
182 } |
182 painter.setPen(Qt::white); |
183 { |
183 painter.drawText(pos + QPointF{5, 5}, vectorToString(*this->worldPosition)); |
184 QPainter painter{this}; |
184 } |
185 QFont font; |
185 { |
186 //font.setStyle(QFont::StyleItalic); |
186 QPainter painter{this}; |
187 painter.setFont(font); |
187 QFont font; |
188 QFontMetrics fontMetrics{font}; |
188 //font.setStyle(QFont::StyleItalic); |
189 const auto renderText = [&](const QString& text, const geom::PointOnRectagle& intersection) |
189 painter.setFont(font); |
190 { |
190 QFontMetrics fontMetrics{font}; |
191 QPointF position = toQPointF(intersection.position); |
191 const auto renderText = [&](const QString& text, const geom::PointOnRectagle& intersection) |
192 const geom::RectangleSide side = intersection.side; |
192 { |
193 switch (side) |
193 QPointF position = toQPointF(intersection.position); |
194 { |
194 const geom::RectangleSide side = intersection.side; |
195 case geom::RectangleSide::Top: |
195 switch (side) |
196 position += QPointF{0, static_cast<qreal>(fontMetrics.ascent())}; |
196 { |
197 break; |
197 case geom::RectangleSide::Top: |
198 case geom::RectangleSide::Left: |
198 position += QPointF{0, static_cast<qreal>(fontMetrics.ascent())}; |
199 break; |
199 break; |
200 case geom::RectangleSide::Bottom: |
200 case geom::RectangleSide::Left: |
201 position += QPointF{0, static_cast<qreal>(-fontMetrics.descent())}; |
201 break; |
202 break; |
202 case geom::RectangleSide::Bottom: |
203 case geom::RectangleSide::Right: |
203 position += QPointF{0, static_cast<qreal>(-fontMetrics.descent())}; |
204 position += QPointF{static_cast<qreal>(-fontMetrics.width(text)), 0}; |
204 break; |
205 break; |
205 case geom::RectangleSide::Right: |
206 } |
206 position += QPointF{static_cast<qreal>(-fontMetrics.width(text)), 0}; |
207 painter.drawText(position, text); |
207 break; |
208 }; |
208 } |
209 const QRectF box { |
209 painter.drawText(position, text); |
210 QPointF{0, 0}, |
210 }; |
211 QPointF{static_cast<qreal>(this->width()), static_cast<qreal>(this->height())} |
211 const QRectF box { |
212 }; |
212 QPointF{0, 0}, |
213 const QPointF p1 = this->modelToScreenCoordinates(glm::vec3{0, 0, 0}); |
213 QPointF{static_cast<qreal>(this->width()), static_cast<qreal>(this->height())} |
214 |
214 }; |
215 static const struct |
215 const QPointF p1 = this->modelToScreenCoordinates(glm::vec3{0, 0, 0}); |
216 { |
216 |
217 QString text; |
217 static const struct |
218 glm::vec3 direction; |
218 { |
219 } directions[] = |
219 QString text; |
220 { |
220 glm::vec3 direction; |
221 {"+𝑥", {1, 0, 0}}, |
221 } directions[] = |
222 {"-𝑥", {-1, 0, 0}}, |
222 { |
223 {"+𝑦", {0, 1, 0}}, |
223 {"+𝑥", {1, 0, 0}}, |
224 {"-𝑦", {0, -1, 0}}, |
224 {"-𝑥", {-1, 0, 0}}, |
225 {"+𝑧", {0, 0, 1}}, |
225 {"+𝑦", {0, 1, 0}}, |
226 {"-𝑧", {0, 0, -1}}, |
226 {"-𝑦", {0, -1, 0}}, |
227 }; |
227 {"+𝑧", {0, 0, 1}}, |
228 for (const auto& axis : directions) |
228 {"-𝑧", {0, 0, -1}}, |
229 { |
229 }; |
230 const QPointF x_p = this->modelToScreenCoordinates(axis.direction); |
230 for (const auto& axis : directions) |
231 const auto intersection = geom::rayRectangleIntersection(geom::rayFromPoints(toVec2(p1), toVec2(x_p)), box); |
231 { |
232 if (intersection.has_value()) |
232 const QPointF x_p = this->modelToScreenCoordinates(axis.direction); |
233 { |
233 const auto intersection = geom::rayRectangleIntersection(geom::rayFromPoints(toVec2(p1), toVec2(x_p)), box); |
234 renderText(axis.text, *intersection); |
234 if (intersection.has_value()) |
|
235 { |
|
236 renderText(axis.text, *intersection); |
|
237 } |
235 } |
238 } |
236 } |
239 } |
237 } |
240 } |
238 } |
241 } |
239 |
242 |