#include "mesh_viewer.h" #include #include #include #include MeshViewer::MeshViewer(QWidget *parent) : QOpenGLWidget(parent) { setMouseTracking(true); setFocus(); } QSize MeshViewer::sizeHint() const { return QSize(640, 480); } void MeshViewer::initializeGL() { QOpenGLFunctions *glf = context()->functions(); #ifdef QT_DEBUG QOpenGLDebugLogger *logger = new QOpenGLDebugLogger(this); if (!logger->initialize()) { qDebug("OpenGL debug output unavailable"); } connect(logger, &QOpenGLDebugLogger::messageLogged, [](const QOpenGLDebugMessage &message) { qDebug() << "OpenGL: " << message.message(); }); logger->startLogging(); #endif QOpenGLShader vertex_shader(QOpenGLShader::Vertex); if (!vertex_shader.compileSourceFile(":/shader.vert")) { qCritical() << vertex_shader.log(); } QOpenGLShader fragment_shader(QOpenGLShader::Fragment); if (fragment_shader.compileSourceFile(":/shader.frag")) { qCritical() << fragment_shader.log(); } if (!program.addShader(&vertex_shader)) { qCritical() << program.log(); } if (!program.addShader(&fragment_shader)) { qCritical() << program.log(); } if (!program.link()) { qCritical() << program.log(); } program.bind(); program.setUniformValue("alpha", (GLfloat) 1); program.setUniformValue("wf_col", WIREFRAME_COLOR); glf->glClearColor(1, 1, 1, 0); glf->glEnable(GL_DEPTH_TEST); glf->glEnable(GL_MULTISAMPLE); qDebug("Mesh viewer: initialization complete"); emit initialized(); } void MeshViewer::resizeGL(int w, int h) { QMatrix4x4 projection; projection.perspective(FOV, (float) w/h, .01, 100); program.setUniformValue("proj", projection); } void MeshViewer::paintGL() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); QMatrix4x4 trans; trans.translate(0, 0, -cam_dist); QMatrix4x4 view = trans * rot; program.setUniformValue("view", view); for (MeshView &m : meshes) { m.paint(program); } } void MeshViewer::addMesh(const MyMesh &mesh) { Q_ASSERT(isValid()); makeCurrent(); meshes.emplace_back(mesh, program); doneCurrent(); update(); } void MeshViewer::removeMesh(const MyMesh &mesh) { makeCurrent(); meshes.remove_if([&](const MeshView &mv) { return &mv.mesh == &mesh; }); doneCurrent(); update(); } void MeshViewer::mousePressEvent(QMouseEvent *e) { if (e->button() == Qt::LeftButton) { mouse_pos = e->pos(); } } void MeshViewer::mouseReleaseEvent(QMouseEvent *e) { (void) e; rot_start = rot; } void MeshViewer::mouseMoveEvent(QMouseEvent *e) { if (e->buttons() & Qt::LeftButton) { QPoint delta = e->pos() - mouse_pos; rot = rot_start; rot.rotate(delta.x() / 5., 0, 1, 0); rot.rotate(delta.y() / 5., QVector3D(1, 0, 0) * rot); update(); } } void MeshViewer::wheelEvent(QWheelEvent *e) { cam_dist -= e->angleDelta().y() / 1000. * cam_dist; update(); }