一直想用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下载。