- 步骤
1. VS中创建Qt Widgets Application工程,继承自QWidget类
2. 设置工程属性,添加QT模块opengl
3. 双击ui文件跳转到QT设计师界面,拖入一个OpenGL Widget控件
4. 在右侧的对象查看器中右键上一步添加的控件,提升为,设置类名、添加、提升
5. 回到VS工具栏的 项目,选择 Add Qt Class... 设置类名(复制上一步的类名),继承自QOpenGLWidget
6. 编辑刚刚的类,使其也继承自QOpenGLFunctions,添加三个需要重载的函数
void initializeGL();//初始化gl
void paintGL();//刷新显示
void resizeGL(int width, int height);//窗口尺寸变化
7. 添加私有成员QGLShaderProgram program;用于调用shader代码
8. 调试、运行
- 代码
1. 新建类的头文件
#pragma once
#include <QOpenGLWidget>
#include <QOpenGLFunctions>
#include <QGLShaderProgram.h>
class XVideoWidget : public QOpenGLWidget, protected QOpenGLFunctions
{
Q_OBJECT
public:
XVideoWidget(QWidget *parent);
~XVideoWidget();
//重载使用的参数
protected:
//初始化gl
void initializeGL();
//刷新显示
void paintGL();
//窗口尺寸变化
void resizeGL(int width, int height);
private:
//shader程序
QGLShaderProgram program;
};
2. 新建类的源文件
#include "XVideoWidget.h"
#include <QDebug.h>
//自动加双引号
#define GET_STR(x) #x
//顶点shader脚本
const char *vString = GET_STR(
attribute vec4 vertexIn;
attribute vec2 textureIn;
varying vec2 textureOut;
void main(void)
{
gl_Position = vertexIn;
textureOut = textureIn;
}
);
//片元shader脚本
//注意必须在字符文本的最前边加上版本:#version 430 core \n 不然会提示语法错误
const char *tString = GET_STR(
#version 430 core \n
varying vec2 textureOut;
uniform sampler2D tex_y;
uniform sampler2D tex_u;
uniform sampler2D tex_v;
void main(void)
{
vec3 yuv;
vec3 rgb;
yuv.x = texture2D(tex_y, textureOut).r;
yuv.y = texture2D(tex_u, textureOut).r - 0.5;
yuv.z = texture2D(tex_v, textureOut).r - 0.5;
rgb = mat3(1.0, 1.0, 1.0,
0.0, -0.39465, 2.03211,
1.13983, -0.58060, 0.0) * yuv;
gl_FragColor = vec4(rgb, 1.0);
}
);
/*** 这种方式也可以
const char *tString =
"#version 430 core \n"
"varying vec2 textureOut;"
"uniform sampler2D tex_y;"
"uniform sampler2D tex_u;"
"uniform sampler2D tex_v;"
"void main(void)"
"{"
"vec3 yuv;"
"vec3 rgb;"
"yuv.x = texture2D(tex_y, textureOut).r;"
"yuv.y = texture2D(tex_u, textureOut).r - 0.5;"
"yuv.z = texture2D(tex_v, textureOut).r - 0.5;"
"rgb = mat3(1.0, 1.0, 1.0,0.0, -0.39465, 2.03211,1.13983, -0.58060, 0.0) * yuv;"
"gl_FragColor = vec4(rgb, 1.0);"
"}";
*/
//准备yuv数据
// 时长10秒 大小240*128 图片格式yuv420p
// ffmpeg -i abc.mp4 -t 10 -s 240x128 -pix_fmt yuv420p out240x128.yuv
XVideoWidget::XVideoWidget(QWidget *parent)
: QOpenGLWidget(parent)
{
}
XVideoWidget::~XVideoWidget()
{
}
//初始化gl
void XVideoWidget::initializeGL()
{
qDebug() << "initializeGL";
//初始化OpenGL(QOpenGLFunctions继承)函数
initializeOpenGLFunctions();
//打印版本
char ver[20] = { 0 };
snprintf(ver, 20, "%s", glGetString(GL_SHADING_LANGUAGE_VERSION));
qDebug() << ver;
//program加载shader(顶点、片元)脚本
//片元
qDebug() << program.addShaderFromSourceCode(QGLShader::Fragment, tString);
//顶点
qDebug() << program.addShaderFromSourceCode(QGLShader::Vertex, vString);
}
//刷新显示
void XVideoWidget::paintGL()
{
qDebug() << "paintGL";
}
//窗口尺寸变化
void XVideoWidget::resizeGL(int width, int height)
{
qDebug() << "resizeGL ( " << width << "," << height << " )";
}