2021-10-02 20:47:02 +02:00
|
|
|
#include "mesh_view.h"
|
2021-10-03 11:43:55 +02:00
|
|
|
#include "util.h"
|
2021-10-02 22:51:20 +02:00
|
|
|
#include <QOpenGLContext>
|
2021-10-03 00:11:29 +02:00
|
|
|
#include <QOpenGLFunctions_2_1>
|
2021-10-02 20:47:02 +02:00
|
|
|
|
|
|
|
|
2021-10-03 11:43:55 +02:00
|
|
|
MeshView::MeshView(const MeshProcessor &mesh_processor, QOpenGLShaderProgram &program)
|
|
|
|
:vertex_buffer(QOpenGLBuffer::VertexBuffer),
|
|
|
|
index_buffer(QOpenGLBuffer::IndexBuffer),
|
|
|
|
n_faces(mesh_processor.mesh.n_faces()),
|
|
|
|
n_vertices(mesh_processor.mesh.n_vertices()),
|
|
|
|
mesh_processor(mesh_processor) {
|
|
|
|
const MyMesh &mesh = mesh_processor.mesh;
|
2021-10-03 11:48:28 +02:00
|
|
|
QVector<GLfloat> vertices(n_vertices * 3);
|
2021-10-02 20:47:02 +02:00
|
|
|
size_t i = 0;
|
2021-10-03 11:43:55 +02:00
|
|
|
for (const VertexHandle it : mesh.vertices()) {
|
2021-10-03 11:48:28 +02:00
|
|
|
vertices[3*i + 0] = mesh.point(it)[0];
|
|
|
|
vertices[3*i + 1] = mesh.point(it)[1];
|
|
|
|
vertices[3*i + 2] = mesh.point(it)[2];
|
2021-10-03 11:43:55 +02:00
|
|
|
i++;
|
|
|
|
}
|
|
|
|
QVector<GLuint> indices(n_faces * 3);
|
|
|
|
i = 0;
|
|
|
|
for (const FaceHandle it : mesh.faces()) {
|
|
|
|
MyMesh::ConstFaceVertexIter it2 = mesh.cfv_begin(it);
|
|
|
|
indices[3 * i + 0] = it2->idx();
|
|
|
|
++it2;
|
|
|
|
indices[3 * i + 1] = it2->idx();
|
|
|
|
++it2;
|
|
|
|
indices[3 * i + 2] = it2->idx();
|
|
|
|
i++;
|
|
|
|
}
|
2021-10-02 20:47:02 +02:00
|
|
|
|
2021-10-02 22:51:20 +02:00
|
|
|
vao.create();
|
|
|
|
{QOpenGLVertexArrayObject::Binder binder(&vao);
|
2021-10-03 11:43:55 +02:00
|
|
|
vertex_buffer.create();
|
|
|
|
vertex_buffer.bind();
|
|
|
|
vertex_buffer.setUsagePattern(QOpenGLBuffer::StreamDraw);
|
2021-10-03 11:48:28 +02:00
|
|
|
vertex_buffer.allocate(vertices.constData(), n_vertices * 3 * sizeof (GLfloat));
|
2021-10-03 11:43:55 +02:00
|
|
|
index_buffer.create();
|
|
|
|
index_buffer.bind();
|
|
|
|
index_buffer.setUsagePattern(QOpenGLBuffer::StreamDraw);
|
|
|
|
index_buffer.allocate(indices.constData(), n_faces * 3 * sizeof (GLuint));
|
2021-10-03 11:48:28 +02:00
|
|
|
program.setAttributeBuffer("pos", GL_FLOAT, 0, 3);
|
2021-10-02 22:51:20 +02:00
|
|
|
program.enableAttributeArray("pos");
|
|
|
|
}
|
2021-10-02 20:47:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
MeshView::~MeshView() {
|
2021-10-03 11:43:55 +02:00
|
|
|
vertex_buffer.destroy();
|
|
|
|
index_buffer.destroy();
|
2021-10-02 22:51:20 +02:00
|
|
|
vao.destroy();
|
2021-10-02 20:47:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-10-02 22:51:20 +02:00
|
|
|
void MeshView::paint(QOpenGLShaderProgram &program) {
|
2021-10-03 11:43:55 +02:00
|
|
|
const MyMesh &mesh = mesh_processor.mesh;
|
2021-10-02 22:51:20 +02:00
|
|
|
QOpenGLContext *ctx = QOpenGLContext::currentContext();
|
|
|
|
QOpenGLExtraFunctions *glf = ctx->extraFunctions();
|
2021-10-03 00:11:29 +02:00
|
|
|
|
|
|
|
QOpenGLFunctions_2_1 *glf21 = nullptr;
|
|
|
|
glf21 = ctx->versionFunctions<QOpenGLFunctions_2_1>();
|
|
|
|
if (!glf21)
|
|
|
|
qFatal("Failed to get OpenGL 2.1 functions");
|
2021-10-02 20:47:02 +02:00
|
|
|
|
2021-10-02 22:51:20 +02:00
|
|
|
program.setUniformValue("model", mesh.transform);
|
2021-10-03 11:48:28 +02:00
|
|
|
program.setUniformValue("col", mesh.color.redF(), mesh.color.greenF(), mesh.color.blueF());
|
2021-10-02 20:47:02 +02:00
|
|
|
|
2021-10-02 22:51:20 +02:00
|
|
|
{QOpenGLVertexArrayObject::Binder binder(&vao);
|
|
|
|
/* Mesh */
|
|
|
|
glf->glEnable(GL_POLYGON_OFFSET_FILL);
|
|
|
|
glf->glPolygonOffset(1.0, 2);
|
2021-10-03 11:43:55 +02:00
|
|
|
glf->glDrawElements(GL_TRIANGLES, n_faces * 3, GL_UNSIGNED_INT, 0);
|
2021-10-02 22:51:20 +02:00
|
|
|
glf->glDisable(GL_POLYGON_OFFSET_FILL);
|
2021-10-02 20:47:02 +02:00
|
|
|
|
2021-10-02 22:51:20 +02:00
|
|
|
/* Wireframe */
|
2021-10-03 11:43:55 +02:00
|
|
|
glf21->glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
|
|
|
glf->glLineWidth(2);
|
2021-10-02 22:51:20 +02:00
|
|
|
program.setUniformValue("wireframe", 1);
|
2021-10-03 11:43:55 +02:00
|
|
|
glf->glDrawElements(GL_TRIANGLES, n_faces * 3, GL_UNSIGNED_INT, 0);
|
2021-10-03 00:11:29 +02:00
|
|
|
glf21->glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
|
|
|
program.setUniformValue("wireframe", 0);
|
2021-10-03 11:43:55 +02:00
|
|
|
|
|
|
|
// program.setUniformValue("wf_col", QVector3D(1, 0, 1));
|
|
|
|
// for (HalfedgeHandle hole : mesh_processor.holes) {
|
|
|
|
// for (HalfedgeHandle it : ConstHalfedgeLoopRange(mesh, hole)) {
|
|
|
|
// int v0 = mesh.from_vertex_handle(it).idx();
|
|
|
|
// int v1 = mesh.to_vertex_handle(it).idx();
|
|
|
|
// glf->glDrawArrays(GL_LINES, std::min(v0, v1), std::max(v0, v1));
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// program.setUniformValue("wf_col", QVector3D(0, 0, 0));
|
2021-10-02 22:51:20 +02:00
|
|
|
}
|
2021-10-02 20:47:02 +02:00
|
|
|
}
|