Test QOpenGLWidget example with meshlite
commit
7d8e8c4bc5
|
@ -0,0 +1,21 @@
|
||||||
|
QT += core widgets opengl
|
||||||
|
CONFIG += debug
|
||||||
|
|
||||||
|
INCLUDEPATH += src
|
||||||
|
|
||||||
|
SOURCES += src/mainwindow.cpp
|
||||||
|
HEADERS += src/mainwindow.h
|
||||||
|
|
||||||
|
SOURCES += src/modelingwidget.cpp
|
||||||
|
HEADERS += src/modelingwidget.h
|
||||||
|
|
||||||
|
SOURCES += src/mesh.cpp
|
||||||
|
HEADERS += src/mesh.h
|
||||||
|
|
||||||
|
SOURCES += src/main.cpp
|
||||||
|
|
||||||
|
INCLUDEPATH += ../meshlite/include
|
||||||
|
LIBS += -L../meshlite/target/debug -lmeshlite
|
||||||
|
|
||||||
|
target.path = ./
|
||||||
|
INSTALLS += target
|
|
@ -0,0 +1,28 @@
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QDesktopWidget>
|
||||||
|
#include "mainwindow.h"
|
||||||
|
#include "meshlite.h"
|
||||||
|
|
||||||
|
int main(int argc, char ** argv)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
void *lite = meshlite_create_context();
|
||||||
|
int first = meshlite_import(lite, "/Users/jeremy/cube.obj");
|
||||||
|
int second = meshlite_import(lite, "/Users/jeremy/ball.obj");
|
||||||
|
meshlite_scale(lite, first, 0.65);
|
||||||
|
int result = meshlite_intersect(lite, first, second);
|
||||||
|
meshlite_export(lite, result, "/Users/jeremy/testlib.obj");
|
||||||
|
*/
|
||||||
|
QApplication app(argc, argv);
|
||||||
|
QCoreApplication::setApplicationName("Dust 3D");
|
||||||
|
MainWindow mainWindow;
|
||||||
|
mainWindow.resize(mainWindow.sizeHint());
|
||||||
|
int desktopArea = QApplication::desktop()->width() *
|
||||||
|
QApplication::desktop()->height();
|
||||||
|
int widgetArea = mainWindow.width() * mainWindow.height();
|
||||||
|
if (((float)widgetArea / (float)desktopArea) < 0.75f)
|
||||||
|
mainWindow.show();
|
||||||
|
else
|
||||||
|
mainWindow.showMaximized();
|
||||||
|
return app.exec();
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
#include "mainwindow.h"
|
||||||
|
|
||||||
|
|
||||||
|
MainWindow::MainWindow()
|
||||||
|
{
|
||||||
|
modelingWidget = new ModelingWidget(this);
|
||||||
|
setCentralWidget(modelingWidget);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
#ifndef MAIN_WINDOW_H
|
||||||
|
#define MAIN_WINDOW_H
|
||||||
|
|
||||||
|
#include <QMainWindow>
|
||||||
|
#include "modelingwidget.h"
|
||||||
|
|
||||||
|
class MainWindow : public QMainWindow
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
MainWindow();
|
||||||
|
|
||||||
|
private:
|
||||||
|
ModelingWidget *modelingWidget;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,57 @@
|
||||||
|
#include "mesh.h"
|
||||||
|
#include "meshlite.h"
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
Mesh::Mesh(void *meshlite, int mesh_id) :
|
||||||
|
m_vertices(NULL),
|
||||||
|
m_vertexCount(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 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);
|
||||||
|
|
||||||
|
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];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delete[] positions;
|
||||||
|
delete[] triangleIndices;
|
||||||
|
delete[] normals;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mesh::~Mesh()
|
||||||
|
{
|
||||||
|
delete[] m_vertices;
|
||||||
|
m_vertexCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vertex *Mesh::vertices()
|
||||||
|
{
|
||||||
|
return m_vertices;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Mesh::vertexCount()
|
||||||
|
{
|
||||||
|
return m_vertexCount;
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
#ifndef MESH_H
|
||||||
|
#define MESH_H
|
||||||
|
#include <QObject>
|
||||||
|
#include <QOpenGLFunctions>
|
||||||
|
|
||||||
|
#pragma pack(push)
|
||||||
|
#pragma pack(1)
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
GLfloat posX;
|
||||||
|
GLfloat posY;
|
||||||
|
GLfloat posZ;
|
||||||
|
GLfloat normX;
|
||||||
|
GLfloat normY;
|
||||||
|
GLfloat normZ;
|
||||||
|
} Vertex;
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
class Mesh
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Mesh(void *meshlite, int mesh_id);
|
||||||
|
~Mesh();
|
||||||
|
Vertex *vertices();
|
||||||
|
int vertexCount();
|
||||||
|
private:
|
||||||
|
Vertex *m_vertices;
|
||||||
|
int m_vertexCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,280 @@
|
||||||
|
#include "modelingwidget.h"
|
||||||
|
#include <QMouseEvent>
|
||||||
|
#include <QOpenGLShaderProgram>
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <math.h>
|
||||||
|
#include "meshlite.h"
|
||||||
|
|
||||||
|
// Modifed from http://doc.qt.io/qt-5/qtopengl-hellogl2-glwidget-cpp.html
|
||||||
|
|
||||||
|
bool ModelingWidget::m_transparent = false;
|
||||||
|
|
||||||
|
ModelingWidget::ModelingWidget(QWidget *parent)
|
||||||
|
: QOpenGLWidget(parent),
|
||||||
|
m_xRot(0),
|
||||||
|
m_yRot(0),
|
||||||
|
m_zRot(0),
|
||||||
|
m_program(0),
|
||||||
|
m_mesh(NULL)
|
||||||
|
{
|
||||||
|
m_core = QSurfaceFormat::defaultFormat().profile() == QSurfaceFormat::CoreProfile;
|
||||||
|
// --transparent causes the clear color to be transparent. Therefore, on systems that
|
||||||
|
// support it, the widget will become transparent apart from the logo.
|
||||||
|
if (m_transparent) {
|
||||||
|
QSurfaceFormat fmt = format();
|
||||||
|
fmt.setAlphaBufferSize(8);
|
||||||
|
setFormat(fmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *lite = meshlite_create_context();
|
||||||
|
int first = meshlite_import(lite, "/Users/jeremy/cube.obj");
|
||||||
|
int second = meshlite_import(lite, "/Users/jeremy/ball.obj");
|
||||||
|
meshlite_scale(lite, first, 0.65);
|
||||||
|
int intersect = meshlite_intersect(lite, first, second);
|
||||||
|
int triangulate = meshlite_triangulate(lite, intersect);
|
||||||
|
meshlite_export(lite, triangulate, "/Users/jeremy/testlib.obj");
|
||||||
|
Mesh *mesh = new Mesh(lite, triangulate);
|
||||||
|
updateMesh(mesh);
|
||||||
|
}
|
||||||
|
|
||||||
|
ModelingWidget::~ModelingWidget()
|
||||||
|
{
|
||||||
|
cleanup();
|
||||||
|
delete m_mesh;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize ModelingWidget::minimumSizeHint() const
|
||||||
|
{
|
||||||
|
return QSize(50, 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize ModelingWidget::sizeHint() const
|
||||||
|
{
|
||||||
|
return QSize(400, 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void qNormalizeAngle(int &angle)
|
||||||
|
{
|
||||||
|
while (angle < 0)
|
||||||
|
angle += 360 * 16;
|
||||||
|
while (angle > 360 * 16)
|
||||||
|
angle -= 360 * 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelingWidget::setXRotation(int angle)
|
||||||
|
{
|
||||||
|
qNormalizeAngle(angle);
|
||||||
|
if (angle != m_xRot) {
|
||||||
|
m_xRot = angle;
|
||||||
|
emit xRotationChanged(angle);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelingWidget::setYRotation(int angle)
|
||||||
|
{
|
||||||
|
qNormalizeAngle(angle);
|
||||||
|
if (angle != m_yRot) {
|
||||||
|
m_yRot = angle;
|
||||||
|
emit yRotationChanged(angle);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelingWidget::setZRotation(int angle)
|
||||||
|
{
|
||||||
|
qNormalizeAngle(angle);
|
||||||
|
if (angle != m_zRot) {
|
||||||
|
m_zRot = angle;
|
||||||
|
emit zRotationChanged(angle);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelingWidget::cleanup()
|
||||||
|
{
|
||||||
|
if (m_program == nullptr)
|
||||||
|
return;
|
||||||
|
makeCurrent();
|
||||||
|
m_modelVbo.destroy();
|
||||||
|
delete m_program;
|
||||||
|
m_program = 0;
|
||||||
|
doneCurrent();
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *vertexShaderSourceCore =
|
||||||
|
"#version 150\n"
|
||||||
|
"in vec4 vertex;\n"
|
||||||
|
"in vec3 normal;\n"
|
||||||
|
"out vec3 vert;\n"
|
||||||
|
"out vec3 vertNormal;\n"
|
||||||
|
"uniform mat4 projMatrix;\n"
|
||||||
|
"uniform mat4 mvMatrix;\n"
|
||||||
|
"uniform mat3 normalMatrix;\n"
|
||||||
|
"void main() {\n"
|
||||||
|
" vert = vertex.xyz;\n"
|
||||||
|
" vertNormal = normalMatrix * normal;\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"
|
||||||
|
"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(0.39, 1.0, 0.0);\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"
|
||||||
|
"varying vec3 vert;\n"
|
||||||
|
"varying vec3 vertNormal;\n"
|
||||||
|
"uniform mat4 projMatrix;\n"
|
||||||
|
"uniform mat4 mvMatrix;\n"
|
||||||
|
"uniform mat3 normalMatrix;\n"
|
||||||
|
"void main() {\n"
|
||||||
|
" vert = vertex.xyz;\n"
|
||||||
|
" vertNormal = normalMatrix * normal;\n"
|
||||||
|
" gl_Position = projMatrix * mvMatrix * vertex;\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
static const char *fragmentShaderSource =
|
||||||
|
"varying highp vec3 vert;\n"
|
||||||
|
"varying highp vec3 vertNormal;\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(0.39, 1.0, 0.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"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
void ModelingWidget::initializeGL()
|
||||||
|
{
|
||||||
|
// In this example the widget's corresponding top-level window can change
|
||||||
|
// several times during the widget's lifetime. Whenever this happens, the
|
||||||
|
// QOpenGLWidget's associated context is destroyed and a new one is created.
|
||||||
|
// Therefore we have to be prepared to clean up the resources on the
|
||||||
|
// aboutToBeDestroyed() signal, instead of the destructor. The emission of
|
||||||
|
// the signal will be followed by an invocation of initializeGL() where we
|
||||||
|
// can recreate all resources.
|
||||||
|
connect(context(), &QOpenGLContext::aboutToBeDestroyed, this, &ModelingWidget::cleanup);
|
||||||
|
|
||||||
|
initializeOpenGLFunctions();
|
||||||
|
glClearColor(0, 0, 0, m_transparent ? 0 : 1);
|
||||||
|
|
||||||
|
m_program = new QOpenGLShaderProgram;
|
||||||
|
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->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
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
// Setup our vertex buffer object.
|
||||||
|
m_modelVbo.create();
|
||||||
|
m_modelVbo.bind();
|
||||||
|
m_modelVbo.allocate(m_mesh->vertices(), m_mesh->vertexCount() * sizeof(Vertex));
|
||||||
|
|
||||||
|
// Store the vertex attribute bindings for the program.
|
||||||
|
setupVertexAttribs();
|
||||||
|
|
||||||
|
// Our camera never changes in this example.
|
||||||
|
m_camera.setToIdentity();
|
||||||
|
m_camera.translate(0, 0, -4.5);
|
||||||
|
|
||||||
|
// Light position is fixed.
|
||||||
|
m_program->setUniformValue(m_lightPosLoc, QVector3D(0, 0, 70));
|
||||||
|
|
||||||
|
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);
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
glEnable(GL_CULL_FACE);
|
||||||
|
|
||||||
|
m_world.setToIdentity();
|
||||||
|
m_world.rotate(180.0f - (m_xRot / 16.0f), 1, 0, 0);
|
||||||
|
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);
|
||||||
|
m_program->bind();
|
||||||
|
m_program->setUniformValue(m_projMatrixLoc, m_proj);
|
||||||
|
m_program->setUniformValue(m_mvMatrixLoc, m_camera * m_world);
|
||||||
|
QMatrix3x3 normalMatrix = m_world.normalMatrix();
|
||||||
|
m_program->setUniformValue(m_normalMatrixLoc, normalMatrix);
|
||||||
|
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, m_mesh->vertexCount());
|
||||||
|
|
||||||
|
m_program->release();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelingWidget::resizeGL(int w, int h)
|
||||||
|
{
|
||||||
|
m_proj.setToIdentity();
|
||||||
|
m_proj.perspective(45.0f, GLfloat(w) / h, 0.01f, 100.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelingWidget::mousePressEvent(QMouseEvent *event)
|
||||||
|
{
|
||||||
|
m_lastPos = event->pos();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelingWidget::mouseMoveEvent(QMouseEvent *event)
|
||||||
|
{
|
||||||
|
int dx = event->x() - m_lastPos.x();
|
||||||
|
int dy = event->y() - m_lastPos.y();
|
||||||
|
|
||||||
|
if (event->buttons() & Qt::LeftButton) {
|
||||||
|
setXRotation(m_xRot - 8 * dy);
|
||||||
|
setYRotation(m_yRot - 8 * dx);
|
||||||
|
} else if (event->buttons() & Qt::RightButton) {
|
||||||
|
setXRotation(m_xRot - 8 * dy);
|
||||||
|
setZRotation(m_zRot - 8 * dx);
|
||||||
|
}
|
||||||
|
m_lastPos = event->pos();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelingWidget::updateMesh(Mesh *mesh)
|
||||||
|
{
|
||||||
|
QMutexLocker lock(&m_meshMutex);
|
||||||
|
if (mesh != m_mesh) {
|
||||||
|
delete m_mesh;
|
||||||
|
m_mesh = mesh;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
#ifndef MODELING_WIDGET_H
|
||||||
|
#define MODELING_WIDGET_H
|
||||||
|
|
||||||
|
#include <QOpenGLWidget>
|
||||||
|
#include <QOpenGLFunctions>
|
||||||
|
#include <QOpenGLVertexArrayObject>
|
||||||
|
#include <QOpenGLBuffer>
|
||||||
|
#include <QMatrix4x4>
|
||||||
|
#include <QMutex>
|
||||||
|
#include "mesh.h"
|
||||||
|
|
||||||
|
QT_FORWARD_DECLARE_CLASS(QOpenGLShaderProgram)
|
||||||
|
|
||||||
|
class ModelingWidget : public QOpenGLWidget, protected QOpenGLFunctions
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
ModelingWidget(QWidget *parent = 0);
|
||||||
|
~ModelingWidget();
|
||||||
|
|
||||||
|
static bool isTransparent() { return m_transparent; }
|
||||||
|
static void setTransparent(bool t) { m_transparent = t; }
|
||||||
|
|
||||||
|
QSize minimumSizeHint() const override;
|
||||||
|
QSize sizeHint() const override;
|
||||||
|
|
||||||
|
void updateMesh(Mesh *mesh);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void setXRotation(int angle);
|
||||||
|
void setYRotation(int angle);
|
||||||
|
void setZRotation(int angle);
|
||||||
|
void cleanup();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void xRotationChanged(int angle);
|
||||||
|
void yRotationChanged(int angle);
|
||||||
|
void zRotationChanged(int angle);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void initializeGL() override;
|
||||||
|
void paintGL() override;
|
||||||
|
void resizeGL(int width, int height) override;
|
||||||
|
void mousePressEvent(QMouseEvent *event) override;
|
||||||
|
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;
|
||||||
|
QOpenGLShaderProgram *m_program;
|
||||||
|
int m_projMatrixLoc;
|
||||||
|
int m_mvMatrixLoc;
|
||||||
|
int m_normalMatrixLoc;
|
||||||
|
int m_lightPosLoc;
|
||||||
|
QMatrix4x4 m_proj;
|
||||||
|
QMatrix4x4 m_camera;
|
||||||
|
QMatrix4x4 m_world;
|
||||||
|
static bool m_transparent;
|
||||||
|
|
||||||
|
Mesh *m_mesh;
|
||||||
|
QMutex m_meshMutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue