基于QOpenGLWidget自适应大小更新显示图片

一直想用OpenGL来显示图像或者做视频播放器的窗口,网上找了很久,都没有Qt这方面最新的靠谱的例子,大部分都是3D模型上贴图,要不就是各种报错,或者Qt的OpenGL版本不对,自己摸索了好久,终于搞定了,是在QT5.12.7MSVC2017下编译的,可自适应窗口大小

注:之前代码版本有bug,图像不刷新,新的代码已经更新,当然可能还有BUG(哈哈哈),欢迎指出

部分代码如下:

//-----MyGLWidget.h------

#ifndef MYGLWIDGET_H
#define MYGLWIDGET_H

#include <QObject>
#include <QOpenGLWidget>
#include <GL/gl.h>
#include <GL/glu.h>
#include <QOpenGLFunctions>
#include <QOpenGLShaderProgram>
#include <QOpenGLTexture>
#include <QGLWidget>
#include <QImage>

class MyGLWidget : public QOpenGLWidget, protected QOpenGLFunctions
{
    Q_OBJECT
public:
    explicit MyGLWidget(QWidget *parent = 0);
signals:
public slots:
    void initializeGL() Q_DECL_OVERRIDE;

    void resizeGL(int w, int h) Q_DECL_OVERRIDE;

    void paintGL() Q_DECL_OVERRIDE;

    void setBackground(const QImage &image);

    void initTextures();

    void initShaders();
private:

    QVector<QVector3D> vertices;

    QVector<QVector2D> texCoords;

    QOpenGLShaderProgram program;

    QOpenGLTexture *texture;

    QMatrix4x4 projection;
};

#endif // MYGLWIDGET_H

//-------MyGLWidget.cpp--------

#include "myglwidget.h"
#include <QDebug>
#include <QGraphicsOpacityEffect>
MyGLWidget::MyGLWidget(QWidget *parent) : QOpenGLWidget(parent)
{
}

void MyGLWidget::initTextures()
{
   // 加载 Avengers.jpg 图片
   texture = new QOpenGLTexture(QOpenGLTexture::Target2D);
   // 设置最近的过滤模式,以缩小纹理  
   texture->setMinificationFilter(QOpenGLTexture::LinearMipMapLinear); //滤波
   // 设置双线性过滤模式,以放大纹理
   texture->setMagnificationFilter(QOpenGLTexture::Linear);
   // 重复使用纹理坐标    
   // 纹理坐标(1.1, 1.2)与(0.1, 0.2)相同
   texture->setWrapMode(QOpenGLTexture::Repeat);
   //设置纹理大小
   texture->setSize(this->width(), this->height());
   //分配储存空间
   texture->allocateStorage();
}

void MyGLWidget::initShaders()
{
    //纹理坐标   
    texCoords.append(QVector2D(0, 1)); //左上
    texCoords.append(QVector2D(1, 1)); //右上    
    texCoords.append(QVector2D(0, 0)); //左下
    texCoords.append(QVector2D(1, 0)); //右下   

    //顶点坐标
    vertices.append(QVector3D(-1, -1, 1));//左下   
    vertices.append(QVector3D(1, -1, 1)); //右下
    vertices.append(QVector3D(-1, 1, 1)); //左上    
    vertices.append(QVector3D(1, 1, 1));  //右上
    QOpenGLShader *vshader = new QOpenGLShader(QOpenGLShader::Vertex, this);    
    const char *vsrc =
            "attribute vec4 vertex;\n"    
           "attribute vec2 texCoord;\n"
            "varying vec2 texc;\n"     
            "void main(void)\n"
            "{\n"           
            "    gl_Position = vertex;\n"
            "    texc = texCoord;\n"         
             "}\n";
    vshader->compileSourceCode(vsrc);//编译顶点着色器代码
    QOpenGLShader *fshader = new QOpenGLShader(QOpenGLShader::Fragment, this);    
    const char *fsrc =
            "uniform sampler2D texture;\n"            
            "varying vec2 texc;\n"
            "void main(void)\n"           
            "{\n"
            "    gl_FragColor = texture2D(texture,texc);\n"           
            "}\n";
    fshader->compileSourceCode(fsrc); //编译纹理着色器代码
    program.addShader(vshader);       //添加顶点着色器    
    program.addShader(fshader);       //添加纹理碎片着色器
    program.bindAttributeLocation("vertex", 0);  //绑定顶点属性位置    
    program.bindAttributeLocation("texCoord", 1);//绑定纹理属性位置
    // 链接着色器管道  
   if (!program.link())
        close();   
   // 绑定着色器管道
    if (!program.bind())        
        close();
}

void MyGLWidget::initializeGL()
{   
    initializeOpenGLFunctions(); //初始化OPenGL功能函数
    glClearColor(0, 0, 0, 0);    //设置背景为黑色    
    glEnable(GL_TEXTURE_2D);     //设置纹理2D功能可用
    initTextures();              //初始化纹理设置
    initShaders();               //初始化shaders
}


void MyGLWidget::resizeGL(int w, int h)
{
    // 计算窗口横纵比   
    qreal aspect = qreal(w) / qreal(h ? h : 1);
    // 设置近平面值 3.0, 远平面值 7.0, 视场45度    
    const qreal zNear = 3.0, zFar = 7.0, fov = 45.0;
    // 重设投影  
    projection.setToIdentity();
    // 设置透视投影  
    projection.perspective(fov, static_cast<float>(aspect), zNear, zFar);
}

void MyGLWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清除屏幕缓存和深度缓冲    
    QMatrix4x4 matrix;  
    matrix.translate(0.0, 0.0, -5.0);                   //矩阵变换
    program.enableAttributeArray(0);    
    program.enableAttributeArray(1);
    program.setAttributeArray(0, vertices.constData());    
    program.setAttributeArray(1, texCoords.constData());
    program.setUniformValue("texture", 0);    
    texture->bind();  //绑定纹理
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);//绘制纹理
    texture->release(); //释放绑定的纹理
    texture->destroy(); //消耗底层的纹理对象
    texture->create();  //重新创建纹理对象
}

void MyGLWidget::setBackground(const QImage &image)
{    
    texture->setData(image); //设置纹理图像
    //设置纹理细节
    texture->setLevelofDetailBias(-1);//值越小,图像越清晰
    //更新图像
    update();
}

修复版源码下载:基于QOpenGLWidget类的图片贴图自适应更新显示Demo_qt基于QOpenGLWidget显示图片-图像处理文档类资源-CSDN下载

  • 7
    点赞
  • 58
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

逆天の诸葛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值