Add wireframe render
parent
f405ac0ede
commit
2aed6b768a
115
src/mesh.cpp
115
src/mesh.cpp
|
@ -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 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 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 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_vertexCount = triangleCount * 3;
|
||||
m_vertices = new Vertex[m_vertexCount * 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 < loadedIndexItemCount);
|
||||
assert(firstIndex + j < loadedTriangleVertexIndexItemCount);
|
||||
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];
|
||||
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[] positions;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
|
17
src/mesh.h
17
src/mesh.h
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue