Qt 使用openGL 渲染YUV420P格式的视频
代码如下
YUV420P_Render.h
#ifndef YUV420P_RENDER_H
#define YUV420P_RENDER_H #include <QObject>
#include <QOpenGLWidget>
#include <QOpenGLFunctions>
#include <QOpenGLShaderProgram>
class YUV420P_Render: protected QOpenGLFunctions
{ public:
YUV420P_Render();
~YUV420P_Render(); //初始化gl
void initialize();
//刷新显示
void render(uchar* py,uchar* pu,uchar* pv,int width,int height,int type);
void render(uchar* ptr,int width,int height,int type); private:
//shader程序
QOpenGLShaderProgram m_program;
//shader中yuv变量地址
GLuint m_textureUniformY, m_textureUniformU , m_textureUniformV;
//创建纹理
GLuint m_idy , m_idu , m_idv; }; #endif // YUV420P_RENDER_H
YUV420P_Render.cpp
#include "YUV420P_Render.h"
#include <QDebug>
#include <QTimer> #define ATTRIB_VERTEX 0
#define ATTRIB_TEXTURE 1 YUV420P_Render::YUV420P_Render()
{
} YUV420P_Render::~YUV420P_Render()
{
} //初始化gl
void YUV420P_Render::initialize()
{
qDebug() << "initializeGL"; //初始化opengl (QOpenGLFunctions继承)函数
initializeOpenGLFunctions(); //顶点shader
const char *vString =
"attribute vec4 vertexPosition;\
attribute vec2 textureCoordinate;\
varying vec2 texture_Out;\
void main(void)\
{\
gl_Position = vertexPosition;\
texture_Out = textureCoordinate;\
}";
//片元shader
const char *tString =
"varying vec2 texture_Out;\
uniform sampler2D tex_y;\
uniform sampler2D tex_u;\
uniform sampler2D tex_v;\
void main(void)\
{\
vec3 YUV;\
vec3 RGB;\
YUV.x = texture2D(tex_y, texture_Out).r;\
YUV.y = texture2D(tex_u, texture_Out).r - 0.5;\
YUV.z = texture2D(tex_v, texture_Out).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);\
}"; //m_program加载shader(顶点和片元)脚本
//片元(像素)
qDebug()<<m_program.addShaderFromSourceCode(QOpenGLShader::Fragment, tString);
//顶点shader
qDebug() << m_program.addShaderFromSourceCode(QOpenGLShader::Vertex, vString); //设置顶点位置
m_program.bindAttributeLocation("vertexPosition",ATTRIB_VERTEX);
//设置纹理位置
m_program.bindAttributeLocation("textureCoordinate",ATTRIB_TEXTURE); //编译shader
qDebug() << "m_program.link() = " << m_program.link(); qDebug() << "m_program.bind() = " << m_program.bind(); //传递顶点和纹理坐标
//顶点
static const GLfloat ver[] = {
-1.0f,-1.0f,
1.0f,-1.0f,
-1.0f, 1.0f,
1.0f,1.0f
// -1.0f,-1.0f,
// 0.9f,-1.0f,
// -1.0f, 1.0f,
// 0.9f,1.0f
};
//纹理
static const GLfloat tex[] = {
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f
}; //设置顶点,纹理数组并启用
glVertexAttribPointer(ATTRIB_VERTEX, , GL_FLOAT, , , ver);
glEnableVertexAttribArray(ATTRIB_VERTEX);
glVertexAttribPointer(ATTRIB_TEXTURE, , GL_FLOAT, , , tex);
glEnableVertexAttribArray(ATTRIB_TEXTURE); //从shader获取地址
m_textureUniformY = m_program.uniformLocation("tex_y");
m_textureUniformU = m_program.uniformLocation("tex_u");
m_textureUniformV = m_program.uniformLocation("tex_v"); //创建纹理
glGenTextures(, &m_idy);
//Y
glBindTexture(GL_TEXTURE_2D, m_idy);
//放大过滤,线性插值 GL_NEAREST(效率高,但马赛克严重)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //U
glGenTextures(, &m_idu);
glBindTexture(GL_TEXTURE_2D, m_idu);
//放大过滤,线性插值
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //V
glGenTextures(, &m_idv);
glBindTexture(GL_TEXTURE_2D, m_idv);
//放大过滤,线性插值
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT); } //刷新显示
void YUV420P_Render::render(uchar* py,uchar* pu,uchar* pv,int width,int height,int type)
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_idy);
//修改纹理内容(复制内存内容)
glTexImage2D(GL_TEXTURE_2D, , GL_RED, width, height, , GL_RED, GL_UNSIGNED_BYTE,py);
//与shader 关联
glUniform1i(m_textureUniformY, ); glActiveTexture(GL_TEXTURE0+);
glBindTexture(GL_TEXTURE_2D, m_idu);
//修改纹理内容(复制内存内容)
glTexImage2D(GL_TEXTURE_2D, , GL_RED, width/, height/, , GL_RED, GL_UNSIGNED_BYTE, pu);
//与shader 关联
glUniform1i(m_textureUniformU,); glActiveTexture(GL_TEXTURE0+);
glBindTexture(GL_TEXTURE_2D, m_idv);
//修改纹理内容(复制内存内容)
glTexImage2D(GL_TEXTURE_2D, , GL_RED, width/, height/, , GL_RED, GL_UNSIGNED_BYTE, pv);
//与shader 关联
glUniform1i(m_textureUniformV, ); glDrawArrays(GL_TRIANGLE_STRIP,,);
qDebug() << "paintGL";
} void YUV420P_Render::render(uchar* ptr,int width,int height,int type)
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_idy);
//修改纹理内容(复制内存内容)
glTexImage2D(GL_TEXTURE_2D, , GL_RED, width, height, , GL_RED, GL_UNSIGNED_BYTE,ptr);
//与shader 关联
glUniform1i(m_textureUniformY, ); glActiveTexture(GL_TEXTURE0+);
glBindTexture(GL_TEXTURE_2D, m_idu);
//修改纹理内容(复制内存内容)
glTexImage2D(GL_TEXTURE_2D, , GL_RED, width/, height/, , GL_RED, GL_UNSIGNED_BYTE, ptr+width*height);
//与shader 关联
glUniform1i(m_textureUniformU,); glActiveTexture(GL_TEXTURE0+);
glBindTexture(GL_TEXTURE_2D, m_idv);
//修改纹理内容(复制内存内容)
glTexImage2D(GL_TEXTURE_2D, , GL_RED, width/, height/, , GL_RED, GL_UNSIGNED_BYTE, ptr+width*height*/);
//与shader 关联
glUniform1i(m_textureUniformV, ); glDrawArrays(GL_TRIANGLE_STRIP,,);
qDebug() << "paintGL";
}
最后写一个窗口类继承 QOpenGLWidget
重写两个函数
void initializeGL(); //调用上面渲染类的初始化函数
void paintGL();//调用上面渲染类的渲染函数
Qt 使用openGL 渲染YUV420P格式的视频的更多相关文章
- Qt 使用openGL 渲染NV12格式的视频
直接上代码 Nv12Render.h #ifndef NV12RENDER_H #define NV12RENDER_H #include <QOpenGLFunctions> #incl ...
- 视频和音频播放的演示最简单的例子6:OpenGL广播YUV420P(T经exture,采用Shader)
===================================================== 最简单的视频和音频播放的演示样品系列列表: 最简单的视音频播放演示样例1:总述 最简单的视音 ...
- 关于QT Graphics View开启OpenGL渲染后复选框、微调框等无法正常显示的问题
之前学习QT Graphics View框架,除了基本的图元外,还可以通过QGraphicsProxyWidget类添加QT的基本Widget(如按钮.复选框.单选框等),常使用的场景类接口如下: Q ...
- Qt Examples - Boxes (在Qt场景视图中结合OpenGL渲染)
QT自带例程Boxes使用QT Graphics View框架实现了2D图形和3D图形的混合渲染,综合性比较强,整合知识较多,值得学习. 可以使用鼠标通过以下方式控制演示中的元素: 按住鼠标左键的同时 ...
- 最简单的视音频播放示例6:OpenGL播放YUV420P(通过Texture,使用Shader)
本文记录OpenGL播放视频的技术.上一篇文章中,介绍了一种简单的使用OpenGL显示视频的方式.但是那还不是OpenGL显示视频技术的精髓.和Direct3D一样,OpenGL更好的显示视频的方式也 ...
- D3D三层Texture纹理经像素着色器实现渲染YUV420P
简单记录一下这两天用Texture实现渲染YUV420P的一些要点. 在视频播放的过程中,有的时候解码出来的数据是YUV420P的.表面(surface)通过设置参数是可以渲染YUV420P的,但Te ...
- 初始化glew,创建OpenGL渲染上下文
void RegisterWinDowClass(HINSTANCE hInstance,std::string className,WNDPROC proc) { WNDCLASS wndClass ...
- 使用X264编码yuv格式的视频帧使用ffmpeg解码h264视频帧
前面一篇博客介绍在centos上搭建点击打开链接ffmpeg及x264开发环境.以下就来问个样例: 1.利用x264库将YUV格式视频文件编码为h264格式视频文件 2.利用ffmpeh库将h264格 ...
- Qt Quick + OpenGL + Bullet初次測试
Qt Quick + OpenGL + Bullet初次測试 眼下Qt的Quick模块已经表现得很出色,并且可以预留接口来渲染OpenGL场景.一般来说,已经可以满足大部分编程须要了.这次呢.尝试使用 ...
随机推荐
- Postman的Tests标签测试
接口测试最重要的就是返回数据的检查,一个简单的接口,我们可以肉眼检查返回数据,但接口一旦多起来且复杂,每次的检查都会很费劲,此时我们就需要postman 的tests模块来代替 postman面板: ...
- 我的微软最有价值专家(Microsoft MVP)之路
一.写在前面 2018年对我来说是幸运的一年,对我来说最幸运的事情有两个,一个是在离驾照考试过期还有一个月(报名之后一直没去考)终于拿到了我的驾照,还有一件事莫过于获得了微软MVP.期间,一直有朋友问 ...
- CAP理论与分布式事务解决方案
微服务系统所设计的系统是分布式系统.分布式系统有一个著名的CAP理论,即同时满足"一致性""可用性"和"分区容错"是一件不可能的事.CAP理 ...
- Python入门-三级菜单
作业题目: 三级菜单 作业需求: menu = { '北京':{ '海淀':{ '五道口':{ 'soho':{}, '网易':{}, 'google':{} }, '中关村':{ '爱奇艺':{}, ...
- Floyd最短路(带路径输出)
摘要(以下内容来自百度) Floyd算法又称为插点法,是一种利用动态规划的思想寻找给定的加权图中多源点之间最短路径的算法,与Dijkstra算法类似. 该算法名称以创始人之一.1978年图灵奖获得者. ...
- FPGA中边沿触发和电平触发
边沿触发和电平触发基本就是触发器和锁存器的区别: 触发器是边沿触发,只有当时钟上升(或下降)的一瞬间,触发器会读取并锁存输入信号.输出信号仅在时钟信号上升(或下降)的一瞬间会发生变化. 锁存器是电 ...
- PS调出怀旧雨中特写的非主流照片
原图 最终效果 一.打开原图素材,按Ctrl + ALt + ~ 调出高光选区,按Ctrl + Shift + I 反选,然后创建曲线调整图层,适当调暗一点. 二.合并所有图层,点通道面板,选择蓝色通 ...
- mysql_查的小理解
show create table employee; 对这个语句的小理解: 顿悟呀,之前一直不太理解这条语句,现在忽然觉得明朗起来.他就是展示创建这个表格时的SQL语句.执行上述代码之后结果如下: ...
- 03-命令图片.doc
- 搭建RISC-V错误记录
错误:riscv64-unknown-elf-gcc: Command not found 解决办法:将riscv64-unknown-elf-gcc文件拷贝到根目录的/bin目录下. 原因是make ...