diff --git a/QtMeshViewer/Header/GeometryEngine.h b/QtMeshViewer/Header/GeometryEngine.h index 38cb92f..5ae5779 100644 --- a/QtMeshViewer/Header/GeometryEngine.h +++ b/QtMeshViewer/Header/GeometryEngine.h @@ -4,6 +4,7 @@ #include #include #include +#include class GeometryEngine : protected QOpenGLFunctions { @@ -11,15 +12,15 @@ public: GeometryEngine(); virtual ~GeometryEngine(); - void drawGeometry(QOpenGLShaderProgram *program); - private: + QOpenGLBuffer m_arrayBuf; + QOpenGLBuffer m_indexBuf; + QVector m_textures; + void initCubeGeometry(); void initTexture(); - QOpenGLBuffer arrayBuf; - QOpenGLBuffer indexBuf; - - QOpenGLTexture *texture; +public: + void drawGeometry(QOpenGLShaderProgram *program); }; diff --git a/QtMeshViewer/Header/OglViewerWidget.h b/QtMeshViewer/Header/OglViewerWidget.h index 2089b94..9763748 100644 --- a/QtMeshViewer/Header/OglViewerWidget.h +++ b/QtMeshViewer/Header/OglViewerWidget.h @@ -21,6 +21,19 @@ public: explicit OglViewerWidget(QWidget *parent = 0); ~OglViewerWidget(); +private: + struct { + bool left = false; + bool right = false; + QVector2D position; + } m_mouse; + + QOpenGLShaderProgram m_program; + GeometryEngine *m_dataEngine; + + QMatrix4x4 m_projection; + QQuaternion m_rotation; + protected: void mousePressEvent(QMouseEvent *e) Q_DECL_OVERRIDE; void mouseReleaseEvent(QMouseEvent *e) Q_DECL_OVERRIDE; @@ -34,17 +47,6 @@ protected: private: void initShaders(); -private: - struct { - bool left = false; - bool right = false; - QVector2D position; - } m_mouse; - QOpenGLShaderProgram m_program; - GeometryEngine *m_dataEngine; - - QMatrix4x4 m_projection; - QQuaternion m_rotation; }; diff --git a/QtMeshViewer/Source/GeometryEngine.cpp b/QtMeshViewer/Source/GeometryEngine.cpp index ad7b77a..d804a3e 100644 --- a/QtMeshViewer/Source/GeometryEngine.cpp +++ b/QtMeshViewer/Source/GeometryEngine.cpp @@ -10,15 +10,18 @@ struct VertexData QVector2D texCoord; }; + +///////////////////////////////////////////////////////////////////////// +// public constructor/destructor + GeometryEngine::GeometryEngine() - : indexBuf(QOpenGLBuffer::IndexBuffer) - , texture(Q_NULLPTR) + : m_indexBuf(QOpenGLBuffer::IndexBuffer) { initializeOpenGLFunctions(); // Generate 2 VBOs - arrayBuf.create(); - indexBuf.create(); + m_arrayBuf.create(); + m_indexBuf.create(); // Initializes cube geometry and transfers it to VBOs initCubeGeometry(); @@ -26,17 +29,23 @@ GeometryEngine::GeometryEngine() GeometryEngine::~GeometryEngine() { - arrayBuf.destroy(); - indexBuf.destroy(); - delete texture; + m_arrayBuf.destroy(); + m_indexBuf.destroy(); + + for (auto it : m_textures) + delete it; + m_textures.clear(); + m_textures.squeeze(); } + +///////////////////////////////////////////////////////////////////////// +// private functions + void GeometryEngine::initCubeGeometry() { - // For cube we would need only 8 vertices but we have to - // duplicate vertex for each face because texture coordinate - // is different. - VertexData vertices[] = { + + QVector vertices = { // Vertex data for face 0 {QVector3D(-1.0f, -1.0f, 1.0f), QVector2D(0.0f, 0.0f)}, // v0 {QVector3D( 1.0f, -1.0f, 1.0f), QVector2D(0.33f, 0.0f)}, // v1 @@ -74,14 +83,7 @@ void GeometryEngine::initCubeGeometry() {QVector3D( 1.0f, 1.0f, -1.0f), QVector2D(0.66f, 1.0f)} // v23 }; - // Indices for drawing cube faces using triangle strips. - // Triangle strips can be connected by duplicating indices - // between the strips. If connecting strips have opposite - // vertex order then last index of the first strip and first - // index of the second strip needs to be duplicated. If - // connecting strips have same vertex order then only last - // index of the first strip needs to be duplicated. - GLushort indices[] = { + QVector indices = { 0,1,2, //vorne (4) 3,2,1, 4,5,7, //rechts (1) @@ -94,41 +96,48 @@ void GeometryEngine::initCubeGeometry() 19,18,17, 23,22,20, //oben (2)* 23,20,21 - }; + }; - // Transfer vertex data to VBO 0 - arrayBuf.bind(); - arrayBuf.allocate(vertices, 24 * sizeof(VertexData)); + // Transfer vertex data to VBO 0 + m_arrayBuf.bind(); + m_arrayBuf.allocate(vertices.data(), vertices.size() * sizeof(VertexData)); - // Transfer index data to VBO 1 - indexBuf.bind(); - indexBuf.allocate(indices, 36 * sizeof(GLushort)); + // Transfer index data to VBO 1 + m_indexBuf.bind(); + m_indexBuf.allocate(indices.data(), indices.size() * sizeof(GLushort)); + // load the texture initTexture(); } void GeometryEngine::initTexture() { // Load cube.png image - texture = new QOpenGLTexture(QImage(":images/cube.png").mirrored()); + QOpenGLTexture* new_texture = new QOpenGLTexture(QImage(":images/cube.png").mirrored()); // Set nearest filtering mode for texture minification - texture->setMinificationFilter(QOpenGLTexture::Nearest); + new_texture->setMinificationFilter(QOpenGLTexture::Nearest); // Set bilinear filtering mode for texture magnification - texture->setMagnificationFilter(QOpenGLTexture::Linear); + new_texture->setMagnificationFilter(QOpenGLTexture::Linear); // Wrap texture coordinates by repeating // f.ex. texture coordinate (1.1, 1.2) is same as (0.1, 0.2) - texture->setWrapMode(QOpenGLTexture::Repeat); + new_texture->setWrapMode(QOpenGLTexture::Repeat); + + m_textures.push_back(new_texture); } + +///////////////////////////////////////////////////////////////////////// +// public functions + void GeometryEngine::drawGeometry(QOpenGLShaderProgram *program) { // Tell OpenGL which VBOs to use - arrayBuf.bind(); - indexBuf.bind(); - texture->bind(); + m_arrayBuf.bind(); + m_indexBuf.bind(); + m_textures.first()->bind(); // Use texture unit 0 which contains cube.png program->setUniformValue("texture", 0); diff --git a/QtMeshViewer/Source/OglViewerWidget.cpp b/QtMeshViewer/Source/OglViewerWidget.cpp index 1089f6b..a5fa522 100644 --- a/QtMeshViewer/Source/OglViewerWidget.cpp +++ b/QtMeshViewer/Source/OglViewerWidget.cpp @@ -3,6 +3,10 @@ #include #include + +///////////////////////////////////////////////////////////////////////// +// public constructor/destructor + OglViewerWidget::OglViewerWidget(QWidget *parent) : QOpenGLWidget(parent), m_dataEngine(0) @@ -19,6 +23,10 @@ OglViewerWidget::~OglViewerWidget() doneCurrent(); } + +///////////////////////////////////////////////////////////////////////// +// protected functions + void OglViewerWidget::mousePressEvent(QMouseEvent *e) { // Save mouse press position @@ -83,25 +91,6 @@ void OglViewerWidget::initializeGL() } -void OglViewerWidget::initShaders() -{ - // Compile vertex shader - if (!m_program.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shaders/vshader.glsl")) - close(); - - // Compile fragment shader - if (!m_program.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shaders/fshader.glsl")) - close(); - - // Link shader pipeline - if (!m_program.link()) - close(); - - // Bind shader pipeline for use - if (!m_program.bind()) - close(); -} - void OglViewerWidget::resizeGL(int w, int h) { // Calculate aspect ratio @@ -133,3 +122,30 @@ void OglViewerWidget::paintGL() // Draw cube geometry m_dataEngine->drawGeometry(&m_program); } + + +///////////////////////////////////////////////////////////////////////// +// private functions + +void OglViewerWidget::initShaders() +{ + // Compile vertex shader + if (!m_program.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shaders/vshader.glsl")) + close(); + + // Compile fragment shader + if (!m_program.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shaders/fshader.glsl")) + close(); + + // Link shader pipeline + if (!m_program.link()) + close(); + + // Bind shader pipeline for use + if (!m_program.bind()) + close(); +} + + +///////////////////////////////////////////////////////////////////////// +// public functions \ No newline at end of file