QT6 使用OpenGL库画两个不同外形的立方体(1)

QT6 使用OpenGL库画两个不同外形的立方体

首先准备两幅图片,分别如下

然后新建一个工程,不用窗体。分别新建如下代码:

文档结构如下:

two_cube.pro

QT += core gui widgets opengl openglwidgets

TARGET = cube
TEMPLATE = app

SOURCES += main.cpp

SOURCES += \
    mainwidget.cpp \
    geometryengine.cpp

HEADERS += \
    mainwidget.h \
    geometryengine.h

RESOURCES += \
    shaders.qrc \
    textures.qrc

# install
target.path = $$[QT_INSTALL_EXAMPLES]/opengl/cube
INSTALLS += target
GEOMETRYENGINE_H
#ifndef GEOMETRYENGINE_H
#define GEOMETRYENGINE_H

#include <QOpenGLFunctions>
#include <QOpenGLShaderProgram>
#include <QOpenGLBuffer>

class GeometryEngine : protected QOpenGLFunctions
{
public:
    GeometryEngine();
    virtual ~GeometryEngine();

    void drawCubeGeometry(QOpenGLShaderProgram *program);
    void drawCubeGeometry2(QOpenGLShaderProgram *program);


private:
    void initCubeGeometry();

    QOpenGLBuffer arrayBuf;
    QOpenGLBuffer indexBuf;

    QOpenGLBuffer arrayBuf2;
};

#endif // GEOMETRYENGINE_H
MAINWIDGET_H
#ifndef MAINWIDGET_H
#define MAINWIDGET_H

#include "geometryengine.h"

#include <QOpenGLWidget>
#include <QOpenGLFunctions>
#include <QMatrix4x4>
#include <QQuaternion>
#include <QVector2D>
#include <QBasicTimer>
#include <QOpenGLShaderProgram>
#include <QOpenGLTexture>

class GeometryEngine;

class MainWidget : public QOpenGLWidget, protected QOpenGLFunctions
{
    Q_OBJECT

public:
    using QOpenGLWidget::QOpenGLWidget;
    ~MainWidget();

protected:
    void mousePressEvent(QMouseEvent *e) override;
    void mouseReleaseEvent(QMouseEvent *e) override;
    void timerEvent(QTimerEvent *e) override;

    void initializeGL() override;
    void resizeGL(int w, int h) override;
    void paintGL() override;

    void initShaders();
    void initTextures();

private:
    QBasicTimer timer;
    QOpenGLShaderProgram program;
    QOpenGLShaderProgram program2;
    GeometryEngine *geometries = nullptr;

    QOpenGLTexture *texture = nullptr;
    QOpenGLTexture *texture2 = nullptr;

    QMatrix4x4 projection;
    QMatrix4x4 projection2;

    QVector2D mousePressPosition;
    QVector3D rotationAxis;
    qreal angularSpeed = 0;
    QQuaternion rotation;
    QQuaternion rotation2;
};

#endif // MAINWIDGET_H
geometryengine.cpp
#include "geometryengine.h"

#include <QVector2D>
#include <QVector3D>

struct VertexData
{
    QVector3D position;
    QVector2D texCoord;
};

//! [0]
GeometryEngine::GeometryEngine()
    : indexBuf(QOpenGLBuffer::IndexBuffer)
{
    initializeOpenGLFunctions();

    // Generate 2 VBOs
    arrayBuf.create();
    arrayBuf2.create();
    indexBuf.create();

    // Initializes cube geometry and transfers it to VBOs
    initCubeGeometry();
}

GeometryEngine::~GeometryEngine()
{
    arrayBuf.destroy();
    arrayBuf2.destroy();
    indexBuf.destroy();
}
//! [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.
    VertexData 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
        {QVector3D(-1.0f,  1.0f,  1.0f), QVector2D(0.0f, 0.5f)},  // v2
        {QVector3D( 1.0f,  1.0f,  1.0f), QVector2D(0.33f, 0.5f)}, // v3

        // Vertex data for face 1
        {QVector3D( 1.0f, -1.0f,  1.0f), QVector2D( 0.0f, 0.5f)}, // v4
        {QVector3D( 1.0f, -1.0f, -1.0f), QVector2D(0.33f, 0.5f)}, // v5
        {QVector3D( 1.0f,  1.0f,  1.0f), QVector2D(0.0f, 1.0f)},  // v6
        {QVector3D( 1.0f,  1.0f, -1.0f), QVector2D(0.33f, 1.0f)}, // v7

        // Vertex data for face 2
        {QVector3D( 1.0f, -1.0f, -1.0f), QVector2D(0.66f, 0.5f)}, // v8
        {QVector3D(-1.0f, -1.0f, -1.0f), QVector2D(1.0f, 0.5f)},  // v9
        {QVector3D( 1.0f,  1.0f, -1.0f), QVector2D(0.66f, 1.0f)}, // v10
        {QVector3D(-1.0f,  1.0f, -1.0f), QVector2D(1.0f, 1.0f)},  // v11

        // Vertex data for face 3
        {QVector3D(-1.0f, -1.0f, -1.0f), QVector2D(0.66f, 0.0f)}, // v12
        {QVector3D(-1.0f, -1.0f,  1.0f), QVector2D(1.0f, 0.0f)},  // v13
        {QVector3D(-1.0f,  1.0f, -1.0f), QVector2D(0.66f, 0.5f)}, // v14
        {QVector3D(-1.0f,  1.0f,  1.0f), QVector2D(1.0f, 0.5f)},  // v15

        // Vertex data for face 4
        {QVector3D(-1.0f, -1.0f, -1.0f), QVector2D(0.33f, 0.0f)}, // v16
        {QVector3D( 1.0f, -1.0f, -1.0f), QVector2D(0.66f, 0.0f)}, // v17
        {QVector3D(-1.0f, -1.0f,  1.0f), QVector2D(0.33f, 0.5f)}, // v18
        {QVector3D( 1.0f, -1.0f,  1.0f), QVector2D(0.66f, 0.5f)}, // v19

        // Vertex data for face 5
        {QVector3D(-1.0f,  1.0f,  1.0f), QVector2D(0.33f, 0.5f)}, // v20
        {QVector3D( 1.0f,  1.0f,  1.0f), QVector2D(0.66f, 0.5f)}, // v21
        {QVector3D(-1.0f,  1.0f, -1.0f), QVector2D(0.33f, 1.0f)}, // v22
        {QVector3D( 1.0f,  1.0f, -1.0f), QVector2D(0.66f, 1.0f)},  // v23

        /***
        // Vertex data for face 01
        {QVector3D(-1.0f, -1.0f,  1.0f), QVector2D(0.0f-0.2f, 0.0f-0.2f)},  // v0
        {QVector3D( 1.0f, -1.0f,  1.0f), QVector2D(0.33f-0.2f, 0.0f-0.2f)}, // v1
        {QVector3D(-1.0f,  1.0f,  1.0f), QVector2D(0.0f-0.2f, 0.5f-0.2f)},  // v2
        {QVector3D( 1.0f,  1.0f,  1.0f), QVector2D(0.33f-0.2f, 0.5f-0.2f)}, // v3

        // Vertex data for face 11
        {QVector3D( 1.0f, -1.0f,  1.0f), QVector2D( 0.0f-0.2f, 0.5f-0.2f)}, // v4
        {QVector3D( 1.0f, -1.0f, -1.0f), QVector2D(0.33f-0.2f, 0.5f-0.2f)}, // v5
        {QVector3D( 1.0f,  1.0f,  1.0f), QVector2D(0.0f-0.2f, 1.0f-0.2f)},  // v6
        {QVector3D( 1.0f,  1.0f, -1.0f), QVector2D(0.33f-0.2f, 1.0f-0.2f)}, // v7

        // Vertex data for face 21
        {QVector3D( 1.0f, -1.0f, -1.0f), QVector2D(0.66f-0.2f, 0.5f-0.2f)}, // v8
        {QVector3D(-1.0f, -1.0f, -1.0f), QVector2D(1.0f-0.2f, 0.5f-0.2f)},  // v9
        {QVector3D( 1.0f,  1.0f, -1.0f), QVector2D(0.66f-0.2f, 1.0f-0.2f)}, // v10
        {QVector3D(-1.0f,  1.0f, -1.0f), QVector2D(1.0f-0.2f, 1.0f-0.2f)},  // v11

        // Vertex data for face 31
        {QVector3D(-1.0f, -1.0f, -1.0f), QVector2D(0.66f-0.2f, 0.0f-0.2f)}, // v12
        {QVector3D(-1.0f, -1.0f,  1.0f), QVector2D(1.0f-0.2f, 0.0f-0.2f)},  // v13
        {QVector3D(-1.0f,  1.0f, -1.0f), QVector2D(0.66f-0.2f, 0.5f-0.2f)}, // v14
        {QVector3D(-1.0f,  1.0f,  1.0f), QVector2D(1.0f-0.2f, 0.5f-0.2f)},  // v15

        // Vertex data for face 41
        {QVector3D(-1.0f, -1.0f, -1.0f), QVector2D(0.33f-0.2f, 0.0f-0.2f)}, // v16
        {QVector3D( 1.0f, -1.0f, -1.0f), QVector2D(0.66f-0.2f, 0.0f-0.2f)}, // v17
        {QVector3D(-1.0f, -1.0f,  1.0f), QVector2D(0.33f-0.2f, 0.5f-0.2f)}, // v18
        {QVector3D( 1.0f, -1.0f,  1.0f), QVector2D(0.66f-0.2f, 0.5f-0.2f)}, // v19

        // Vertex data for face 51
        {QVector3D(-1.0f,  1.0f,  1.0f), QVector2D(0.33f-0.2f, 0.5f-0.2f)}, // v20
        {QVector3D( 1.0f,  1.0f,  1.0f), QVector2D(0.66f-0.2f, 0.5f-0.2f)}, // v21
        {QVector3D(-1.0f,  1.0f, -1.0f), QVector2D(0.33f-0.2f, 1.0f-0.2f)}, // v22
        {QVector3D( 1.0f,  1.0f, -1.0f), QVector2D(0.66f-0.2f, 1.0f-0.2f)}  // v23
        ***/
    };


    /***
    VertexData vertices2[] = {
        // Vertex data for face 0
        {QVector3D(-1.0f, -1.0f,  1.0f), QVector2D(0.0f-0.2f, 0.0f-0.2f)},  // v0
        {QVector3D( 1.0f, -1.0f,  1.0f), QVector2D(0.33f-0.2f, 0.0f-0.2f)}, // v1
        {QVector3D(-1.0f,  1.0f,  1.0f), QVector2D(0.0f-0.2f, 0.5f-0.2f)},  // v2
        {QVector3D( 1.0f,  1.0f,  1.0f), QVector2D(0.33f-0.2f, 0.5f-0.2f)}, // v3

        // Vertex data for face 1
        {QVector3D( 1.0f, -1.0f,  1.0f), QVector2D( 0.0f-0.2f, 0.5f-0.2f)}, // v4
        {QVector3D( 1.0f, -1.0f, -1.0f), QVector2D(0.33f-0.2f, 0.5f-0.2f)}, // v5
        {QVector3D( 1.0f,  1.0f,  1.0f), QVector2D(0.0f-0.2f, 1.0f-0.2f)},  // v6
        {QVector3D( 1.0f,  1.0f, -1.0f), QVector2D(0.33f-0.2f, 1.0f-0.2f)}, // v7

        // Vertex data for face 2
        {QVector3D( 1.0f, -1.0f, -1.0f), QVector2D(0.66f-0.2f, 0.5f-0.2f)}, // v8
        {QVector3D(-1.0f, -1.0f, -1.0f), QVector2D(1.0f-0.2f, 0.5f-0.2f)},  // v9
        {QVector3D( 1.0f,  1.0f, -1.0f), QVector2D(0.66f-0.2f, 1.0f-0.2f)}, // v10
        {QVector3D(-1.0f,  1.0f, -1.0f), QVector2D(1.0f-0.2f, 1.0f-0.2f)},  // v11

        // Vertex data for face 3
        {QVector3D(-1.0f, -1.0f, -1.0f), QVector2D(0.66f-0.2f, 0.0f-0.2f)}, // v12
        {QVector3D(-1.0f, -1.0f,  1.0f), QVector2D(1.0f-0.2f, 0.0f-0.2f)},  // v13
        {QVector3D(-1.0f,  1.0f, -1.0f), QVector2D(0.66f-0.2f, 0.5f-0.2f)}, // v14
        {QVector3D(-1.0f,  1.0f,  1.0f), QVector2D(1.0f-0.2f, 0.5f-0.2f)},  // v15

        // Vertex data for face 4
        {QVector3D(-1.0f, -1.0f, -1.0f), QVector2D(0.33f-0.2f, 0.0f-0.2f)}, // v16
        {QVector3D( 1.0f, -1.0f, -1.0f), QVector2D(0.66f-0.2f, 0.0f-0.2f)}, // v17
        {QVector3D(-1.0f, -1.0f,  1.0f), QVector2D(0.33f-0.2f, 0.5f-0.2f)}, // v18
        {QVector3D( 1.0f, -1.0f,  1.0f), QVector2D(0.66f-0.2f, 0.5f-0.2f)}, // v19

        // Vertex data for face 5
        {QVector3D(-1.0f,  1.0f,  1.0f), QVector2D(0.33f-0.2f, 0.5f-0.2f)}, // v20
        {QVector3D( 1.0f,  1.0f,  1.0f), QVector2D(0.66f-0.2f, 0.5f-0.2f)}, // v21
        {QVector3D(-1.0f,  1.0f, -1.0f), QVector2D(0.33f-0.2f, 1.0f-0.2f)}, // v22
        {QVector3D( 1.0f,  1.0f, -1.0f), QVector2D(0.66f-0.2f, 1.0f-0.2f)}  // v23
    };
    ***/


     VertexData vertices3[] = {
         // Vertex data for face 02
         {QVector3D(-1.0f-3.0f*0.5f, -1.0f-3.0f*0.5f,  1.0f-3.0f*0.5f), QVector2D(0.0f, 0.0f)},  // v0
         {QVector3D( 1.0f-3.0f*0.5f, -1.0f-3.0f*0.5f,  1.0f-3.0f*0.5f), QVector2D(0.33f, 0.0f)}, // v1
         {QVector3D(-1.0f-3.0f*0.5f,  1.0f-3.0f*0.5f,  1.0f-3.0f*0.5f), QVector2D(0.0f, 0.5f)},  // v2
         {QVector3D( 1.0f-3.0f*0.5f,  1.0f-3.0f*0.5f,  1.0f-3.0f*0.5f), QVector2D(0.33f, 0.5f)}, // v3

         // Vertex data for face 12
         {QVector3D( 1.0f-3.0f*0.5f, -1.0f-3.0f*0.5f,  1.0f-3.0f*0.5f), QVector2D( 0.0f, 0.5f)}, // v4
         {QVector3D( 1.0f-3.0f*0.5f, -1.0f-3.0f*0.5f, -1.0f-3.0f*0.5f), QVector2D(0.33f, 0.5f)}, // v5
         {QVector3D( 1.0f-3.0f*0.5f,  1.0f-3.0f*0.5f,  1.0f-3.0f*0.5f), QVector2D(0.0f, 1.0f)},  // v6
         {QVector3D( 1.0f-3.0f*0.5f,  1.0f-3.0f*0.5f, -1.0f-3.0f*0.5f), QVector2D(0.33f, 1.0f)}, // v7

         // Vertex data for face 22
         {QVector3D( 1.0f-3.0f*0.5f, -1.0f-3.0f*0.5f, -1.0f-3.0f*0.5f), QVector2D(0.66f, 0.5f)}, // v8
         {QVector3D(-1.0f-3.0f*0.5f, -1.0f-3.0f*0.5f, -1.0f-3.0f*0.5f), QVector2D(1.0f, 0.5f)},  // v9
         {QVector3D( 1.0f-3.0f*0.5f,  1.0f-3.0f*0.5f, -1.0f-3.0f*0.5f), QVector2D(0.66f, 1.0f)}, // v10
         {QVector3D(-1.0f-3.0f*0.5f,  1.0f-3.0f*0.5f, -1.0f-3.0f*0.5f), QVector2D(1.0f, 1.0f)},  // v11

         // Vertex data for face 32
         {QVector3D(-1.0f-3.0f*0.5f, -1.0f-3.0f*0.5f, -1.0f-3.0f*0.5f), QVector2D(0.66f, 0.0f)}, // v12
         {QVector3D(-1.0f-3.0f*0.5f, -1.0f-3.0f*0.5f,  1.0f-3.0f*0.5f), QVector2D(1.0f, 0.0f)},  // v13
         {QVector3D(-1.0f-3.0f*0.5f,  1.0f-3.0f*0.5f, -1.0f-3.0f*0.5f), QVector2D(0.66f, 0.5f)}, // v14
         {QVector3D(-1.0f-3.0f*0.5f,  1.0f-3.0f*0.5f,  1.0f-3.0f*0.5f), QVector2D(1.0f, 0.5f)},  // v15

         // Vertex data for face 42
         {QVector3D(-1.0f-3.0f*0.5f, -1.0f-3.0f*0.5f, -1.0f-3.0f*0.5f), QVector2D(0.33f, 0.0f)}, // v16
         {QVector3D( 1.0f-3.0f*0.5f, -1.0f-3.0f*0.5f, -1.0f-3.0f*0.5f), QVector2D(0.66f, 0.0f)}, // v17
         {QVector3D(-1.0f-3.0f*0.5f, -1.0f-3.0f*0.5f,  1.0f-3.0f*0.5f), QVector2D(0.33f, 0.5f)}, // v18
         {QVector3D( 1.0f-3.0f*0.5f, -1.0f-3.0f*0.5f,  1.0f-3.0f*0.5f), QVector2D(0.66f, 0.5f)}, // v19

         // Vertex data for face 52
         {QVector3D(-1.0f-3.0f*0.5f,  1.0f-3.0f*0.5f,  1.0f-3.0f*0.5f), QVector2D(0.33f, 0.5f)}, // v20
         {QVector3D( 1.0f-3.0f*0.5f,  1.0f-3.0f*0.5f,  1.0f-3.0f*0.5f), QVector2D(0.66f, 0.5f)}, // v21
         {QVector3D(-1.0f-3.0f*0.5f,  1.0f-3.0f*0.5f, -1.0f-3.0f*0.5f), QVector2D(0.33f, 1.0f)}, // v22
         {QVector3D( 1.0f-3.0f*0.5f,  1.0f-3.0f*0.5f, -1.0f-3.0f*0.5f), 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[] = {
         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)
    };

//! [1]
    // Transfer vertex data to VBO 0
    arrayBuf.bind();
    arrayBuf.allocate(vertices, 24 * sizeof(VertexData));
    arrayBuf2.bind();
    arrayBuf2.allocate(vertices3, 24 * sizeof(VertexData));
    // Transfer index data to VBO 1
    indexBuf.bind();
    indexBuf.allocate(indices, 34 * sizeof(GLushort));
//! [1]
}

//! [2]
void GeometryEngine::drawCubeGeometry(QOpenGLShaderProgram *program)
{
    // Tell OpenGL which VBOs to use
    arrayBuf.bind();
    //arrayBuf2.bind();
    indexBuf.bind();

    // 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_TRIANGLE_STRIP, 34, GL_UNSIGNED_SHORT, nullptr);
}


void GeometryEngine::drawCubeGeometry2(QOpenGLShaderProgram *program)
{
    // Tell OpenGL which VBOs to use
    //arrayBuf.bind();
    arrayBuf2.bind();
    indexBuf.bind();

    // 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_TRIANGLE_STRIP, 34, GL_UNSIGNED_SHORT, nullptr);
}
//! [2]

mainwidget.cpp 

#include "mainwidget.h"

#include <QMouseEvent>

#include <cmath>

MainWidget::~MainWidget()
{
    // Make sure the context is current when deleting the texture
    // and the buffers.
    makeCurrent();
    delete texture;
    delete texture2;
    delete geometries;
    doneCurrent();
}

//! [0]
void MainWidget::mousePressEvent(QMouseEvent *e)
{
    // Save mouse press position
    mousePressPosition = QVector2D(e->position());
}

void MainWidget::mouseReleaseEvent(QMouseEvent *e)
{
    // Mouse release position - mouse press position
    QVector2D diff = QVector2D(e->position()) - mousePressPosition;

    // Rotation axis is perpendicular to the mouse position difference
    // vector
    QVector3D n = QVector3D(diff.y(), diff.x(), 0.0).normalized();

    // Accelerate angular speed relative to the length of the mouse sweep
    qreal acc = diff.length() / 100.0;

    // Calculate new rotation axis as weighted sum
    rotationAxis = (rotationAxis * angularSpeed + n * acc).normalized();

    // Increase angular speed
    angularSpeed += acc;
}
//! [0]

//! [1]
void MainWidget::timerEvent(QTimerEvent *)
{
    // Decrease angular speed (friction)
    angularSpeed *= 0.99;

    // Stop rotation when speed goes below threshold
    if (angularSpeed < 0.01) {
        angularSpeed = 0.0;
    } else {
        // Update rotation
        rotation = QQuaternion::fromAxisAndAngle(rotationAxis, angularSpeed) * rotation;
        rotation2 = QQuaternion::fromAxisAndAngle(rotationAxis, angularSpeed/2.0) * rotation2;
        // Request an update
        update();
    }
}
//! [1]

void MainWidget::initializeGL()
{
    initializeOpenGLFunctions();

    glClearColor(0, 0, 0, 1);

    initShaders();
    initTextures();

//! [2]
    // Enable depth buffer
    glEnable(GL_DEPTH_TEST);

    // Enable back face culling
    glEnable(GL_CULL_FACE);
//! [2]

    geometries = new GeometryEngine;

    // Use QBasicTimer because its faster than QTimer
    timer.start(12, this);
}

//! [3]
void MainWidget::initShaders()
{
    // Compile vertex shader
    if (!program.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/vshader.glsl"))
        close();

    // Compile fragment shader
    if (!program.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/fshader.glsl"))
        close();

    // Link shader pipeline
    if (!program.link())
        close();

    // Bind shader pipeline for use
    if (!program.bind())
        close();

    // Compile vertex shader
    if (!program2.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/vshader.glsl"))
        close();

    // Compile fragment shader
    if (!program2.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/fshader.glsl"))
        close();

    // Link shader pipeline
    if (!program2.link())
        close();

    // Bind shader pipeline for use
    if (!program2.bind())
        close();
}
//! [3]

//! [4]
void MainWidget::initTextures()
{
    // Load cube.png image
    texture = new QOpenGLTexture(QImage(":/cube3.jpeg").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);

    // Load cube.png image
    texture2 = new QOpenGLTexture(QImage(":/cube.jpg").mirrored());

    // Set nearest filtering mode for texture minification
    texture2->setMinificationFilter(QOpenGLTexture::Nearest);

    // Set bilinear filtering mode for texture magnification
    texture2->setMagnificationFilter(QOpenGLTexture::Linear);

    // Wrap texture coordinates by repeating
    // f.ex. texture coordinate (1.1, 1.2) is same as (0.1, 0.2)
    texture2->setWrapMode(QOpenGLTexture::Repeat);
}
//! [4]

//! [5]
void MainWidget::resizeGL(int w, int h)
{
    // Calculate aspect ratio
    qreal aspect = qreal(w) / qreal(h ? h : 1);

    qreal aspect2 = aspect*1.5;//此处可以改变立方体形状

    // Set near plane to 3.0, far plane to 7.0, field of view 45 degrees
    const qreal zNear = 3.0, zFar = 7.0, fov = 45.0;

    // Reset projection
    projection.setToIdentity();

    // Set perspective projection
    projection.perspective(fov, aspect, zNear, zFar);

    // Reset projection
    projection2.setToIdentity();

    // Set perspective projection
    projection2.perspective(fov, aspect2, zNear, zFar);
}
//! [5]

void MainWidget::paintGL()
{
    // Clear color and depth buffer
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    texture->bind();

    //texture2->bind();

//! [6]
    // Calculate model view transformation
    QMatrix4x4 matrix;
    matrix.translate(0.0, 0.0, -5.0);
    matrix.rotate(rotation);

    /***
    QMatrix4x4 matrix2;
    matrix2.translate(-1.5, -1.5, -7.0);
    matrix2.rotate(rotation2);
    ***/

    // Set modelview-projection matrix
    program.setUniformValue("mvp_matrix", projection * matrix);

    program2.setUniformValue("mvp_matrix2", projection2 * matrix);
//! [6]

    // Use texture unit 0 which contains cube.png
    program.setUniformValue("texture", 0);

    // Use texture unit 1 which contains cube.jpg
    program2.setUniformValue("texture2", 1);

    // Draw cube geometry
    geometries->drawCubeGeometry(&program);

    texture2->bind();
    geometries->drawCubeGeometry2(&program2);
}

main.cpp

#include <QApplication>
#include <QLabel>
#include <QSurfaceFormat>

#ifndef QT_NO_OPENGL
#include "mainwidget.h"
#endif

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QSurfaceFormat format;
    format.setDepthBufferSize(24);
    QSurfaceFormat::setDefaultFormat(format);

    app.setApplicationName("cube");
    app.setApplicationVersion("0.1");
#ifndef QT_NO_OPENGL
    MainWidget widget;
    widget.show();
#else
    QLabel note("OpenGL Support required");
    note.show();
#endif
    return app.exec();
}

代码效果如下,图像可旋转:

 如有疑问,请您留言或者私信,谢谢阅读。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

potato_potato_123

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值