先看效果:
参照上一篇文章:Qt OPenGL 光的漫反射
添加一个定时器:
#pragma once
#include <QOpenGLWindow>
#include <QOpenGLExtraFunctions>
#include <QDebug>
#include <QOpenGLTexture>
#include <QElapsedTimer>
#include <QOpenGLShader>
#include <QOpenGLShaderProgram>
class DiffuseLightWnd : public QOpenGLWindow {
Q_OBJECT
public:
DiffuseLightWnd();
~DiffuseLightWnd();
protected:
void initializeGL()override;
void paintGL()override;
void keyPressEvent(QKeyEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void wheelEvent(QWheelEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void resizeGL(int w, int h) Q_DECL_OVERRIDE;
private:
void drawObj();
private slots:
void slotTimeout();
private:
GLuint _VBO, _VAO;
class QOpenGLFunctions_3_3_Core* _openGLCore;
QOpenGLShaderProgram _shaderProgram;//着色器程序,所里系统所有的着色器
QMatrix4x4 model, view, projection;
class DiffuseLightCamera* _diffuseLightCamera = nullptr;
bool _lBtnDown = false;
QPoint _lBtnDownPos;
class QTimer* _timer;
float _rotateModel = 45.0;
};
#include "DiffuseLightWnd.h"
#include <QKeyEvent>
#include <QMouseEvent>
#include <QWheelEvent>
#include <QTimer>
#include <QOpenGLFunctions_3_3_Core>
#include "DiffuseLightCamera.h"
DiffuseLightWnd::DiffuseLightWnd() {
_diffuseLightCamera = new DiffuseLightCamera(QVector3D(0.0, 0.0, -4.0), 0.0, 90.0, QVector3D(0.0, 1.0, 0.0));
_timer = new QTimer;
connect(_timer, SIGNAL(timeout()), this, SLOT(slotTimeout()));
_timer->start(50);
}
DiffuseLightWnd::~DiffuseLightWnd() {
}
void DiffuseLightWnd::initializeGL() {
_openGLCore = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_3_3_Core>();
//开启深度测试
_openGLCore->glEnable(GL_DEPTH_TEST);
_openGLCore->glDepthFunc(GL_LESS);
// 顶点数据(纹理坐标未使用)
float vertices[] = {
// positions // normal vector // texture
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
// 2
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
// 3
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
// 4
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
// 5
-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
// 6
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
};
// 1.创建对象
_openGLCore->glGenVertexArrays(1, &_VAO);
_openGLCore->glGenBuffers(1, &_VBO);
// 2.绑定对象
_openGLCore->glBindVertexArray(_VAO);
_openGLCore->glBindBuffer(GL_ARRAY_BUFFER, _VBO);
// 3.数据存放
_openGLCore->glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// 4.解析数据
_openGLCore->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
_openGLCore->glEnableVertexAttribArray(0);
// 5.顶点法向量
_openGLCore->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
_openGLCore->glEnableVertexAttribArray(1);
// 6.解绑
_openGLCore->glBindBuffer(GL_ARRAY_BUFFER, 0);
_openGLCore->glBindVertexArray(0);
// 7.着色器程序
_shaderProgram.addShaderFromSourceFile(QOpenGLShader::Vertex, "E:/Projects/QtGuiTest/OPenGLApp/DiffuseLight/DiffuseLight.vert");
_shaderProgram.addShaderFromSourceFile(QOpenGLShader::Fragment, "E:/Projects/QtGuiTest/OPenGLApp/DiffuseLight/DiffuseLight.frag");
_shaderProgram.link();
}
void DiffuseLightWnd::paintGL() {
_openGLCore->glClearColor(0.4f, 0.4f, 0.4f, 1.0f);
_openGLCore->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
_openGLCore->glBindVertexArray(_VAO);
drawObj();
update();
}
void DiffuseLightWnd::keyPressEvent(QKeyEvent *event) {
_diffuseLightCamera->keyPress(event->key());
}
void DiffuseLightWnd::mouseMoveEvent(QMouseEvent *event) {
if (_lBtnDown) {
float xpos = static_cast<float>(event->pos().x());
float ypos = static_cast<float>(event->pos().y());
float xoffset = _lBtnDownPos.x() - xpos;
float yoffset = _lBtnDownPos.y() - ypos;
_lBtnDownPos = event->pos();
_diffuseLightCamera->mouseMove(xoffset, yoffset);
}
}
void DiffuseLightWnd::wheelEvent(QWheelEvent *event) {
_diffuseLightCamera->wheel(event->delta());
update();
}
void DiffuseLightWnd::mousePressEvent(QMouseEvent *event) {
if (event->button() == Qt::LeftButton) {
_lBtnDown = true;
_lBtnDownPos = event->pos();
}
}
void DiffuseLightWnd::mouseReleaseEvent(QMouseEvent *event) {
if (event->button() == Qt::LeftButton) {
_lBtnDown = false;
}
}
void DiffuseLightWnd::resizeGL(int w, int h) {
glViewport(0, 0, w, h);
}
void DiffuseLightWnd::drawObj() {
_shaderProgram.bind();
QMatrix4x4 model;
model.rotate(_rotateModel, QVector3D(1.0, 1.0, 1.0));
model.scale(0.5);
QMatrix4x4 view = _diffuseLightCamera->getViewMatrix();
QMatrix4x4 projection;
projection.perspective(_diffuseLightCamera->getZoom(), width() / height(), 0.1, 100);
_shaderProgram.setUniformValue("model", model);
_shaderProgram.setUniformValue("view", view);
_shaderProgram.setUniformValue("projection", projection);
_shaderProgram.setUniformValue("objectColor", 1.0f, 0.5f, 0.31f);
_shaderProgram.setUniformValue("lightColor", 1.0f, 1.0f, 1.0f);
_shaderProgram.setUniformValue("lightPos", 0.0f, 0.0f, -4.0f);
_openGLCore->glDrawArrays(GL_TRIANGLES, 0, 36);
}
void DiffuseLightWnd::slotTimeout() {
_rotateModel++;
}
aaa