当前位置: 首页 > article >正文

Qt QOpenGLFunctions详解

1. 概述

QOpenGLFunctions 是 Qt 提供的一个工具类,用于封装 OpenGL 的函数调用。它使得在 Qt 应用程序中使用 OpenGL 更加方便和安全,同时提供了跨平台的兼容性。通过继承 QOpenGLFunctions,开发者可以轻松地访问 OpenGL 的核心功能,而无需直接调用原生的 OpenGL API。

QOpenGLFunctions 提供了大量封装的 OpenGL 函数,这些函数与 OpenGL 的原生函数一一对应,但通过 Qt 的方式进行了封装,使得代码更加简洁和易于管理。此外,QOpenGLFunctions 还提供了一些辅助功能,例如检查 OpenGL 功能是否可用。

2. 重要函数

以下是 QOpenGLFunctions 中一些常用的重要函数,这些函数覆盖了 OpenGL 的核心功能:

纹理相关
  • glActiveTexture(GLenum texture)
    激活指定的纹理单元。

  • glBindTexture(GLenum target, GLuint texture)
    绑定一个纹理对象到指定的目标。

  • glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels)
    定义二维纹理图像。

  • glTexParameteri(GLenum target, GLenum pname, GLint param)
    设置纹理参数。

着色器相关
  • glCreateProgram()
    创建一个新的着色器程序。

  • glCreateShader(GLenum type)
    创建一个新的着色器对象。

  • glAttachShader(GLuint program, GLuint shader)
    将着色器对象附加到着色器程序。

  • glCompileShader(GLuint shader)
    编译着色器对象。

  • glLinkProgram(GLuint program)
    链接着色器程序。

  • glUseProgram(GLuint program)
    使用指定的着色器程序。

缓冲区相关
  • glGenBuffers(GLsizei n, GLuint* buffers)
    生成一个或多个缓冲对象。

  • glBindBuffer(GLenum target, GLuint buffer)
    绑定一个缓冲对象到指定的目标。

  • glBufferData(GLenum target, GLsizeiptr size, const void* data, GLenum usage)
    设置缓冲对象的数据。

渲染相关
  • glClear(GLbitfield mask)
    清除颜色、深度或模板缓冲区。

  • glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
    设置清除颜色缓冲区时使用的颜色。

  • glDrawArrays(GLenum mode, GLint first, GLsizei count)
    使用当前的顶点数组渲染几何图元。

  • glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
    使用顶点数组和索引数组渲染几何图元。

状态查询
  • glGetError()
    获取当前的 OpenGL 错误状态。

  • glGetProgramiv(GLuint program, GLenum pname, GLint* params)
    获取着色器程序的参数。

  • glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
    获取着色器对象的参数。

  • glGetUniformLocation(GLuint program, const char* name)
    获取着色器程序中统一变量的位置。

class MyGLWidget : public QOpenGLWidget, protected QOpenGLFunctions
{
    Q_OBJECT

public:
    MyGLWidget(QWidget *parent = nullptr) : QOpenGLWidget(parent) {}

protected:
    void initializeGL() override
    {
        initializeOpenGLFunctions(); // 初始化 OpenGL 函数

        // 创建着色器程序
        program = new QOpenGLShaderProgram(this);
        if (!program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource))
            qFatal("Vertex shader failed");
        if (!program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource))
            qFatal("Fragment shader failed");
        if (!program->link())
            qFatal("Shader program linking failed");

        // 设置顶点数据
        vertices = { -0.5f, -0.5f, 0.0f,
                      0.5f, -0.5f, 0.0f,
                      0.0f,  0.5f, 0.0f };
        glGenBuffers(1, &vbo);
        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), vertices.data(), GL_STATIC_DRAW);
    }

    void paintGL() override
    {
        glClear(GL_COLOR_BUFFER_BIT); // 清除颜色缓冲区

        // 使用着色器程序
        program->bind();

        // 设置顶点属性
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
        glEnableVertexAttribArray(0);

        // 绘制三角形
        glDrawArrays(GL_TRIANGLES, 0, 3);

        // 释放资源
        glDisableVertexAttribArray(0);
        program->release();
    }

    void resizeGL(int w, int h) override
    {
        glViewport(0, 0, w, h); // 设置视口大小
    }

private:
    QOpenGLShaderProgram *program;
    std::vector<float> vertices;
    GLuint vbo;

    const char *vertexShaderSource = R"(
        #version 330 core
        layout (location = 0) in vec3 aPos;
        void main()
        {
            gl_Position = vec4(aPos, 1.0);
        }
    )";

    const char *fragmentShaderSource = R"(
        #version 330 core
        out vec4 FragColor;
        void main()
        {
            FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
        }
    )";
};

觉得有帮助的话,打赏一下呗。。

           

需要商务合作(定制程序)的欢迎私信!! 


http://www.kler.cn/a/542953.html

相关文章:

  • 【vs2022配置cursor】
  • Java多线程——线程池的使用
  • 关于“#pragma arm section zidata = “mgr_buffer_section“的解析
  • 接口测试Day12-持续集成、git简介和安装、Gitee远程仓库、jenkins集成
  • soular基础教程-使用指南
  • (1/100)每日小游戏平台系列
  • AF3 drmsd函数解读
  • .Net使用EF Core框架如何连接Oracle
  • JVM-Java虚拟机
  • 在postman中设置环境变量和全局变量以及五大常用响应体断言
  • 【C#零基础从入门到精通】(十四)——面向对象三大特征C#封装详解
  • 二叉树、平衡二叉树、B树与B+树的区别与应用
  • redis的数据结构介绍(string
  • 心脏滴血漏洞复现(CVE-2014-0160)
  • 备战蓝桥杯:双指针(滑动窗口)算法之逛花展
  • SpringBoot分布式开发依赖项中,除了myql、redis,都要哪些依赖项是需要本地安装软件并开启服务的?
  • 蓝桥杯---N字形变换(leetcode第6题)题解
  • IDEA中列举的是否是SpringBoot的依赖项的全部?在哪里能查到所有依赖项,如何开发自己的依赖项让别人使用
  • Django:构建高效Web应用的强大框架
  • Idea集成deepseek生成代码
  • ffmpeg -hwaccels
  • 用 TDD 构建 Rust 命令行搜索功能:以 minigrep 为例
  • 3D文档控件Aspose.3D实用教程: 在 Java 中创建 FBX 文件并无缝将圆柱体转换为网格
  • 企业数据集成案例:吉客云销售渠道到MySQL
  • 率失真理论(Rate-Distortion Theory)和信息瓶颈(Information Bottleneck, IB)
  • Flutter_学习记录_安装第三方包(演示安装 Intl 包)