X-Git-Url: https://git.sur5r.net/?p=fstl;a=blobdiff_plain;f=src%2Fcanvas.cpp;h=4da41a7e0cc17c8e049182fdb2c287205c2a7c9d;hp=dd188fffb7e26a82a9841d4437926fe0c134ff23;hb=dd4a156f8787b310568d82161bddd478b0938499;hpb=0da9fdf2b9623665a991990e57485a007645eba6 diff --git a/src/canvas.cpp b/src/canvas.cpp index dd188ff..4da41a7 100644 --- a/src/canvas.cpp +++ b/src/canvas.cpp @@ -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.