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