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

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

基于QOpenGLWidget自适应大小显示图片_第1张图片

部分代码如下:

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

 

#ifndef MYGLWIDGET_H

#define MYGLWIDGET_H

 

 

#include

#include

#include

#include

#include

#include

#include

#include

#include

 

 

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(QImage image);

    void initTextures();

    void initShaders();

private:

    QVector vertices;

    QVector texCoords;

    QOpenGLShaderProgram program;

    QOpenGLTexture *texture;

    QImage m_image;

    QMatrix4x4 projection;

};

#endif // MYGLWIDGET_H

 

/////////////////////////////////////////////////////

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

 

#include "myglwidget.h"

#include

#include

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

{}

void MyGLWidget::initTextures()

{

    if(m_image.isNull())   

    {

       qDebug("Cannot open the image...");       

      QImage dummy(128, 128, QImage::Format_RGB32);//当没找到所需打开的图片时,创建一副128*128大小,深度为32位的位图

       dummy.fill(Qt::green);       

       m_image = dummy;

    }    

   // 加载 Avengers.jpg 图片

    texture = new QOpenGLTexture(m_image);

 

    // 设置最近的过滤模式,以缩小纹理  

   texture->setMinificationFilter(QOpenGLTexture::Nearest); //滤波

    // 设置双线性过滤模式,以放大纹理

    texture->setMagnificationFilter(QOpenGLTexture::Linear);

 

    //重复使用纹理坐标    

    //纹理坐标(1.1, 1.2)与(0.1, 0.2)相同

    texture->setWrapMode(QOpenGLTexture::Repeat);

}

 

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_CULL_FACE);

    glEnable(GL_TEXTURE_2D);   

     initTextures();

    initShaders();

 

}

 

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(aspect), zNear, zFar);

 

}

 

void MyGLWidget::paintGL()

{

 

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清除屏幕缓存和深度缓冲    

    texture->bind();                                    //绑定纹理

    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);    

   glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

 

}

 

void MyGLWidget::setBackground(QImage image)

{    

    m_image = image;

    update();

}

源码下载:https://download.csdn.net/download/yl409519139/10885493;

你可能感兴趣的:(基于QOpenGLWidget自适应大小显示图片)