glwidget.h
#ifndef GLWIDGET_H
#define GLWIDGET_H
#include <QOpenGLWidget>
#include <QOpenGLFunctions>
#include <QOpenGLShaderProgram>
#include <QMatrix4x4>
class GLWidget : public QOpenGLWidget, protected QOpenGLFunctions
{
Q_OBJECT
public:
explicit GLWidget(QWidget *parent = nullptr);
~GLWidget() override;
protected:
void initializeGL() override;
void resizeGL(int w, int h) override;
void paintGL() override;
private:
void initShaders();
QOpenGLShaderProgram shaderProgram;
QMatrix4x4 projection;
QMatrix4x4 view;
QMatrix4x4 model;
float rotationAngle = 0.0f;
};
#endif // GLWIDGET_H
glwidget.cpp
#include "glwidget.h"
#include "QTimer"
GLWidget::GLWidget(QWidget *parent) : QOpenGLWidget(parent)
{
// 设置自动更新,实现旋转动画
QTimer *timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, [this](){
rotationAngle += 0.5f;
if(rotationAngle >= 360.0f) rotationAngle = 0.0f;
update();
});
timer->start(16); // 约60FPS
}
GLWidget::~GLWidget()
{
makeCurrent();
doneCurrent();
}
void GLWidget::initializeGL()
{
initializeOpenGLFunctions();
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glEnable(GL_DEPTH_TEST);
initShaders();
}
void GLWidget::resizeGL(int w, int h)
{
glViewport(0, 0, w, h);
projection.setToIdentity();
projection.perspective(45.0f, (float)w/(float)h, 0.1f, 100.0f);
view.setToIdentity();
view.translate(0.0f, 0.0f, -5.0f);
}
void GLWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
model.setToIdentity();
model.rotate(rotationAngle, 0.0f, 1.0f, 0.0f);
QMatrix4x4 mvp = projection * view * model;
shaderProgram.bind();
shaderProgram.setUniformValue("mvpMatrix", mvp);
GLfloat vertices[] = {
-0.2f, 0.3f, 0.5f, // p1
1.0f, 1.0f, 1.0f // p2
};
GLfloat colors[] = {
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f
};
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertices);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, colors);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glDrawArrays(GL_LINES, 0, 2);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
shaderProgram.release();
}
void GLWidget::initShaders()
{
const char *vertexShaderSource =
"#version 330 core\n"
"layout(location = 0) in vec3 position;\n"
"layout(location = 1) in vec3 color;\n"
"uniform mat4 mvpMatrix;\n"
"out vec3 fragColor;\n"
"void main() {\n"
" gl_Position = mvpMatrix * vec4(position, 1.0);\n"
" fragColor = color;\n"
"}\n";
const char *fragmentShaderSource =
"#version 330 core\n"
"in vec3 fragColor;\n"
"out vec4 outColor;\n"
"void main() {\n"
" outColor = vec4(fragColor, 1.0);\n"
"}\n";
shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);
shaderProgram.link();
}
在mainwindow.ui中,添加OpenGLWidget,并提升为:GLWidget