70 } |
70 } |
71 |
71 |
72 void PartRenderer::resizeGL(int width, int height) |
72 void PartRenderer::resizeGL(int width, int height) |
73 { |
73 { |
74 glViewport(0, 0, width, height); |
74 glViewport(0, 0, width, height); |
75 this->viewportMatrix = { |
|
76 {1, 0, 0}, |
|
77 {0, 1, 0}, |
|
78 {width * 0.5f, height * 0.5f, 1} |
|
79 }; |
|
80 this->projectionMatrix = glm::perspective( |
75 this->projectionMatrix = glm::perspective( |
81 glm::radians(45.0f), |
76 glm::radians(45.0f), |
82 static_cast<float>(width) / static_cast<float>(height), |
77 static_cast<float>(width) / static_cast<float>(height), |
83 0.1f, |
78 0.1f, |
84 10000.f); |
79 10000.f); |
99 return GL_QUADS; |
94 return GL_QUADS; |
100 } |
95 } |
101 throw std::runtime_error{"Bad vbo class passed to getGlTypeForVboClass"}; |
96 throw std::runtime_error{"Bad vbo class passed to getGlTypeForVboClass"}; |
102 } |
97 } |
103 |
98 |
|
99 #include <QPainter> |
104 void PartRenderer::paintGL() |
100 void PartRenderer::paintGL() |
105 { |
101 { |
106 glEnable(GL_DEPTH_TEST); |
102 glEnable(GL_DEPTH_TEST); |
107 glShadeModel(GL_SMOOTH); |
103 glShadeModel(GL_SMOOTH); |
108 this->renderScene(); |
104 this->renderScene(); |
|
105 QPainter painter{this}; |
|
106 painter.setPen(Qt::white); |
|
107 painter.setBrush(Qt::red); |
|
108 for (float x : {1, -1}) |
|
109 { |
|
110 for (float y : {1, -1}) |
|
111 { |
|
112 for (float z : {1, -1}) |
|
113 { |
|
114 painter.drawEllipse(this->modelToScreenCoordinates({x, y, z}), 10, 10); |
|
115 } |
|
116 } |
|
117 } |
109 } |
118 } |
110 |
119 |
111 void PartRenderer::renderScene() |
120 void PartRenderer::renderScene() |
112 { |
121 { |
113 this->checkForGLErrors(); |
122 this->checkForGLErrors(); |
283 this->zoom = std::clamp(this->zoom + move, MIN_ZOOM, MAX_ZOOM); |
292 this->zoom = std::clamp(this->zoom + move, MIN_ZOOM, MAX_ZOOM); |
284 this->updateViewMatrix(); |
293 this->updateViewMatrix(); |
285 this->update(); |
294 this->update(); |
286 } |
295 } |
287 |
296 |
288 std::optional<glm::vec3> PartRenderer::cameraToGrid(const QPoint& point) |
297 glm::vec3 PartRenderer::viewport(const glm::vec3& point) |
|
298 { |
|
299 return viewport(point, this->width(), this->height()); |
|
300 } |
|
301 |
|
302 std::optional<glm::vec3> PartRenderer::screenToModelCoordinates(const QPoint& point) |
289 { |
303 { |
290 glm::vec3 pp = {point.x(), this->height() - point.y(), 1}; |
304 glm::vec3 pp = {point.x(), this->height() - point.y(), 1}; |
291 pp = glm::inverse(this->viewportMatrix) * pp; |
|
292 glm::mat4 matrix; |
305 glm::mat4 matrix; |
293 matrix = this->projectionMatrix * this->viewMatrix * glm::mat4_cast(this->modelQuaternion); |
306 matrix = this->projectionMatrix * this->viewMatrix * glm::mat4_cast(this->modelQuaternion); |
294 matrix = glm::transpose(glm::inverse(matrix)); |
307 matrix = glm::transpose(glm::inverse(matrix)); |
295 auto p1 = matrix * glm::vec4{pp.x, pp.y, 0, 1}; |
308 auto p1 = matrix * glm::vec4{pp.x, pp.y, 0, 1}; |
296 auto p2 = matrix * glm::vec4{pp.x, pp.y, 1, 1}; |
309 auto p2 = matrix * glm::vec4{pp.x, pp.y, 1, 1}; |
297 geom::Line line = geom::lineFromPoints(p1, p2); |
310 geom::Line line = geom::lineFromPoints(p1, p2); |
298 return geom::linePlaneIntersection(line, geom::XY); |
311 return geom::linePlaneIntersection(line, geom::XY); |
299 } |
312 } |
300 |
313 |
301 QPointF PartRenderer::worldToCamera(const glm::vec3& point) |
314 QPointF PartRenderer::modelToScreenCoordinates(const glm::vec3& point) |
302 { |
315 { |
303 glm::vec4 p = {point, 1}; |
316 glm::vec4 p = {point, 1}; |
304 p = glm::mat4_cast(this->modelQuaternion) * p; |
317 p = glm::mat4_cast(this->modelQuaternion) * p; |
305 p = this->viewMatrix * p; |
318 p = this->viewMatrix * p; |
306 p = this->projectionMatrix * p; |
319 p = this->projectionMatrix * p; |
307 glm::vec2 pp = this->viewportMatrix * glm::vec3{p.x, p.y, 1}; |
320 glm::vec2 pp = this->viewport({p.x / p.w, p.y / p.w, 1}); |
308 return toQPointF(pp); |
321 return toQPointF(pp); |
309 /* |
|
310 const glm::mat4 matrix = this->projectionMatrix * this->viewMatrix * glm::mat4_cast(this->modelQuaternion); |
|
311 return toQPointF(matrix * glm::vec4{point, 1}); |
|
312 */ |
|
313 } |
322 } |
314 |
323 |
315 ldraw::Id PartRenderer::pick(const QPoint& where) |
324 ldraw::Id PartRenderer::pick(const QPoint& where) |
316 { |
325 { |
317 const gl::RenderStyle oldRenderStyle = this->renderPreferences.style; |
326 const gl::RenderStyle oldRenderStyle = this->renderPreferences.style; |
347 this->renderPreferences = newPreferences; |
356 this->renderPreferences = newPreferences; |
348 if (mainColorChanged or backgroundColorChanged) |
357 if (mainColorChanged or backgroundColorChanged) |
349 { |
358 { |
350 this->compiler->build(this->model, this->documents, this->renderPreferences); |
359 this->compiler->build(this->model, this->documents, this->renderPreferences); |
351 this->setupBackgroundColor(); |
360 this->setupBackgroundColor(); |
352 |
361 } |
353 } |
362 this->update(); |
354 this->update(); |
363 } |
355 } |
364 |
|
365 glm::vec3 PartRenderer::viewport(const glm::vec3& point, float width, float height) |
|
366 { |
|
367 return { |
|
368 width * 0.5 * (point.x + 1), |
|
369 height * 0.5 * (-point.y + 1), |
|
370 0 |
|
371 }; |
|
372 } |