#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 const QSurfaceFormat &format = context()->format(); qDebug("MeshViewer: OpenGL %s%d.%d %s", format.renderableType() == QSurfaceFormat::OpenGLES ? "ES " : "", format.majorVersion(), format.minorVersion(), format.profile() == QSurfaceFormat::CoreProfile ? "core profile" : (format.profile() == QSurfaceFormat::CompatibilityProfile ? "compatibility profile" : "")); 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 if (!program.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shader.vert")) { qFatal("%s", program.log().toUtf8().constData()); } if (!program.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shader.frag")) { qFatal("%s", program.log().toUtf8().constData()); } if (!program.link()) { qFatal("%s", program.log().toUtf8().constData()); } 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("MeshViewer: 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.bind(); program.setUniformValue("view", view); for (MeshView &m : meshes) { m.paint(program); } } void MeshViewer::addMesh(const MeshProcessor &mesh_processor) { Q_ASSERT(isValid()); makeCurrent(); meshes.emplace_back(mesh_processor, program); doneCurrent(); update(); } void MeshViewer::removeMesh(const MeshProcessor &mesh_processor) { makeCurrent(); meshes.remove_if([&](const MeshView &mv) { return &mv.mesh_processor == &mesh_processor; }); 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(); }