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();
}
代码效果如下,图像可旋转:
如有疑问,请您留言或者私信,谢谢阅读。