Seperate the shader program and mesh binder to seperated source files
parent
ec154633be
commit
b99e0db0b2
|
@ -7,6 +7,12 @@ INCLUDEPATH += src
|
||||||
SOURCES += src/mainwindow.cpp
|
SOURCES += src/mainwindow.cpp
|
||||||
HEADERS += src/mainwindow.h
|
HEADERS += src/mainwindow.h
|
||||||
|
|
||||||
|
SOURCES += src/modelshaderprogram.cpp
|
||||||
|
HEADERS += src/modelshaderprogram.h
|
||||||
|
|
||||||
|
SOURCES += src/modelmeshbinder.cpp
|
||||||
|
HEADERS += src/modelmeshbinder.h
|
||||||
|
|
||||||
SOURCES += src/modelwidget.cpp
|
SOURCES += src/modelwidget.cpp
|
||||||
HEADERS += src/modelwidget.h
|
HEADERS += src/modelwidget.h
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,122 @@
|
||||||
|
#include <QMutexLocker>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QTextStream>
|
||||||
|
#include "modelmeshbinder.h"
|
||||||
|
#include "ds3file.h"
|
||||||
|
|
||||||
|
ModelMeshBinder::ModelMeshBinder() :
|
||||||
|
m_renderTriangleVertexCount(0),
|
||||||
|
m_renderEdgeVertexCount(0),
|
||||||
|
m_mesh(NULL),
|
||||||
|
m_meshUpdated(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ModelMeshBinder::~ModelMeshBinder()
|
||||||
|
{
|
||||||
|
delete m_mesh;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelMeshBinder::updateMesh(Mesh *mesh)
|
||||||
|
{
|
||||||
|
QMutexLocker lock(&m_meshMutex);
|
||||||
|
if (mesh != m_mesh) {
|
||||||
|
delete m_mesh;
|
||||||
|
m_mesh = mesh;
|
||||||
|
m_meshUpdated = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelMeshBinder::exportMeshAsObj(const QString &filename)
|
||||||
|
{
|
||||||
|
QMutexLocker lock(&m_meshMutex);
|
||||||
|
if (m_mesh) {
|
||||||
|
QFile file(filename);
|
||||||
|
if (file.open(QIODevice::WriteOnly)) {
|
||||||
|
QTextStream stream(&file);
|
||||||
|
stream << "# " << Ds3FileReader::m_applicationName << endl;
|
||||||
|
for (std::vector<const QVector3D>::iterator it = m_mesh->vertices().begin() ; it != m_mesh->vertices().end(); ++it) {
|
||||||
|
stream << "v " << (*it).x() << " " << (*it).y() << " " << (*it).z() << endl;
|
||||||
|
}
|
||||||
|
for (std::vector<const std::vector<int>>::iterator it = m_mesh->faces().begin() ; it != m_mesh->faces().end(); ++it) {
|
||||||
|
stream << "f";
|
||||||
|
for (std::vector<const int>::iterator subIt = (*it).begin() ; subIt != (*it).end(); ++subIt) {
|
||||||
|
stream << " " << (1 + *subIt);
|
||||||
|
}
|
||||||
|
stream << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelMeshBinder::initialize()
|
||||||
|
{
|
||||||
|
m_vaoTriangle.create();
|
||||||
|
m_vaoEdge.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelMeshBinder::paint()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
QMutexLocker lock(&m_meshMutex);
|
||||||
|
if (m_meshUpdated) {
|
||||||
|
if (m_mesh) {
|
||||||
|
{
|
||||||
|
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_renderTriangleVertexCount = 0;
|
||||||
|
m_renderEdgeVertexCount = 0;
|
||||||
|
}
|
||||||
|
m_meshUpdated = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelMeshBinder::cleanup()
|
||||||
|
{
|
||||||
|
if (m_vboTriangle.isCreated())
|
||||||
|
m_vboTriangle.destroy();
|
||||||
|
if (m_vboEdge.isCreated())
|
||||||
|
m_vboEdge.destroy();
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
#ifndef MODEL_MESH_BINDER_H
|
||||||
|
#define MODEL_MESH_BINDER_H
|
||||||
|
#include <QOpenGLVertexArrayObject>
|
||||||
|
#include <QMutex>
|
||||||
|
#include <QOpenGLBuffer>
|
||||||
|
#include <QString>
|
||||||
|
#include "mesh.h"
|
||||||
|
|
||||||
|
class ModelMeshBinder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ModelMeshBinder();
|
||||||
|
~ModelMeshBinder();
|
||||||
|
void updateMesh(Mesh *mesh);
|
||||||
|
void exportMeshAsObj(const QString &filename);
|
||||||
|
void initialize();
|
||||||
|
void paint();
|
||||||
|
void cleanup();
|
||||||
|
private:
|
||||||
|
QOpenGLVertexArrayObject m_vaoTriangle;
|
||||||
|
QOpenGLBuffer m_vboTriangle;
|
||||||
|
QOpenGLVertexArrayObject m_vaoEdge;
|
||||||
|
QOpenGLBuffer m_vboEdge;
|
||||||
|
Mesh *m_mesh;
|
||||||
|
QMutex m_meshMutex;
|
||||||
|
int m_renderTriangleVertexCount;
|
||||||
|
int m_renderEdgeVertexCount;
|
||||||
|
bool m_meshUpdated;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,101 @@
|
||||||
|
#include <QSurfaceFormat>
|
||||||
|
#include "modelshaderprogram.h"
|
||||||
|
|
||||||
|
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";
|
||||||
|
|
||||||
|
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 = 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";
|
||||||
|
|
||||||
|
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 = 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";
|
||||||
|
|
||||||
|
ModelShaderProgram::ModelShaderProgram()
|
||||||
|
{
|
||||||
|
this->addShaderFromSourceCode(QOpenGLShader::Vertex, QSurfaceFormat::defaultFormat().profile() == QSurfaceFormat::CoreProfile ? vertexShaderSourceCore : vertexShaderSource);
|
||||||
|
this->addShaderFromSourceCode(QOpenGLShader::Fragment, QSurfaceFormat::defaultFormat().profile() == QSurfaceFormat::CoreProfile ? fragmentShaderSourceCore : fragmentShaderSource);
|
||||||
|
this->bindAttributeLocation("vertex", 0);
|
||||||
|
this->bindAttributeLocation("normal", 1);
|
||||||
|
this->bindAttributeLocation("color", 2);
|
||||||
|
this->link();
|
||||||
|
|
||||||
|
this->bind();
|
||||||
|
m_projMatrixLoc = this->uniformLocation("projMatrix");
|
||||||
|
m_mvMatrixLoc = this->uniformLocation("mvMatrix");
|
||||||
|
m_normalMatrixLoc = this->uniformLocation("normalMatrix");
|
||||||
|
m_lightPosLoc = this->uniformLocation("lightPos");
|
||||||
|
}
|
||||||
|
|
||||||
|
int ModelShaderProgram::projMatrixLoc()
|
||||||
|
{
|
||||||
|
return m_projMatrixLoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ModelShaderProgram::mvMatrixLoc()
|
||||||
|
{
|
||||||
|
return m_mvMatrixLoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ModelShaderProgram::normalMatrixLoc()
|
||||||
|
{
|
||||||
|
return m_normalMatrixLoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ModelShaderProgram::lightPosLoc()
|
||||||
|
{
|
||||||
|
return m_lightPosLoc;
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
#ifndef MODEL_SHADER_PROGRAM_H
|
||||||
|
#define MODEL_SHADER_PROGRAM_H
|
||||||
|
#include <QOpenGLShaderProgram>
|
||||||
|
|
||||||
|
class ModelShaderProgram : public QOpenGLShaderProgram
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ModelShaderProgram();
|
||||||
|
int projMatrixLoc();
|
||||||
|
int mvMatrixLoc();
|
||||||
|
int normalMatrixLoc();
|
||||||
|
int lightPosLoc();
|
||||||
|
private:
|
||||||
|
int m_projMatrixLoc;
|
||||||
|
int m_mvMatrixLoc;
|
||||||
|
int m_normalMatrixLoc;
|
||||||
|
int m_lightPosLoc;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -16,15 +16,10 @@ ModelWidget::ModelWidget(QWidget *parent)
|
||||||
m_xRot(0),
|
m_xRot(0),
|
||||||
m_yRot(0),
|
m_yRot(0),
|
||||||
m_zRot(0),
|
m_zRot(0),
|
||||||
m_program(0),
|
m_program(NULL),
|
||||||
m_renderTriangleVertexCount(0),
|
|
||||||
m_renderEdgeVertexCount(0),
|
|
||||||
m_mesh(NULL),
|
|
||||||
m_meshUpdated(false),
|
|
||||||
m_moveStarted(false),
|
m_moveStarted(false),
|
||||||
m_graphicsView(NULL)
|
m_graphicsView(NULL)
|
||||||
{
|
{
|
||||||
m_core = QSurfaceFormat::defaultFormat().profile() == QSurfaceFormat::CoreProfile;
|
|
||||||
// --transparent causes the clear color to be transparent. Therefore, on systems that
|
// --transparent causes the clear color to be transparent. Therefore, on systems that
|
||||||
// support it, the widget will become transparent apart from the logo.
|
// support it, the widget will become transparent apart from the logo.
|
||||||
if (m_transparent) {
|
if (m_transparent) {
|
||||||
|
@ -49,7 +44,6 @@ void ModelWidget::setGraphicsView(SkeletonEditGraphicsView *view)
|
||||||
ModelWidget::~ModelWidget()
|
ModelWidget::~ModelWidget()
|
||||||
{
|
{
|
||||||
cleanup();
|
cleanup();
|
||||||
delete m_mesh;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qNormalizeAngle(int &angle)
|
static void qNormalizeAngle(int &angle)
|
||||||
|
@ -95,76 +89,12 @@ void ModelWidget::cleanup()
|
||||||
if (m_program == nullptr)
|
if (m_program == nullptr)
|
||||||
return;
|
return;
|
||||||
makeCurrent();
|
makeCurrent();
|
||||||
if (m_vboTriangle.isCreated())
|
m_meshBinder.cleanup();
|
||||||
m_vboTriangle.destroy();
|
|
||||||
delete m_program;
|
delete m_program;
|
||||||
m_program = 0;
|
m_program = 0;
|
||||||
doneCurrent();
|
doneCurrent();
|
||||||
}
|
}
|
||||||
|
|
||||||
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";
|
|
||||||
|
|
||||||
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 = 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";
|
|
||||||
|
|
||||||
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 = 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";
|
|
||||||
|
|
||||||
void ModelWidget::initializeGL()
|
void ModelWidget::initializeGL()
|
||||||
{
|
{
|
||||||
// In this example the widget's corresponding top-level window can change
|
// In this example the widget's corresponding top-level window can change
|
||||||
|
@ -184,33 +114,20 @@ void ModelWidget::initializeGL()
|
||||||
glClearColor(bgcolor.redF(), bgcolor.greenF(), bgcolor.blueF(), 1);
|
glClearColor(bgcolor.redF(), bgcolor.greenF(), bgcolor.blueF(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_program = new QOpenGLShaderProgram;
|
m_program = new ModelShaderProgram;
|
||||||
m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, m_core ? vertexShaderSourceCore : vertexShaderSource);
|
|
||||||
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();
|
|
||||||
m_projMatrixLoc = m_program->uniformLocation("projMatrix");
|
|
||||||
m_mvMatrixLoc = m_program->uniformLocation("mvMatrix");
|
|
||||||
m_normalMatrixLoc = m_program->uniformLocation("normalMatrix");
|
|
||||||
m_lightPosLoc = m_program->uniformLocation("lightPos");
|
|
||||||
|
|
||||||
// Create a vertex array object. In OpenGL ES 2.0 and OpenGL 2.x
|
// Create a vertex array object. In OpenGL ES 2.0 and OpenGL 2.x
|
||||||
// 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_vaoTriangle.create();
|
m_meshBinder.initialize();
|
||||||
m_vaoEdge.create();
|
|
||||||
|
|
||||||
// Our camera never changes in this example.
|
// Our camera never changes in this example.
|
||||||
m_camera.setToIdentity();
|
m_camera.setToIdentity();
|
||||||
m_camera.translate(0, 0, -2.5);
|
m_camera.translate(0, 0, -2.5);
|
||||||
|
|
||||||
// Light position is fixed.
|
// Light position is fixed.
|
||||||
m_program->setUniformValue(m_lightPosLoc, QVector3D(0, 0, 70));
|
m_program->setUniformValue(m_program->lightPosLoc(), QVector3D(0, 0, 70));
|
||||||
|
|
||||||
m_program->release();
|
m_program->release();
|
||||||
}
|
}
|
||||||
|
@ -227,66 +144,14 @@ void ModelWidget::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);
|
||||||
|
|
||||||
{
|
|
||||||
QMutexLocker lock(&m_meshMutex);
|
|
||||||
if (m_meshUpdated) {
|
|
||||||
if (m_mesh) {
|
|
||||||
{
|
|
||||||
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_renderTriangleVertexCount = 0;
|
|
||||||
m_renderEdgeVertexCount = 0;
|
|
||||||
}
|
|
||||||
m_meshUpdated = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_program->bind();
|
m_program->bind();
|
||||||
m_program->setUniformValue(m_projMatrixLoc, m_proj);
|
m_program->setUniformValue(m_program->projMatrixLoc(), m_proj);
|
||||||
m_program->setUniformValue(m_mvMatrixLoc, m_camera * m_world);
|
m_program->setUniformValue(m_program->mvMatrixLoc(), m_camera * m_world);
|
||||||
QMatrix3x3 normalMatrix = m_world.normalMatrix();
|
QMatrix3x3 normalMatrix = m_world.normalMatrix();
|
||||||
m_program->setUniformValue(m_normalMatrixLoc, normalMatrix);
|
m_program->setUniformValue(m_program->normalMatrixLoc(), normalMatrix);
|
||||||
|
|
||||||
if (m_renderEdgeVertexCount > 0) {
|
m_meshBinder.paint();
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
@ -365,33 +230,11 @@ void ModelWidget::wheelEvent(QWheelEvent *event)
|
||||||
|
|
||||||
void ModelWidget::updateMesh(Mesh *mesh)
|
void ModelWidget::updateMesh(Mesh *mesh)
|
||||||
{
|
{
|
||||||
QMutexLocker lock(&m_meshMutex);
|
m_meshBinder.updateMesh(mesh);
|
||||||
if (mesh != m_mesh) {
|
|
||||||
delete m_mesh;
|
|
||||||
m_mesh = mesh;
|
|
||||||
m_meshUpdated = true;
|
|
||||||
update();
|
update();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelWidget::exportMeshAsObj(const QString &filename)
|
void ModelWidget::exportMeshAsObj(const QString &filename)
|
||||||
{
|
{
|
||||||
QMutexLocker lock(&m_meshMutex);
|
m_meshBinder.exportMeshAsObj(filename);
|
||||||
if (m_mesh) {
|
|
||||||
QFile file(filename);
|
|
||||||
if (file.open(QIODevice::WriteOnly)) {
|
|
||||||
QTextStream stream(&file);
|
|
||||||
stream << "# " << Ds3FileReader::m_applicationName << endl;
|
|
||||||
for (std::vector<const QVector3D>::iterator it = m_mesh->vertices().begin() ; it != m_mesh->vertices().end(); ++it) {
|
|
||||||
stream << "v " << (*it).x() << " " << (*it).y() << " " << (*it).z() << endl;
|
|
||||||
}
|
|
||||||
for (std::vector<const std::vector<int>>::iterator it = m_mesh->faces().begin() ; it != m_mesh->faces().end(); ++it) {
|
|
||||||
stream << "f";
|
|
||||||
for (std::vector<const int>::iterator subIt = (*it).begin() ; subIt != (*it).end(); ++subIt) {
|
|
||||||
stream << " " << (1 + *subIt);
|
|
||||||
}
|
|
||||||
stream << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#ifndef MODEL_WIDGET_H
|
#ifndef MODEL_WIDGET_H
|
||||||
#define MODEL_WIDGET_H
|
#define MODEL_WIDGET_H
|
||||||
|
|
||||||
#include <QOpenGLWidget>
|
#include <QOpenGLWidget>
|
||||||
#include <QOpenGLFunctions>
|
#include <QOpenGLFunctions>
|
||||||
#include <QOpenGLVertexArrayObject>
|
#include <QOpenGLVertexArrayObject>
|
||||||
|
@ -9,8 +8,8 @@
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
#include <QRubberBand>
|
#include <QRubberBand>
|
||||||
#include "mesh.h"
|
#include "mesh.h"
|
||||||
|
#include "modelshaderprogram.h"
|
||||||
QT_FORWARD_DECLARE_CLASS(QOpenGLShaderProgram)
|
#include "modelmeshbinder.h"
|
||||||
|
|
||||||
class SkeletonEditGraphicsView;
|
class SkeletonEditGraphicsView;
|
||||||
|
|
||||||
|
@ -49,34 +48,19 @@ protected:
|
||||||
void wheelEvent(QWheelEvent *event) override;
|
void wheelEvent(QWheelEvent *event) override;
|
||||||
void mouseReleaseEvent(QMouseEvent *event) override;
|
void mouseReleaseEvent(QMouseEvent *event) override;
|
||||||
private:
|
private:
|
||||||
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_vaoTriangle;
|
ModelMeshBinder m_meshBinder;
|
||||||
QOpenGLBuffer m_vboTriangle;
|
ModelShaderProgram *m_program;
|
||||||
QOpenGLVertexArrayObject m_vaoEdge;
|
|
||||||
QOpenGLBuffer m_vboEdge;
|
|
||||||
QOpenGLShaderProgram *m_program;
|
|
||||||
int m_renderTriangleVertexCount;
|
|
||||||
int m_renderEdgeVertexCount;
|
|
||||||
int m_projMatrixLoc;
|
|
||||||
int m_mvMatrixLoc;
|
|
||||||
int m_normalMatrixLoc;
|
|
||||||
int m_lightPosLoc;
|
|
||||||
QMatrix4x4 m_proj;
|
QMatrix4x4 m_proj;
|
||||||
QMatrix4x4 m_camera;
|
QMatrix4x4 m_camera;
|
||||||
QMatrix4x4 m_world;
|
QMatrix4x4 m_world;
|
||||||
static bool m_transparent;
|
static bool m_transparent;
|
||||||
|
|
||||||
Mesh *m_mesh;
|
|
||||||
QMutex m_meshMutex;
|
|
||||||
bool m_meshUpdated;
|
|
||||||
bool m_moveStarted;
|
bool m_moveStarted;
|
||||||
QPoint m_moveStartPos;
|
QPoint m_moveStartPos;
|
||||||
QRect m_moveStartGeometry;
|
QRect m_moveStartGeometry;
|
||||||
|
|
||||||
SkeletonEditGraphicsView *m_graphicsView;
|
SkeletonEditGraphicsView *m_graphicsView;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue