From 049998215056daf3adbf27b3b1cf79fa30203e81 Mon Sep 17 00:00:00 2001 From: Anakin Date: Thu, 29 Dec 2016 13:37:15 +0100 Subject: [PATCH] move texture to GeometryEngine --- QtMeshViewer/Header/GeometryEngine.h | 70 ++-------- QtMeshViewer/Header/OglViewerWidget.h | 9 +- QtMeshViewer/Resources/fshader.glsl | 3 - QtMeshViewer/Resources/vshader.glsl | 2 - QtMeshViewer/Source/GeometryEngine.cpp | 169 ++++++++++-------------- QtMeshViewer/Source/OglViewerWidget.cpp | 49 ++----- 6 files changed, 99 insertions(+), 203 deletions(-) diff --git a/QtMeshViewer/Header/GeometryEngine.h b/QtMeshViewer/Header/GeometryEngine.h index 36f7797..38cb92f 100644 --- a/QtMeshViewer/Header/GeometryEngine.h +++ b/QtMeshViewer/Header/GeometryEngine.h @@ -1,73 +1,25 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef GEOMETRYENGINE_H -#define GEOMETRYENGINE_H +#pragma once #include #include #include +#include class GeometryEngine : protected QOpenGLFunctions { public: - GeometryEngine(); - virtual ~GeometryEngine(); + GeometryEngine(); + virtual ~GeometryEngine(); - void drawCubeGeometry(QOpenGLShaderProgram *program); + void drawGeometry(QOpenGLShaderProgram *program); private: - void initCubeGeometry(); + void initCubeGeometry(); + void initTexture(); - QOpenGLBuffer arrayBuf; - QOpenGLBuffer indexBuf; + QOpenGLBuffer arrayBuf; + QOpenGLBuffer indexBuf; + + QOpenGLTexture *texture; }; -#endif // GEOMETRYENGINE_H diff --git a/QtMeshViewer/Header/OglViewerWidget.h b/QtMeshViewer/Header/OglViewerWidget.h index 4b62ae0..2089b94 100644 --- a/QtMeshViewer/Header/OglViewerWidget.h +++ b/QtMeshViewer/Header/OglViewerWidget.h @@ -9,7 +9,7 @@ #include #include #include -#include + class GeometryEngine; @@ -31,8 +31,8 @@ protected: void resizeGL(int w, int h) Q_DECL_OVERRIDE; void paintGL() Q_DECL_OVERRIDE; +private: void initShaders(); - void initTextures(); private: struct { @@ -40,10 +40,9 @@ private: bool right = false; QVector2D position; } m_mouse; - QOpenGLShaderProgram program; - GeometryEngine *geometries; - QOpenGLTexture *texture; + QOpenGLShaderProgram m_program; + GeometryEngine *m_dataEngine; QMatrix4x4 m_projection; QQuaternion m_rotation; diff --git a/QtMeshViewer/Resources/fshader.glsl b/QtMeshViewer/Resources/fshader.glsl index 18068cf..44dc245 100644 --- a/QtMeshViewer/Resources/fshader.glsl +++ b/QtMeshViewer/Resources/fshader.glsl @@ -8,11 +8,8 @@ uniform sampler2D texture; varying vec2 v_texcoord; -//! [0] void main() { // Set fragment color from texture gl_FragColor = texture2D(texture, v_texcoord); } -//! [0] - diff --git a/QtMeshViewer/Resources/vshader.glsl b/QtMeshViewer/Resources/vshader.glsl index cfdc061..d8b9246 100644 --- a/QtMeshViewer/Resources/vshader.glsl +++ b/QtMeshViewer/Resources/vshader.glsl @@ -11,7 +11,6 @@ attribute vec2 a_texcoord; varying vec2 v_texcoord; -//! [0] void main() { // Calculate vertex position in screen space @@ -21,4 +20,3 @@ void main() // Value will be automatically interpolated to fragments inside polygon faces v_texcoord = a_texcoord; } -//! [0] diff --git a/QtMeshViewer/Source/GeometryEngine.cpp b/QtMeshViewer/Source/GeometryEngine.cpp index 21e1703..ad7b77a 100644 --- a/QtMeshViewer/Source/GeometryEngine.cpp +++ b/QtMeshViewer/Source/GeometryEngine.cpp @@ -1,90 +1,41 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - #include "..\Header\GeometryEngine.h" #include #include + struct VertexData { - QVector3D position; - QVector2D texCoord; + QVector3D position; + QVector2D texCoord; }; -//! [0] GeometryEngine::GeometryEngine() - : indexBuf(QOpenGLBuffer::IndexBuffer) + : indexBuf(QOpenGLBuffer::IndexBuffer) + , texture(Q_NULLPTR) { - initializeOpenGLFunctions(); + initializeOpenGLFunctions(); - // Generate 2 VBOs - arrayBuf.create(); - indexBuf.create(); + // Generate 2 VBOs + arrayBuf.create(); + indexBuf.create(); - // Initializes cube geometry and transfers it to VBOs - initCubeGeometry(); + // Initializes cube geometry and transfers it to VBOs + initCubeGeometry(); } GeometryEngine::~GeometryEngine() { - arrayBuf.destroy(); - indexBuf.destroy(); + arrayBuf.destroy(); + indexBuf.destroy(); + delete texture; } -//! [0] 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. + // For cube we would need only 8 vertices but we have to + // duplicate vertex for each face because texture coordinate + // is different. VertexData vertices[] = { // Vertex data for face 0 {QVector3D(-1.0f, -1.0f, 1.0f), QVector2D(0.0f, 0.0f)}, // v0 @@ -131,49 +82,73 @@ void GeometryEngine::initCubeGeometry() // connecting strips have same vertex order then only last // index of the first strip needs to be duplicated. GLushort indices[] = { - 0, 1, 2, 3, 3, // Face 0 - triangle strip ( v0, v1, v2, v3) - 4, 4, 5, 6, 7, 7, // Face 1 - triangle strip ( v4, v5, v6, v7) - 8, 8, 9, 10, 11, 11, // Face 2 - triangle strip ( v8, v9, v10, v11) - 12, 12, 13, 14, 15, 15, // Face 3 - triangle strip (v12, v13, v14, v15) - 16, 16, 17, 18, 19, 19, // Face 4 - triangle strip (v16, v17, v18, v19) - 20, 20, 21, 22, 23 // Face 5 - triangle strip (v20, v21, v22, v23) + 0,1,2, //vorne (4) + 3,2,1, + 4,5,7, //rechts (1) + 6,4,7, + 8,9,11, //hinten (3)* + 8,11,10, + 14,12,13, //links (6)* + 14,13,15, + 18,16,17, //unten (5) + 19,18,17, + 23,22,20, //oben (2)* + 23,20,21 }; -//! [1] // Transfer vertex data to VBO 0 arrayBuf.bind(); arrayBuf.allocate(vertices, 24 * sizeof(VertexData)); // Transfer index data to VBO 1 indexBuf.bind(); - indexBuf.allocate(indices, 34 * sizeof(GLushort)); -//! [1] + indexBuf.allocate(indices, 36 * sizeof(GLushort)); + + initTexture(); } -//! [2] -void GeometryEngine::drawCubeGeometry(QOpenGLShaderProgram *program) +void GeometryEngine::initTexture() { - // Tell OpenGL which VBOs to use - arrayBuf.bind(); - indexBuf.bind(); + // Load cube.png image + texture = new QOpenGLTexture(QImage(":images/cube.png").mirrored()); - // Offset for position - quintptr offset = 0; + // Set nearest filtering mode for texture minification + texture->setMinificationFilter(QOpenGLTexture::Nearest); - // Tell OpenGL programmable pipeline how to locate vertex position data - int vertexLocation = program->attributeLocation("a_position"); - program->enableAttributeArray(vertexLocation); - program->setAttributeBuffer(vertexLocation, GL_FLOAT, offset, 3, sizeof(VertexData)); + // Set bilinear filtering mode for texture magnification + texture->setMagnificationFilter(QOpenGLTexture::Linear); - // Offset for texture coordinate - offset += sizeof(QVector3D); - - // Tell OpenGL programmable pipeline how to locate vertex texture coordinate data - int texcoordLocation = program->attributeLocation("a_texcoord"); - program->enableAttributeArray(texcoordLocation); - program->setAttributeBuffer(texcoordLocation, GL_FLOAT, offset, 2, sizeof(VertexData)); - - // Draw cube geometry using indices from VBO 1 - glDrawElements(GL_TRIANGLE_STRIP, 34, GL_UNSIGNED_SHORT, 0); + // Wrap texture coordinates by repeating + // f.ex. texture coordinate (1.1, 1.2) is same as (0.1, 0.2) + texture->setWrapMode(QOpenGLTexture::Repeat); +} + +void GeometryEngine::drawGeometry(QOpenGLShaderProgram *program) +{ + // Tell OpenGL which VBOs to use + arrayBuf.bind(); + indexBuf.bind(); + texture->bind(); + + // Use texture unit 0 which contains cube.png + program->setUniformValue("texture", 0); + + // Offset for position + quintptr offset = 0; + + // Tell OpenGL programmable pipeline how to locate vertex position data + int vertexLocation = program->attributeLocation("a_position"); + program->enableAttributeArray(vertexLocation); + program->setAttributeBuffer(vertexLocation, GL_FLOAT, offset, 3, sizeof(VertexData)); + + // Offset for texture coordinate + offset += sizeof(QVector3D); + + // Tell OpenGL programmable pipeline how to locate vertex texture coordinate data + int texcoordLocation = program->attributeLocation("a_texcoord"); + program->enableAttributeArray(texcoordLocation); + program->setAttributeBuffer(texcoordLocation, GL_FLOAT, offset, 2, sizeof(VertexData)); + + // Draw cube geometry using indices from VBO 1 + glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 0); } -//! [2] diff --git a/QtMeshViewer/Source/OglViewerWidget.cpp b/QtMeshViewer/Source/OglViewerWidget.cpp index 76554c2..1089f6b 100644 --- a/QtMeshViewer/Source/OglViewerWidget.cpp +++ b/QtMeshViewer/Source/OglViewerWidget.cpp @@ -2,12 +2,10 @@ #include #include -#include OglViewerWidget::OglViewerWidget(QWidget *parent) : QOpenGLWidget(parent), - geometries(0), - texture(0) + m_dataEngine(0) { setFocus(); } @@ -17,8 +15,7 @@ OglViewerWidget::~OglViewerWidget() // Make sure the context is current when deleting the texture // and the buffers. makeCurrent(); - delete texture; - delete geometries; + delete m_dataEngine; doneCurrent(); } @@ -75,7 +72,6 @@ void OglViewerWidget::initializeGL() glClearColor(0, 0, 0, 1); initShaders(); - initTextures(); // Enable depth buffer glEnable(GL_DEPTH_TEST); @@ -83,45 +79,29 @@ void OglViewerWidget::initializeGL() // Enable back face culling glEnable(GL_CULL_FACE); - geometries = new GeometryEngine; + m_dataEngine = new GeometryEngine; } void OglViewerWidget::initShaders() { // Compile vertex shader - if (!program.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shaders/vshader.glsl")) + if (!m_program.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shaders/vshader.glsl")) close(); // Compile fragment shader - if (!program.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shaders/fshader.glsl")) + if (!m_program.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shaders/fshader.glsl")) close(); // Link shader pipeline - if (!program.link()) + if (!m_program.link()) close(); // Bind shader pipeline for use - if (!program.bind()) + if (!m_program.bind()) close(); } -void OglViewerWidget::initTextures() -{ - // Load cube.png image - texture = new QOpenGLTexture(QImage(":images/cube.png").mirrored()); - - // Set nearest filtering mode for texture minification - texture->setMinificationFilter(QOpenGLTexture::Nearest); - - // Set bilinear filtering mode for texture magnification - 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); -} - void OglViewerWidget::resizeGL(int w, int h) { // Calculate aspect ratio @@ -142,19 +122,14 @@ void OglViewerWidget::paintGL() // Clear color and depth buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - texture->bind(); - // Calculate model view transformation - QMatrix4x4 matrix; - matrix.translate(0.0, 0.0, -5.0); - matrix.rotate(m_rotation); + QMatrix4x4 view; + view.translate(0.0, 0.0, -5.0); + view.rotate(m_rotation); // Set modelview-projection matrix - program.setUniformValue("mvp_matrix", m_projection * matrix); - - // Use texture unit 0 which contains cube.png - program.setUniformValue("texture", 0); + m_program.setUniformValue("mvp_matrix", m_projection * view); // Draw cube geometry - geometries->drawCubeGeometry(&program); + m_dataEngine->drawGeometry(&m_program); }