#include "mesh_view.h" #include "util.h" #include #include MeshView::MeshView(const MyMesh &mesh, QOpenGLShaderProgram &program) :vertex_buffer(QOpenGLBuffer::VertexBuffer), index_buffer(QOpenGLBuffer::IndexBuffer), holes_index_buffer(QOpenGLBuffer::IndexBuffer), n_faces(mesh.n_faces()), n_vertices(mesh.n_vertices()), mesh(mesh) { QVector vertices(n_vertices * 6); size_t i = 0; for (const VertexHandle it : mesh.vertices()) { vertices[6*i + 0] = mesh.point(it)[0]; vertices[6*i + 1] = mesh.point(it)[1]; vertices[6*i + 2] = mesh.point(it)[2]; vertices[6*i + 3] = mesh.color(it)[0]; vertices[6*i + 4] = mesh.color(it)[1]; vertices[6*i + 5] = mesh.color(it)[2]; i++; } QVector 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++; } QVector holes_indices; n_boundary_halfedges = 0; for (std::vector hole : mesh.holes) { for (HalfedgeHandle it : hole) { holes_indices.push_back(mesh.from_vertex_handle(it).idx()); holes_indices.push_back(mesh.to_vertex_handle(it).idx()); n_boundary_halfedges++; } } vao.create(); {QOpenGLVertexArrayObject::Binder binder(&vao); vertex_buffer.create(); vertex_buffer.bind(); vertex_buffer.setUsagePattern(QOpenGLBuffer::DynamicDraw); vertex_buffer.allocate(vertices.constData(), n_vertices * 6 * sizeof (GLfloat)); index_buffer.create(); index_buffer.bind(); index_buffer.setUsagePattern(QOpenGLBuffer::DynamicDraw); index_buffer.allocate(indices.constData(), n_faces * 3 * sizeof (GLuint)); holes_index_buffer.create(); holes_index_buffer.bind(); holes_index_buffer.setUsagePattern(QOpenGLBuffer::DynamicDraw); holes_index_buffer.allocate(holes_indices.constData(), n_boundary_halfedges * 2 * sizeof (GLuint)); vertex_buffer.bind(); program.setAttributeBuffer("pos", GL_FLOAT, 0, 3, 6 * sizeof (GLfloat)); program.enableAttributeArray("pos"); program.setAttributeBuffer("col", GL_FLOAT, 3 * sizeof (GLfloat), 3, 6 * sizeof (GLfloat)); program.enableAttributeArray("col"); } } MeshView::~MeshView() { vertex_buffer.destroy(); index_buffer.destroy(); vao.destroy(); } void MeshView::paint(QOpenGLShaderProgram &program) { QOpenGLContext *ctx = QOpenGLContext::currentContext(); QOpenGLExtraFunctions *glf = ctx->extraFunctions(); QOpenGLFunctions_2_1 *glf21 = nullptr; glf21 = ctx->versionFunctions(); if (!glf21) qFatal("Failed to get OpenGL 2.1 functions"); program.setUniformValue("model", mesh.transform); // program.setUniformValue("col", mesh.color.redF(), mesh.color.greenF(), mesh.color.blueF()); {QOpenGLVertexArrayObject::Binder binder(&vao); /* Mesh */ glf->glEnable(GL_POLYGON_OFFSET_FILL); glf->glPolygonOffset(1.0, 2); glf->glDrawElements(GL_TRIANGLES, n_faces * 3, GL_UNSIGNED_INT, 0); glf->glDisable(GL_POLYGON_OFFSET_FILL); program.setUniformValue("wireframe", 1); /* Wireframe */ glf21->glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glf->glDepthMask(GL_FALSE); glf->glDrawElements(GL_TRIANGLES, n_faces * 3, GL_UNSIGNED_INT, 0); glf->glDepthMask(GL_TRUE); glf21->glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); /* Holes */ program.setUniformValue("wf_col", QVector3D(1, 0, 1)); holes_index_buffer.bind(); glf->glDrawElements(GL_LINES, n_boundary_halfedges * 2, GL_UNSIGNED_INT, 0); index_buffer.bind(); program.setUniformValue("wf_col", QVector3D(0, 0, 0)); program.setUniformValue("wireframe", 0); } }