#include "mesh_view.h" #include "util.h" #include #include 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; QVector vertices(n_vertices * 3); size_t i = 0; for (const VertexHandle it : mesh.vertices()) { vertices[3*i + 0] = mesh.point(it)[0]; vertices[3*i + 1] = mesh.point(it)[1]; vertices[3*i + 2] = mesh.point(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++; } vao.create(); {QOpenGLVertexArrayObject::Binder binder(&vao); vertex_buffer.create(); vertex_buffer.bind(); vertex_buffer.setUsagePattern(QOpenGLBuffer::StreamDraw); vertex_buffer.allocate(vertices.constData(), n_vertices * 3 * sizeof (GLfloat)); index_buffer.create(); index_buffer.bind(); index_buffer.setUsagePattern(QOpenGLBuffer::StreamDraw); index_buffer.allocate(indices.constData(), n_faces * 3 * sizeof (GLuint)); program.setAttributeBuffer("pos", GL_FLOAT, 0, 3); program.enableAttributeArray("pos"); } } MeshView::~MeshView() { vertex_buffer.destroy(); index_buffer.destroy(); vao.destroy(); } void MeshView::paint(QOpenGLShaderProgram &program) { const MyMesh &mesh = mesh_processor.mesh; 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); /* Wireframe */ glf21->glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glf->glLineWidth(2); program.setUniformValue("wireframe", 1); glf->glDrawElements(GL_TRIANGLES, n_faces * 3, GL_UNSIGNED_INT, 0); glf21->glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); program.setUniformValue("wireframe", 0); // 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)); } }