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

qt QOpenGLTexture详解

1. 概述

QOpenGLTexture 是 Qt5 提供的一个类,用于表示和管理 OpenGL 纹理。它封装了 OpenGL 纹理的创建、分配存储、绑定和设置像素数据等操作,简化了 OpenGL 纹理的使用。

2. 重要函数
  • 构造函数

    • QOpenGLTexture(const QImage &image, QOpenGLTexture::MipMapGeneration genMipMaps = GenerateMipMaps)

    • QOpenGLTexture(QOpenGLTexture::Target target)

  • 纹理配置

    • void allocateStorage()

    • void allocateStorage(QOpenGLTexture::PixelFormat pixelFormat, QOpenGLTexture::PixelType pixelType)

    • void setFormat(QOpenGLTexture::TextureFormat format)

    • void setLayers(int layers)

    • void setSize(int width, int height = 1, int depth = 1)

  • 绑定和解绑

    • void bind()

    • void bind(uint unit, QOpenGLTexture::TextureUnitReset reset = DontResetTextureUnit)

    • void release()

    • void release(uint unit, QOpenGLTexture::TextureUnitReset reset = DontResetTextureUnit)

  • 设置像素数据

    • void setData(int mipLevel, QOpenGLTexture::PixelFormat sourceFormat, QOpenGLTexture::PixelType sourceType, const void *data, const QOpenGLPixelTransferOptions *const options = nullptr)

    • void setData(const QImage &image, QOpenGLTexture::MipMapGeneration genMipMaps = GenerateMipMaps)

  • 生成 Mipmaps

    • void generateMipMaps()

    • void generateMipMaps(int baseLevel, bool resetBaseLevel = true)

  • 获取纹理属性

    • int width() const

    • int height() const

    • int depth() const

    • GLuint textureId() const

3. 常用枚举类型
  • BindingTarget:纹理绑定目标,如 BindingTarget2DBindingTargetCubeMap 等。

  • ComparisonFunction:深度和模板比较函数。

  • ComparisonMode:比较模式,如 CompareRefToTexture

  • CubeMapFace:立方体贴图的各个面,如 CubeMapPositiveX

  • DepthStencilMode:深度和模板模式。

  • Feature:纹理特性,如 TextureRectangleTextureArrays

  • Filter:纹理过滤方式,如 NearestLinear

  • MipMapGeneration:是否生成 Mipmaps,GenerateMipMapsDontGenerateMipMaps

  • PixelFormat:像素格式,如 RGBA8888

  • PixelType:像素类型,如 UnsignedByte

  • SwizzleComponent:颜色通道,如 SwizzleRed

  • SwizzleValue:颜色值,如 RedValue

  • Target:纹理目标,如 Target2D

  • TextureFormat:纹理格式,如 RGB8_UNorm

  • WrapMode:纹理环绕模式,如 RepeatClampToEdge

#include "widget.h"

float vertices[] = {
    // positions          // colors           // texture coords
     0.5f,  0.5f, 0.0f,   1.0f, 0.0f, 0.0f,   1.0f, 1.0f, // top right
     0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,   1.0f, 0.0f, // bottom right
    -0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f, // bottom left
    -0.5f,  0.5f, 0.0f,   1.0f, 1.0f, 0.0f,   0.0f, 1.0f  // top left
};
unsigned int indices[] = {
    0, 1, 3, // first triangle
    1, 2, 3  // second triangle
};


MyGLWidget::MyGLWidget(QWidget *parent) : QOpenGLWidget(parent)
{

}

MyGLWidget::~MyGLWidget()
{
    glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &VBO);
    glDeleteBuffers(1, &EBO);
}

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

    bool success;
    m_shaderProgram.addShaderFromSourceFile(QOpenGLShader::Vertex,":/shader/shader.vert");
    m_shaderProgram.addShaderFromSourceFile(QOpenGLShader::Fragment,":/shader/shader.frag");
    success=m_shaderProgram.link();
    if(!success) qDebug()<<"ERR:"<<m_shaderProgram.log();

    //创建、绑定VAO
    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);

    //创建、绑定VBO + 填充数据
    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    //设置顶点属性指针
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    // 颜色属性
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3* sizeof(float)));
    glEnableVertexAttribArray(1);

    //纹理坐标
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
    glEnableVertexAttribArray(2);

    //解绑缓冲区和 VAO
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

    //创建、绑定纹理
    m_diffuseTex = new QOpenGLTexture(QImage(":/img/container.png").mirrored());
    m_specularTex = new QOpenGLTexture(QImage(":/img/awesomeface.png").mirrored());
    m_shaderProgram.bind();
    m_shaderProgram.setUniformValue("texture1", 0);
    m_shaderProgram.setUniformValue("texture2", 1);;
}

void MyGLWidget::paintGL()
{
    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT); // 清除颜色缓冲区

    m_shaderProgram.bind();
    m_diffuseTex->bind(0);
    m_specularTex->bind(1);

    glBindVertexArray(VAO);
    //glDrawArrays(GL_TRIANGLES, 0, 3);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

    glBindVertexArray(0);
}

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

unsigned int MyGLWidget::loadTexture(const char *fileName, bool alpha)
{
    unsigned int texture;
    glGenTextures(1, &texture); // 生成纹理 ID
    glBindTexture(GL_TEXTURE_2D, texture); // 绑定纹理

    // 设置纹理参数
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
#if 0
    // 加载图片并转换为 OpenGL 格式
    QImage image;
    if (!image.load(fileName))
    {
        qWarning() << "Failed to load texture image";
        return 0;
    }
    image = QGLWidget::convertToGLFormat(image); // 转换为 OpenGL 格式
    unsigned char *data = image.bits();
    // 生成纹理
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
    glGenerateMipmap(GL_TEXTURE_2D); // 生成多级渐远纹理
#else

    QFile file(fileName);
    file.copy(file.fileName(), QFileInfo(file).fileName());

    int width, height, nrChannels;
    stbi_set_flip_vertically_on_load(true); // tell stb_image.h to flip loaded texture's on the y-axis.
    unsigned char *data = stbi_load(QFileInfo(file).fileName().toStdString().c_str(), &width, &height, &nrChannels, 0);
    if (data)//awesomeface  container
    {
        if(alpha)
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
        else
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
        glGenerateMipmap(GL_TEXTURE_2D);
    }
    else
    {
        std::cout << "Failed to load texture1" << std::endl;
    }
    stbi_image_free(data);
#endif
    return texture;
}

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

           

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

相关文章:

  • 算法【贪心经典题目专题4】
  • 用AI写SQL2——递归查询WITH RECURSIVE
  • 科技云报到:科技普惠潮流渐起,“开源”将带我们走向何方?
  • 北京海百川科技有限公司:以智能体技术助力特殊教育行业
  • Python中如何进行数据库连接?
  • [题解]2024CCPC重庆站-小 C 的神秘图形
  • 智能马达保护器:为工业电机安全运行保驾护航
  • HepG2细胞复苏实验以及六孔板种植细胞实验
  • JavaEE基础 Tomcat与Http (下)
  • 【Prometheus】prometheus结合domain_exporter实现域名监控
  • 矩阵碰一碰发视频源码源头搭建,支持OEM
  • PLC的五个学习步骤
  • Linux学习笔记之虚拟地址空间
  • Spring 是如何解决循环依赖问题的?
  • Python——寻找矩阵的【鞍点】(教师:恒风)
  • 如何理解什么是股指期货?
  • 【复现DeepSeek-R1之Open R1实战】系列3:跑通GRPO!
  • 访问一些网站时,谷歌浏览器提示403 Forbidden
  • 将pyspark中的UDF提升6倍
  • 从开发到部署:EasyRTC嵌入式视频通话SDK如何简化实时音视频通信的集成与应用
  • 是否进行了及时有效处置?伤者情况如何?辽阳市相关负责人就饭店火灾事故答问
  • “上报集团文化助力区域高质量发展赋能平台”揭牌
  • 人社部:将会同更多部门分行业、分领域制定专项培训计划
  • 洛阳原副市长收礼品消费卡,河南通报6起违反八项规定典型问题
  • 四川:全省统一取消普通住宅和非普通住宅标准
  • 东北财大“一把手”调整:方红星任校党委书记,汪旭晖任校长