Qt5与现代OpenGL学习(十)OpenGL Widget画旋转的直线

发布于:2025-05-14 ⋅ 阅读:(11) ⋅ 点赞:(0)

请添加图片描述
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


网站公告

今日签到

点亮在社区的每一天
去签到