]> git.sur5r.net Git - fstl/blobdiff - src/canvas.cpp
New upstream version 0.10.0
[fstl] / src / canvas.cpp
index dd188fffb7e26a82a9841d4437926fe0c134ff23..4da41a7e0cc17c8e049182fdb2c287205c2a7c9d 100644 (file)
@@ -4,15 +4,20 @@
 
 #include "canvas.h"
 #include "backdrop.h"
+#include "axis.h"
 #include "glmesh.h"
 #include "mesh.h"
 
+const float Canvas::P_PERSPECTIVE = 0.25f;
+const float Canvas::P_ORTHOGRAPHIC = 0.0f;
+
 Canvas::Canvas(const QSurfaceFormat& format, QWidget *parent)
     : QOpenGLWidget(parent), mesh(nullptr),
       scale(1), zoom(1), tilt(90), yaw(0),
-      perspective(0.25), anim(this, "perspective"), status(" ")
+      anim(this, "perspective"), status(" "),
+      meshInfo("")
 {
-       setFormat(format);
+    setFormat(format);
     QFile styleFile(":/qt/style.qss");
     styleFile.open( QFile::ReadOnly );
     setStyleSheet(styleFile.readAll());
@@ -22,9 +27,12 @@ Canvas::Canvas(const QSurfaceFormat& format, QWidget *parent)
 
 Canvas::~Canvas()
 {
-       makeCurrent();
-       delete mesh;
-       doneCurrent();
+    makeCurrent();
+    delete mesh;
+    delete mesh_vertshader;
+    delete backdrop;
+    delete axis;
+    doneCurrent();
 }
 
 void Canvas::view_anim(float v)
@@ -34,34 +42,37 @@ void Canvas::view_anim(float v)
     anim.start();
 }
 
-void Canvas::view_orthographic()
-{
-    view_anim(0);
-}
-
-void Canvas::view_perspective()
-{
-    view_anim(0.25);
+void Canvas::view_perspective(float p, bool animate){
+    if(animate)
+    {
+        view_anim(p);
+    }
+    else
+    {
+        set_perspective(p);
+    }
 }
 
-void Canvas::draw_shaded()
+void Canvas::draw_axes(bool d)
 {
-    set_drawMode(0);
+    drawAxes = d;
+    update();
 }
 
-void Canvas::draw_wireframe()
+void Canvas::invert_zoom(bool d)
 {
-    set_drawMode(1);
+    invertZoom = d;
+    update();
 }
 
 void Canvas::load_mesh(Mesh* m, bool is_reload)
 {
+    delete mesh;
     mesh = new GLMesh(m);
-
+    QVector3D lower(m->xmin(), m->ymin(), m->zmin());
+    QVector3D upper(m->xmax(), m->ymax(), m->zmax());
     if (!is_reload)
     {
-        QVector3D lower(m->xmin(), m->ymin(), m->zmin());
-        QVector3D upper(m->xmax(), m->ymax(), m->zmax());
         center = (lower + upper) / 2;
         scale = 2 / (upper - lower).length();
 
@@ -70,7 +81,9 @@ void Canvas::load_mesh(Mesh* m, bool is_reload)
         yaw = 0;
         tilt = 90;
     }
-
+    meshInfo = QStringLiteral("Triangles: %1\nX: [%2, %3]\nY: [%4, %5]\nZ: [%6, %7]").arg(m->triCount());
+    for(int dIdx = 0; dIdx < 3; dIdx++) meshInfo = meshInfo.arg(lower[dIdx]).arg(upper[dIdx]);
+    axis->setScale(lower, upper);
     update();
 
     delete m;
@@ -88,7 +101,7 @@ void Canvas::set_perspective(float p)
     update();
 }
 
-void Canvas::set_drawMode(int mode)
+void Canvas::set_drawMode(enum DrawMode mode)
 {
     drawMode = mode;
     update();
@@ -104,45 +117,58 @@ void Canvas::initializeGL()
 {
     initializeOpenGLFunctions();
 
-    mesh_shader.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/gl/mesh.vert");
+    mesh_vertshader = new QOpenGLShader(QOpenGLShader::Vertex);
+    mesh_vertshader->compileSourceFile(":/gl/mesh.vert");
+    mesh_shader.addShader(mesh_vertshader);
     mesh_shader.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/gl/mesh.frag");
     mesh_shader.link();
-    mesh_wireframe_shader.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/gl/mesh.vert");
+    mesh_wireframe_shader.addShader(mesh_vertshader);
     mesh_wireframe_shader.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/gl/mesh_wireframe.frag");
     mesh_wireframe_shader.link();
+    mesh_surfaceangle_shader.addShader(mesh_vertshader);
+    mesh_surfaceangle_shader.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/gl/mesh_surfaceangle.frag");
+    mesh_surfaceangle_shader.link();
 
     backdrop = new Backdrop();
+    axis = new Axis();
 }
 
 
 void Canvas::paintGL()
 {
-       glClearColor(0.0, 0.0, 0.0, 0.0);
-       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-       glEnable(GL_DEPTH_TEST);
-
-       backdrop->draw();
-       if (mesh)  draw_mesh();
-
-       if (status.isNull())  return;
-
-       QPainter painter(this);
-       painter.setRenderHint(QPainter::Antialiasing);
-       painter.drawText(10, height() - 10, status);
+    glClearColor(0.0, 0.0, 0.0, 0.0);
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+    glEnable(GL_DEPTH_TEST);
+    backdrop->draw();
+    if (mesh)  draw_mesh();
+    if (drawAxes) axis->draw(transform_matrix(), view_matrix(),
+        orient_matrix(), aspect_matrix(), width() / float(height()));
+
+    QPainter painter(this);
+    painter.setRenderHint(QPainter::Antialiasing);
+    float textHeight = painter.fontInfo().pointSize();
+    if (drawAxes) painter.drawText(QRect(10, textHeight, width(), height()), meshInfo);
+    painter.drawText(10, height() - textHeight, status);
 }
 
 void Canvas::draw_mesh()
 {
     QOpenGLShaderProgram* selected_mesh_shader = NULL;
-    // Set gl draw mode
-    if(drawMode == 1)
+    if(drawMode == wireframe)
     {
         selected_mesh_shader = &mesh_wireframe_shader;
         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
     }
     else
     {
-        selected_mesh_shader = &mesh_shader;
+        if(drawMode == shaded)
+        {
+            selected_mesh_shader = &mesh_shader;
+        }
+        else
+        {
+            selected_mesh_shader = &mesh_surfaceangle_shader;
+        }
         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
     }
 
@@ -173,18 +199,23 @@ void Canvas::draw_mesh()
     glDisableVertexAttribArray(vp);
     selected_mesh_shader->release();
 }
-
-QMatrix4x4 Canvas::transform_matrix() const
+QMatrix4x4 Canvas::orient_matrix() const
 {
     QMatrix4x4 m;
     m.rotate(tilt, QVector3D(1, 0, 0));
     m.rotate(yaw,  QVector3D(0, 0, 1));
-    m.scale(-scale, scale, -scale);
+    //We want the x axis to the right, and the z axis up
+    m.scale(-1, 1, -1);
+    return m;
+}
+QMatrix4x4 Canvas::transform_matrix() const
+{
+    QMatrix4x4 m = orient_matrix();
+    m.scale(scale);
     m.translate(-center);
     return m;
 }
-
-QMatrix4x4 Canvas::view_matrix() const
+QMatrix4x4 Canvas::aspect_matrix() const
 {
     QMatrix4x4 m;
     if (width() > height())
@@ -195,6 +226,11 @@ QMatrix4x4 Canvas::view_matrix() const
     {
         m.scale(-1, width() / float(height()), 0.5);
     }
+    return m;
+}
+QMatrix4x4 Canvas::view_matrix() const
+{
+    QMatrix4x4 m = aspect_matrix();
     m.scale(zoom, zoom, 1);
     m(3, 2) = perspective;
     return m;
@@ -246,21 +282,27 @@ void Canvas::wheelEvent(QWheelEvent *event)
 {
     // Find GL position before the zoom operation
     // (to zoom about mouse cursor)
-    auto p = event->pos();
+    auto p = event->position();
     QVector3D v(1 - p.x() / (0.5*width()),
                 p.y() / (0.5*height()) - 1, 0);
     QVector3D a = transform_matrix().inverted() *
                   view_matrix().inverted() * v;
 
-    if (event->delta() < 0)
+    if (event->angleDelta().y() < 0)
     {
-        for (int i=0; i > event->delta(); --i)
-            zoom *= 1.001;
+        for (int i=0; i > event->angleDelta().y(); --i)
+            if (invertZoom)
+                zoom /= 1.001;
+            else 
+                zoom *= 1.001;
     }
-    else if (event->delta() > 0)
+    else if (event->angleDelta().y() > 0)
     {
-        for (int i=0; i < event->delta(); ++i)
-            zoom /= 1.001;
+        for (int i=0; i < event->angleDelta().y(); ++i)
+            if (invertZoom) 
+                zoom *= 1.001;
+            else 
+                zoom /= 1.001;
     }
 
     // Then find the cursor's GL position post-zoom and adjust center.