]> git.sur5r.net Git - fstl/blob - src/canvas.cpp
a5509c0f478a5a2163a74e0624fa384482325a97
[fstl] / src / canvas.cpp
1 #include <QMouseEvent>
2 #include <QDebug>
3
4 #include <cmath>
5
6 #include "canvas.h"
7 #include "backdrop.h"
8 #include "glmesh.h"
9 #include "mesh.h"
10
11 Canvas::Canvas(const QGLFormat& format, QWidget *parent)
12     : QGLWidget(format, parent), mesh(NULL),
13       scale(1), tilt(90), yaw(0)
14 {
15     // Nothing to do here
16 }
17
18 Canvas::~Canvas()
19 {
20     delete mesh;
21 }
22
23 void Canvas::load_mesh(Mesh* m)
24 {
25     mesh = new GLMesh(m);
26     /*
27     center = QVector3D(m->xmin() + m->xmax(),
28                        m->ymin() + m->ymax(),
29                        m->zmin() + m->zmax()) / 2;
30     scale = 2 / sqrt(
31                 pow(m->xmax() - m->xmin(), 2) +
32                 pow(m->ymax() - m->ymin(), 2) +
33                 pow(m->zmax() - m->zmin(), 2));
34     */
35     update();
36
37     delete m;
38 }
39
40 void Canvas::initializeGL()
41 {
42     mesh_shader.addShaderFromSourceFile(QGLShader::Vertex, ":/gl/mesh.vert");
43     mesh_shader.addShaderFromSourceFile(QGLShader::Fragment, ":/gl/mesh.frag");
44     mesh_shader.link();
45
46     backdrop = new Backdrop();
47
48     glClearColor(0.0, 0.0, 0.0, 0.0);
49     glEnable(GL_DEPTH_TEST);
50 }
51
52 void Canvas::paintGL()
53 {
54     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
55
56     backdrop->draw();
57     if (mesh)  draw_mesh();
58 }
59
60 void Canvas::draw_mesh()
61 {
62     mesh_shader.bind();
63
64     // Load the transform and view matrices into the shader
65     glUniformMatrix4fv(
66                 mesh_shader.uniformLocation("transform_matrix"),
67                 1, GL_FALSE, transform_matrix().data());
68     glUniformMatrix4fv(
69                 mesh_shader.uniformLocation("view_matrix"),
70                 1, GL_FALSE, view_matrix().data());
71
72     // Find and enable the attribute location for vertex position
73     const GLuint vp = mesh_shader.attributeLocation("vertex_position");
74     glEnableVertexAttribArray(vp);
75
76     // Then draw the mesh with that vertex position
77     mesh->draw(vp);
78
79     // Clean up state machine
80     glDisableVertexAttribArray(vp);
81     mesh_shader.release();
82 }
83
84 QMatrix4x4 Canvas::transform_matrix() const
85 {
86     QMatrix4x4 m;
87     m.rotate(tilt, QVector3D(1, 0, 0));
88     m.rotate(yaw,  QVector3D(0, 0, 1));
89     m.scale(scale);
90     m.translate(-center);
91     return m;
92 }
93
94 QMatrix4x4 Canvas::view_matrix() const
95 {
96     QMatrix4x4 m;
97     if (width() > height())
98     {
99         m.scale(height() / float(width()), 1, 0.5);
100     }
101     else
102     {
103         m.scale(1, width() / float(height()), 0.5);
104     }
105     return m;
106 }
107
108 void Canvas::mousePressEvent(QMouseEvent* event)
109 {
110     if (event->button() == Qt::LeftButton)
111     {
112         mouse_pos = event->pos();
113         setCursor(Qt::ClosedHandCursor);
114     }
115 }
116
117 void Canvas::mouseReleaseEvent(QMouseEvent* event)
118 {
119     if (event->button() == Qt::LeftButton)
120     {
121         unsetCursor();
122     }
123 }
124
125 void Canvas::mouseMoveEvent(QMouseEvent* event)
126 {
127     if (event->buttons() & Qt::LeftButton)
128     {
129         auto p = event->pos();
130         auto d = p - mouse_pos;
131         yaw = fmod(yaw + d.x(), 360);
132         tilt = fmax(0, fmin(180, tilt - d.y()));
133         mouse_pos = p;
134         update();
135     }
136 }