mod_geo-tp/src/mesh_viewer.cpp

133 lines
2.8 KiB
C++

#include "mesh_viewer.h"
#include <tgmath.h>
#include <QOpenGLShader>
#include <QOpenGLDebugLogger>
#include <QtGlobal>
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();
}