Add wireframe render

master
Jeremy Hu 2018-03-19 21:56:10 +08:00
parent f405ac0ede
commit 2aed6b768a
5 changed files with 176 additions and 82 deletions

View File

@ -2,56 +2,111 @@
#include "meshlite.h" #include "meshlite.h"
#include <assert.h> #include <assert.h>
Mesh::Mesh(void *meshlite, int mesh_id) : Mesh::Mesh(void *meshlite, int meshId) :
m_vertices(NULL), m_triangleVertices(NULL),
m_vertexCount(0) m_triangleVertexCount(0),
m_edgeVertices(NULL),
m_edgeVertexCount(0)
{ {
int positionCount = meshlite_get_vertex_count(meshlite, mesh_id); int edgeVertexPositionCount = meshlite_get_vertex_count(meshlite, meshId);
GLfloat *positions = new GLfloat[positionCount * 3]; GLfloat *edgeVertexPositions = new GLfloat[edgeVertexPositionCount * 3];
int loadedPositionItemCount = meshlite_get_vertex_position_array(meshlite, mesh_id, positions, positionCount * 3); int loadedEdgeVertexPositionItemCount = meshlite_get_vertex_position_array(meshlite, meshId, edgeVertexPositions, edgeVertexPositionCount * 3);
int triangleCount = meshlite_get_face_count(meshlite, mesh_id); int edgeCount = meshlite_get_halfedge_count(meshlite, meshId);
int *edgeIndices = new int[edgeCount * 2];
int loadedEdgeVertexIndexItemCount = meshlite_get_halfedge_index_array(meshlite, meshId, edgeIndices, edgeCount * 2);
GLfloat *edgeNormals = new GLfloat[edgeCount * 3];
int loadedEdgeNormalItemCount = meshlite_get_halfedge_normal_array(meshlite, meshId, edgeNormals, edgeCount * 3);
m_edgeVertexCount = edgeCount * 2;
m_edgeVertices = new Vertex[m_edgeVertexCount * 3];
for (int i = 0; i < edgeCount; i++) {
int firstIndex = i * 2;
for (int j = 0; j < 2; j++) {
assert(firstIndex + j < loadedEdgeVertexIndexItemCount);
int posIndex = edgeIndices[firstIndex + j] * 3;
assert(posIndex < loadedEdgeVertexPositionItemCount);
Vertex *v = &m_edgeVertices[firstIndex + j];
v->posX = edgeVertexPositions[posIndex + 0];
v->posY = edgeVertexPositions[posIndex + 1];
v->posZ = edgeVertexPositions[posIndex + 2];
assert(firstIndex + 2 < loadedEdgeNormalItemCount);
v->normX = edgeNormals[firstIndex + 0];
v->normY = edgeNormals[firstIndex + 1];
v->normZ = edgeNormals[firstIndex + 2];
v->colorR = 0;
v->colorG = 0;
v->colorB = 0;
}
}
int triangleMesh = meshlite_triangulate(meshlite, meshId);
int triangleVertexPositionCount = meshlite_get_vertex_count(meshlite, triangleMesh);
GLfloat *triangleVertexPositions = new GLfloat[triangleVertexPositionCount * 3];
int loadedTriangleVertexPositionItemCount = meshlite_get_vertex_position_array(meshlite, triangleMesh, triangleVertexPositions, triangleVertexPositionCount * 3);
int triangleCount = meshlite_get_face_count(meshlite, triangleMesh);
int *triangleIndices = new int[triangleCount * 3]; int *triangleIndices = new int[triangleCount * 3];
int loadedIndexItemCount = meshlite_get_triangle_index_array(meshlite, mesh_id, triangleIndices, triangleCount * 3); int loadedTriangleVertexIndexItemCount = meshlite_get_triangle_index_array(meshlite, triangleMesh, triangleIndices, triangleCount * 3);
GLfloat *normals = new GLfloat[triangleCount * 3]; GLfloat *triangleNormals = new GLfloat[triangleCount * 3];
int loadedNormalItemCount = meshlite_get_triangle_normal_array(meshlite, mesh_id, normals, triangleCount * 3); int loadedTriangleNormalItemCount = meshlite_get_triangle_normal_array(meshlite, triangleMesh, triangleNormals, triangleCount * 3);
m_vertexCount = triangleCount * 3; m_triangleVertexCount = triangleCount * 3;
m_vertices = new Vertex[m_vertexCount * 3]; m_triangleVertices = new Vertex[m_triangleVertexCount * 3];
for (int i = 0; i < triangleCount; i++) { for (int i = 0; i < triangleCount; i++) {
int firstIndex = i * 3; int firstIndex = i * 3;
for (int j = 0; j < 3; j++) { for (int j = 0; j < 3; j++) {
assert(firstIndex + j < loadedIndexItemCount); assert(firstIndex + j < loadedTriangleVertexIndexItemCount);
int posIndex = triangleIndices[firstIndex + j] * 3; int posIndex = triangleIndices[firstIndex + j] * 3;
assert(posIndex < loadedPositionItemCount); assert(posIndex < loadedTriangleVertexPositionItemCount);
Vertex *v = &m_vertices[firstIndex + j]; Vertex *v = &m_triangleVertices[firstIndex + j];
v->posX = positions[posIndex + 0]; v->posX = triangleVertexPositions[posIndex + 0];
v->posY = positions[posIndex + 1]; v->posY = triangleVertexPositions[posIndex + 1];
v->posZ = positions[posIndex + 2]; v->posZ = triangleVertexPositions[posIndex + 2];
assert(firstIndex + 2 < loadedNormalItemCount); assert(firstIndex + 2 < loadedTriangleNormalItemCount);
v->normX = normals[firstIndex + 0]; v->normX = triangleNormals[firstIndex + 0];
v->normY = normals[firstIndex + 1]; v->normY = triangleNormals[firstIndex + 1];
v->normZ = normals[firstIndex + 2]; v->normZ = triangleNormals[firstIndex + 2];
v->colorR = 1.0;
v->colorG = 1.0;
v->colorB = 1.0;
} }
} }
delete[] positions; delete[] triangleVertexPositions;
delete[] triangleIndices; delete[] triangleIndices;
delete[] normals; delete[] triangleNormals;
delete[] edgeVertexPositions;
delete[] edgeIndices;
delete[] edgeNormals;
} }
Mesh::~Mesh() Mesh::~Mesh()
{ {
delete[] m_vertices; delete[] m_triangleVertices;
m_vertexCount = 0; m_triangleVertexCount = 0;
} }
Vertex *Mesh::vertices() Vertex *Mesh::triangleVertices()
{ {
return m_vertices; return m_triangleVertices;
} }
int Mesh::vertexCount() int Mesh::triangleVertexCount()
{ {
return m_vertexCount; return m_triangleVertexCount;
} }
Vertex *Mesh::edgeVertices()
{
return m_edgeVertices;
}
int Mesh::edgeVertexCount()
{
return m_edgeVertexCount;
}

View File

@ -13,19 +13,26 @@ typedef struct
GLfloat normX; GLfloat normX;
GLfloat normY; GLfloat normY;
GLfloat normZ; GLfloat normZ;
GLfloat colorR;
GLfloat colorG;
GLfloat colorB;
} Vertex; } Vertex;
#pragma pack(pop) #pragma pack(pop)
class Mesh class Mesh
{ {
public: public:
Mesh(void *meshlite, int mesh_id); Mesh(void *meshlite, int meshId);
~Mesh(); ~Mesh();
Vertex *vertices(); Vertex *triangleVertices();
int vertexCount(); int triangleVertexCount();
Vertex *edgeVertices();
int edgeVertexCount();
private: private:
Vertex *m_vertices; Vertex *m_triangleVertices;
int m_vertexCount; int m_triangleVertexCount;
Vertex *m_edgeVertices;
int m_edgeVertexCount;
}; };
#endif #endif

View File

@ -14,7 +14,8 @@ ModelingWidget::ModelingWidget(QWidget *parent)
m_yRot(0), m_yRot(0),
m_zRot(0), m_zRot(0),
m_program(0), m_program(0),
m_renderVertexCount(0), m_renderTriangleVertexCount(0),
m_renderEdgeVertexCount(0),
m_mesh(NULL), m_mesh(NULL),
m_meshUpdated(false) m_meshUpdated(false)
{ {
@ -24,6 +25,11 @@ ModelingWidget::ModelingWidget(QWidget *parent)
if (m_transparent) { if (m_transparent) {
QSurfaceFormat fmt = format(); QSurfaceFormat fmt = format();
fmt.setAlphaBufferSize(8); fmt.setAlphaBufferSize(8);
fmt.setSamples(4);
setFormat(fmt);
} else {
QSurfaceFormat fmt = format();
fmt.setSamples(4);
setFormat(fmt); setFormat(fmt);
} }
} }
@ -77,8 +83,8 @@ void ModelingWidget::cleanup()
if (m_program == nullptr) if (m_program == nullptr)
return; return;
makeCurrent(); makeCurrent();
if (m_modelVbo.isCreated()) if (m_vboTriangle.isCreated())
m_modelVbo.destroy(); m_vboTriangle.destroy();
delete m_program; delete m_program;
m_program = 0; m_program = 0;
doneCurrent(); doneCurrent();
@ -88,14 +94,17 @@ static const char *vertexShaderSourceCore =
"#version 150\n" "#version 150\n"
"in vec4 vertex;\n" "in vec4 vertex;\n"
"in vec3 normal;\n" "in vec3 normal;\n"
"in vec3 color;\n"
"out vec3 vert;\n" "out vec3 vert;\n"
"out vec3 vertNormal;\n" "out vec3 vertNormal;\n"
"out vec3 vertColor;\n"
"uniform mat4 projMatrix;\n" "uniform mat4 projMatrix;\n"
"uniform mat4 mvMatrix;\n" "uniform mat4 mvMatrix;\n"
"uniform mat3 normalMatrix;\n" "uniform mat3 normalMatrix;\n"
"void main() {\n" "void main() {\n"
" vert = vertex.xyz;\n" " vert = vertex.xyz;\n"
" vertNormal = normalMatrix * normal;\n" " vertNormal = normalMatrix * normal;\n"
" vertColor = color;\n"
" gl_Position = projMatrix * mvMatrix * vertex;\n" " gl_Position = projMatrix * mvMatrix * vertex;\n"
"}\n"; "}\n";
@ -103,12 +112,13 @@ static const char *fragmentShaderSourceCore =
"#version 150\n" "#version 150\n"
"in highp vec3 vert;\n" "in highp vec3 vert;\n"
"in highp vec3 vertNormal;\n" "in highp vec3 vertNormal;\n"
"in highp vec3 vertColor;\n"
"out highp vec4 fragColor;\n" "out highp vec4 fragColor;\n"
"uniform highp vec3 lightPos;\n" "uniform highp vec3 lightPos;\n"
"void main() {\n" "void main() {\n"
" highp vec3 L = normalize(lightPos - vert);\n" " highp vec3 L = normalize(lightPos - vert);\n"
" highp float NL = max(dot(normalize(vertNormal), L), 0.0);\n" " highp float NL = max(dot(normalize(vertNormal), L), 0.0);\n"
" highp vec3 color = vec3(1.0, 1.0, 1.0);\n" " highp vec3 color = vertColor;\n"
" highp vec3 col = clamp(color * 0.2 + color * 0.8 * NL, 0.0, 1.0);\n" " highp vec3 col = clamp(color * 0.2 + color * 0.8 * NL, 0.0, 1.0);\n"
" fragColor = vec4(col, 1.0);\n" " fragColor = vec4(col, 1.0);\n"
"}\n"; "}\n";
@ -116,25 +126,29 @@ static const char *fragmentShaderSourceCore =
static const char *vertexShaderSource = static const char *vertexShaderSource =
"attribute vec4 vertex;\n" "attribute vec4 vertex;\n"
"attribute vec3 normal;\n" "attribute vec3 normal;\n"
"attribute vec3 color;\n"
"varying vec3 vert;\n" "varying vec3 vert;\n"
"varying vec3 vertNormal;\n" "varying vec3 vertNormal;\n"
"varying vec3 vertColor;\n"
"uniform mat4 projMatrix;\n" "uniform mat4 projMatrix;\n"
"uniform mat4 mvMatrix;\n" "uniform mat4 mvMatrix;\n"
"uniform mat3 normalMatrix;\n" "uniform mat3 normalMatrix;\n"
"void main() {\n" "void main() {\n"
" vert = vertex.xyz;\n" " vert = vertex.xyz;\n"
" vertNormal = normalMatrix * normal;\n" " vertNormal = normalMatrix * normal;\n"
" vertColor = color;\n"
" gl_Position = projMatrix * mvMatrix * vertex;\n" " gl_Position = projMatrix * mvMatrix * vertex;\n"
"}\n"; "}\n";
static const char *fragmentShaderSource = static const char *fragmentShaderSource =
"varying highp vec3 vert;\n" "varying highp vec3 vert;\n"
"varying highp vec3 vertNormal;\n" "varying highp vec3 vertNormal;\n"
"varying highp vec3 vertColor;\n"
"uniform highp vec3 lightPos;\n" "uniform highp vec3 lightPos;\n"
"void main() {\n" "void main() {\n"
" highp vec3 L = normalize(lightPos - vert);\n" " highp vec3 L = normalize(lightPos - vert);\n"
" highp float NL = max(dot(normalize(vertNormal), L), 0.0);\n" " highp float NL = max(dot(normalize(vertNormal), L), 0.0);\n"
" highp vec3 color = vec3(1.0, 1.0, 1.0);\n" " highp vec3 color = vertColor;\n"
" highp vec3 col = clamp(color * 0.2 + color * 0.8 * NL, 0.0, 1.0);\n" " highp vec3 col = clamp(color * 0.2 + color * 0.8 * NL, 0.0, 1.0);\n"
" gl_FragColor = vec4(col, 1.0);\n" " gl_FragColor = vec4(col, 1.0);\n"
"}\n"; "}\n";
@ -159,6 +173,7 @@ void ModelingWidget::initializeGL()
m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, m_core ? fragmentShaderSourceCore : fragmentShaderSource); m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, m_core ? fragmentShaderSourceCore : fragmentShaderSource);
m_program->bindAttributeLocation("vertex", 0); m_program->bindAttributeLocation("vertex", 0);
m_program->bindAttributeLocation("normal", 1); m_program->bindAttributeLocation("normal", 1);
m_program->bindAttributeLocation("color", 2);
m_program->link(); m_program->link();
m_program->bind(); m_program->bind();
@ -171,11 +186,8 @@ void ModelingWidget::initializeGL()
// implementations this is optional and support may not be present // implementations this is optional and support may not be present
// at all. Nonetheless the below code works in all cases and makes // at all. Nonetheless the below code works in all cases and makes
// sure there is a VAO when one is needed. // sure there is a VAO when one is needed.
m_vao.create(); m_vaoTriangle.create();
//QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao); m_vaoEdge.create();
// Store the vertex attribute bindings for the program.
// Our camera never changes in this example. // Our camera never changes in this example.
m_camera.setToIdentity(); m_camera.setToIdentity();
@ -187,17 +199,6 @@ void ModelingWidget::initializeGL()
m_program->release(); m_program->release();
} }
void ModelingWidget::setupVertexAttribs()
{
m_modelVbo.bind();
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
f->glEnableVertexAttribArray(0);
f->glEnableVertexAttribArray(1);
f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), 0);
f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), reinterpret_cast<void *>(3 * sizeof(GLfloat)));
m_modelVbo.release();
}
void ModelingWidget::paintGL() void ModelingWidget::paintGL()
{ {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@ -209,22 +210,47 @@ void ModelingWidget::paintGL()
m_world.rotate(m_yRot / 16.0f, 0, 1, 0); m_world.rotate(m_yRot / 16.0f, 0, 1, 0);
m_world.rotate(m_zRot / 16.0f, 0, 0, 1); m_world.rotate(m_zRot / 16.0f, 0, 0, 1);
QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao);
{ {
QMutexLocker lock(&m_meshMutex); QMutexLocker lock(&m_meshMutex);
if (m_meshUpdated) { if (m_meshUpdated) {
if (m_mesh) { if (m_mesh) {
// Setup our vertex buffer object. {
if (m_modelVbo.isCreated()) QOpenGLVertexArrayObject::Binder vaoBinder(&m_vaoTriangle);
m_modelVbo.destroy(); if (m_vboTriangle.isCreated())
m_modelVbo.create(); m_vboTriangle.destroy();
m_modelVbo.bind(); m_vboTriangle.create();
m_modelVbo.allocate(m_mesh->vertices(), m_mesh->vertexCount() * sizeof(Vertex)); m_vboTriangle.bind();
m_renderVertexCount = m_mesh->vertexCount(); m_vboTriangle.allocate(m_mesh->triangleVertices(), m_mesh->triangleVertexCount() * sizeof(Vertex));
setupVertexAttribs(); m_renderTriangleVertexCount = m_mesh->triangleVertexCount();
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
f->glEnableVertexAttribArray(0);
f->glEnableVertexAttribArray(1);
f->glEnableVertexAttribArray(2);
f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(GLfloat), 0);
f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(GLfloat), reinterpret_cast<void *>(3 * sizeof(GLfloat)));
f->glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(GLfloat), reinterpret_cast<void *>(6 * sizeof(GLfloat)));
m_vboTriangle.release();
}
{
QOpenGLVertexArrayObject::Binder vaoBinder(&m_vaoEdge);
if (m_vboEdge.isCreated())
m_vboEdge.destroy();
m_vboEdge.create();
m_vboEdge.bind();
m_vboEdge.allocate(m_mesh->edgeVertices(), m_mesh->edgeVertexCount() * sizeof(Vertex));
m_renderEdgeVertexCount = m_mesh->edgeVertexCount();
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
f->glEnableVertexAttribArray(0);
f->glEnableVertexAttribArray(1);
f->glEnableVertexAttribArray(2);
f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(GLfloat), 0);
f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(GLfloat), reinterpret_cast<void *>(3 * sizeof(GLfloat)));
f->glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(GLfloat), reinterpret_cast<void *>(6 * sizeof(GLfloat)));
m_vboEdge.release();
}
} else { } else {
m_renderVertexCount = 0; m_renderTriangleVertexCount = 0;
m_renderEdgeVertexCount = 0;
} }
m_meshUpdated = false; m_meshUpdated = false;
} }
@ -236,8 +262,14 @@ void ModelingWidget::paintGL()
QMatrix3x3 normalMatrix = m_world.normalMatrix(); QMatrix3x3 normalMatrix = m_world.normalMatrix();
m_program->setUniformValue(m_normalMatrixLoc, normalMatrix); m_program->setUniformValue(m_normalMatrixLoc, normalMatrix);
if (m_renderVertexCount > 0) if (m_renderEdgeVertexCount > 0) {
glDrawArrays(GL_TRIANGLES, 0, m_renderVertexCount); QOpenGLVertexArrayObject::Binder vaoBinder(&m_vaoEdge);
glDrawArrays(GL_LINES, 0, m_renderEdgeVertexCount);
}
if (m_renderTriangleVertexCount > 0) {
QOpenGLVertexArrayObject::Binder vaoBinder(&m_vaoTriangle);
glDrawArrays(GL_TRIANGLES, 0, m_renderTriangleVertexCount);
}
m_program->release(); m_program->release();
} }

View File

@ -43,16 +43,18 @@ protected:
void mouseMoveEvent(QMouseEvent *event) override; void mouseMoveEvent(QMouseEvent *event) override;
private: private:
void setupVertexAttribs();
bool m_core; bool m_core;
int m_xRot; int m_xRot;
int m_yRot; int m_yRot;
int m_zRot; int m_zRot;
QPoint m_lastPos; QPoint m_lastPos;
QOpenGLVertexArrayObject m_vao; QOpenGLVertexArrayObject m_vaoTriangle;
QOpenGLBuffer m_modelVbo; QOpenGLBuffer m_vboTriangle;
QOpenGLVertexArrayObject m_vaoEdge;
QOpenGLBuffer m_vboEdge;
QOpenGLShaderProgram *m_program; QOpenGLShaderProgram *m_program;
int m_renderVertexCount; int m_renderTriangleVertexCount;
int m_renderEdgeVertexCount;
int m_projMatrixLoc; int m_projMatrixLoc;
int m_mvMatrixLoc; int m_mvMatrixLoc;
int m_normalMatrixLoc; int m_normalMatrixLoc;

View File

@ -373,10 +373,8 @@ void SkeletonToMesh::process()
int meshIdGeneratedFromExternal = makeMeshliteMeshFromExternal(context, unionPolyhedron); int meshIdGeneratedFromExternal = makeMeshliteMeshFromExternal(context, unionPolyhedron);
delete unionPolyhedron; delete unionPolyhedron;
//int subdived = meshlite_subdivide(context, meshIdGeneratedFromCarve); meshlite_export(context, meshIdGeneratedFromExternal, "/Users/jeremy/testlib.obj");
int triangulate = meshlite_triangulate(context, meshIdGeneratedFromExternal); m_mesh = new Mesh(context, meshIdGeneratedFromExternal);
meshlite_export(context, triangulate, "/Users/jeremy/testlib.obj");
m_mesh = new Mesh(context, triangulate);
} }
meshlite_destroy_context(context); meshlite_destroy_context(context);
emit finished(); emit finished();