开发环境:Qt5.15.2,OpenGL4.5核心模式(OpenGL有核心模式和立即模式)

前言

OpenGL开发环境搭建中,使用OpenGL时,需要引入GLAD、GLFW、GLM库。但是在Qt中,内置了对OpenGL的支持。

在屏幕中央绘制一个三角形

  1. CMAKE配置如下所示:
cmake_minimum_required(VERSION 3.12)

project(test VERSION 1.0 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)

# 设置源文件编码为UTF-8
if(MSVC)
    add_compile_options(/utf-8)
   
endif()

find_package(Qt5 REQUIRED COMPONENTS Core Widgets OpenGL REQUIRED)

file(GLOB sources  *.cpp)
# 资源文件
file(GLOB RESOURCE_FILES
    "${CMAKE_SOURCE_DIR}/*.qrc"
)

add_executable(${PROJECT_NAME}  ${sources} ${RESOURCE_FILES})

target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Core Qt5::Widgets Qt5::OpenGL)


  1. 应用程序主窗口如下所示:
#pragma once

#include <QMainWindow>

class MainWindow  : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget*parent = nullptr);
    ~MainWindow();
};

#include "MainWindow.h"
#include "OpenGLWidget.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    setCentralWidget(new OpenGLWidget());
}

MainWindow::~MainWindow()
{}
  1. 自定义OpenGLWidget类继承自QOpenGLWidget及QOpenGLFunctions_4_5_Core
#pragma once

#include <QOpenGLWidget>
//#include <QOpenGLFunctions_3_3_Core>
#include <QOpenGLFunctions_4_5_Core>
#include <QOpenGLShaderProgram>
#include <QOpenGLBuffer>            // VBO
#include <QOpenGLVertexArrayObject> // VAO

class OpenGLWidget  : public QOpenGLWidget, private QOpenGLFunctions_4_5_Core
{
    Q_OBJECT

public:
    OpenGLWidget(QWidget *parent = nullptr);
    ~OpenGLWidget();

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

    void getVersionInfo();
private:
    QOpenGLShaderProgram* m_program;
    QOpenGLBuffer m_vbo;
    QOpenGLVertexArrayObject m_vao;
};

#include "OpenGLWidget.h"

#include <QDebug>

OpenGLWidget::OpenGLWidget(QWidget *parent)
    : QOpenGLWidget(parent)
{
    QSurfaceFormat format;
    format.setVersion(4, 5);  // 明确要求 4.5
    format.setProfile(QSurfaceFormat::CoreProfile);
    setFormat(format);
}

OpenGLWidget::~OpenGLWidget()
{
    // 清理资源
    if (m_vao.isCreated()) {
        m_vao.destroy();
    }
    if (m_vbo.isCreated()) {
        m_vbo.destroy();
    }
    
}

void OpenGLWidget::getVersionInfo() {
    // 获取 OpenGL 版本信息
    QString versionString = QString::fromUtf8((const char*)glGetString(GL_VERSION));
    QString vendorString = QString::fromUtf8((const char*)glGetString(GL_VENDOR));
    QString rendererString = QString::fromUtf8((const char*)glGetString(GL_RENDERER));
    QString glslVersionString = QString::fromUtf8((const char*)glGetString(GL_SHADING_LANGUAGE_VERSION));

    // === OpenGL 信息 ===
    //版本: "4.5.0 NVIDIA 531.41"
    //供应商 : "NVIDIA Corporation"
    //渲染器 : "NVIDIA GeForce RTX 4060 Laptop GPU/PCIe/SSE2"
    //GLSL版本 : "4.50 NVIDIA"
    //主版本 : 4 次版本 : 5

    qDebug() << "=== OpenGL 信息 ===";
    qDebug() << "版本:" << versionString;
    qDebug() << "供应商:" << vendorString;
    qDebug() << "渲染器:" << rendererString;
    qDebug() << "GLSL版本:" << glslVersionString;

    // 也可以使用现代方式获取版本号
    GLint major, minor;
    glGetIntegerv(GL_MAJOR_VERSION, &major);
    glGetIntegerv(GL_MINOR_VERSION, &minor);
    qDebug() << "主版本:" << major << "次版本:" << minor;

}
void OpenGLWidget::initializeGL() {
    initializeOpenGLFunctions();

    getVersionInfo();

    // 设置清屏颜色
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

    // 创建着色器程序
    m_program = new QOpenGLShaderProgram(this);

    m_program->addShaderFromSourceFile(QOpenGLShader::Vertex,
        ":/shaders/vertex.vert");
    m_program->addShaderFromSourceFile(QOpenGLShader::Fragment,
        ":/shaders/fragment.frag");
    m_program->link();

    // 顶点数据
    const float vertices[] = {
        -0.5f, -0.5f, 0.0f,
         0.5f, -0.5f, 0.0f,
         0.0f,  0.5f, 0.0f
    };

    // 创建和管理 VAO
    m_vao.create();
    m_vao.bind();

    // 创建和配置 VBO
    m_vbo.create();
    m_vbo.bind();
    m_vbo.allocate(vertices, sizeof(vertices));
    
    m_program->bind();
    m_program->enableAttributeArray(0);
    m_program->setAttributeBuffer(0, GL_FLOAT, 0, 3, 3 * sizeof(float));
    m_program->release();

    m_vao.release();
    m_vbo.release();
}

void OpenGLWidget::resizeGL(int w, int h)
{
    glViewport(0, 0, w, h);
}

void OpenGLWidget::paintGL() {
    glClear(GL_COLOR_BUFFER_BIT);

    m_program->bind();
    m_vao.bind();
   
    // 绘制三角形
    glDrawArrays(GL_TRIANGLES, 0, 3);

    m_vao.release();
    m_program->release();
}
  1. 创建vertex.vert及fragment.frag,并将其加入到Qt的资源文件中
// vertex.vert如下所示:
#version 450 core
layout (location = 0) in vec3 aPos;
void main() {
    gl_Position = vec4(aPos, 1.0);
}


// fragment.frag如下所示:
#version 450 core
out vec4 FragColor;
void main() {
    FragColor = vec4(0.0, 0.0, 1.0, 1.0);
}
  1. 程序运行结果如下所示:
    image