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 <assert.h>
Mesh::Mesh(void *meshlite, int mesh_id) :
m_vertices(NULL),
m_vertexCount(0)
Mesh::Mesh(void *meshlite, int meshId) :
m_triangleVertices(NULL),
m_triangleVertexCount(0),
m_edgeVertices(NULL),
m_edgeVertexCount(0)
{
int positionCount = meshlite_get_vertex_count(meshlite, mesh_id);
GLfloat *positions = new GLfloat[positionCount * 3];
int loadedPositionItemCount = meshlite_get_vertex_position_array(meshlite, mesh_id, positions, positionCount * 3);
int edgeVertexPositionCount = meshlite_get_vertex_count(meshlite, meshId);
GLfloat *edgeVertexPositions = new GLfloat[edgeVertexPositionCount * 3];
int loadedEdgeVertexPositionItemCount = meshlite_get_vertex_position_array(meshlite, meshId, edgeVertexPositions, edgeVertexPositionCount * 3);
int triangleCount = meshlite_get_face_count(meshlite, mesh_id);
int *triangleIndices = new int[triangleCount * 3];
int loadedIndexItemCount = meshlite_get_triangle_index_array(meshlite, mesh_id, triangleIndices, triangleCount * 3);
GLfloat *normals = new GLfloat[triangleCount * 3];
int loadedNormalItemCount = meshlite_get_triangle_normal_array(meshlite, mesh_id, normals, triangleCount * 3);
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_vertexCount = triangleCount * 3;
m_vertices = new Vertex[m_vertexCount * 3];
for (int i = 0; i < triangleCount; i++) {
int firstIndex = i * 3;
for (int j = 0; j < 3; j++) {
assert(firstIndex + j < loadedIndexItemCount);
int posIndex = triangleIndices[firstIndex + j] * 3;
assert(posIndex < loadedPositionItemCount);
Vertex *v = &m_vertices[firstIndex + j];
v->posX = positions[posIndex + 0];
v->posY = positions[posIndex + 1];
v->posZ = positions[posIndex + 2];
assert(firstIndex + 2 < loadedNormalItemCount);
v->normX = normals[firstIndex + 0];
v->normY = normals[firstIndex + 1];
v->normZ = normals[firstIndex + 2];
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;
}
}
delete[] positions;
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 loadedTriangleVertexIndexItemCount = meshlite_get_triangle_index_array(meshlite, triangleMesh, triangleIndices, triangleCount * 3);
GLfloat *triangleNormals = new GLfloat[triangleCount * 3];
int loadedTriangleNormalItemCount = meshlite_get_triangle_normal_array(meshlite, triangleMesh, triangleNormals, triangleCount * 3);
m_triangleVertexCount = triangleCount * 3;
m_triangleVertices = new Vertex[m_triangleVertexCount * 3];
for (int i = 0; i < triangleCount; i++) {
int firstIndex = i * 3;
for (int j = 0; j < 3; j++) {
assert(firstIndex + j < loadedTriangleVertexIndexItemCount);
int posIndex = triangleIndices[firstIndex + j] * 3;
assert(posIndex < loadedTriangleVertexPositionItemCount);
Vertex *v = &m_triangleVertices[firstIndex + j];
v->posX = triangleVertexPositions[posIndex + 0];
v->posY = triangleVertexPositions[posIndex + 1];
v->posZ = triangleVertexPositions[posIndex + 2];
assert(firstIndex + 2 < loadedTriangleNormalItemCount);
v->normX = triangleNormals[firstIndex + 0];
v->normY = triangleNormals[firstIndex + 1];
v->normZ = triangleNormals[firstIndex + 2];
v->colorR = 1.0;
v->colorG = 1.0;
v->colorB = 1.0;
}
}
delete[] triangleVertexPositions;
delete[] triangleIndices;
delete[] normals;
delete[] triangleNormals;
delete[] edgeVertexPositions;
delete[] edgeIndices;
delete[] edgeNormals;
}
Mesh::~Mesh()
{
delete[] m_vertices;
m_vertexCount = 0;
delete[] m_triangleVertices;
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 normY;
GLfloat normZ;
GLfloat colorR;
GLfloat colorG;
GLfloat colorB;
} Vertex;
#pragma pack(pop)
class Mesh
{
public:
Mesh(void *meshlite, int mesh_id);
Mesh(void *meshlite, int meshId);
~Mesh();
Vertex *vertices();
int vertexCount();
Vertex *triangleVertices();
int triangleVertexCount();
Vertex *edgeVertices();
int edgeVertexCount();
private:
Vertex *m_vertices;
int m_vertexCount;
Vertex *m_triangleVertices;
int m_triangleVertexCount;
Vertex *m_edgeVertices;
int m_edgeVertexCount;
};
#endif

View File

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

View File

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

View File

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