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场景.一般来说,已经可以满足大部分编程须要了.这次呢.尝试使用 ...
随机推荐
- 完成了Coursera的一个机器学习课程
终于完成了这个课程,从开始学习,到现在差不多过了一年的时间,中间由于一些原因耽搁了,最终还是完成了,记录一下!
- Gym101138D Strange Queries/BZOJ5016 SNOI2017 一个简单的询问 莫队、前缀和、容斥
传送门--Gym 传送门--BZOJ THUWC2019D1T1撞题可还行 以前有些人做过还问过我,但是我没有珍惜,直到进入考场才追悔莫及-- 设\(que_{i,j}\)表示询问\((1,i,1,j ...
- Java8-1-新特性_Lambda表达式
最近实在是闲的蛋疼, 突然想起前一段时间使用Lambda表达式觉得惊为天人, 所以就去仔细的学习了一下, 整理出一份博客出来供大家观赏. 一. 什么是lambda表达式. Lambda 是一个匿名函数 ...
- Vue bus的使用(兄弟|非父子组件传值)-->可以使用一个空的Vue实例作为中央事件总线new Vue()
1.在main.js中注册全局的bus Vue.prototype.bus=new Vue(); 2.在组建中使用 子组建使用:this.bus.$emit('自定义事件名',data) metho ...
- 立足中国,走向世界(Made in China, Go to World)
FineUI一路走来已经历经 9 年的风风雨雨,拥有国内最为广泛的捐赠群体(1500多位),和众多企业客户的青睐(200多家). 今天,我们很高兴的宣布:FineUI英文版上线了! FineUI英文版 ...
- 2小时学会Spring Boot(IDE:eclipse)
一:安装STS插件 官网下载:点此下载STS 注意:STS版本必须与eclipse版本对应 安装教程:http://blog.csdn.net/cryhelyxx/article/details/53 ...
- SoftWater——SDN+UnderWater系列论文一
---- SoftWater: Software-defined networking for next-generation underwater communication systems 来源: ...
- C#跨进程读取listview控件中的数据
http://www.cnblogs.com/Charltsing/p/slv32.html 欢迎交流:QQ564955427 读取标准的32位listview控件中的数据,网上已经有很多代码了.今天 ...
- Telnet服务器和客户端请求处理
Telnet服务器和客户端请求处理 本文的控制台项目是根据SuperSocket官方Telnet示例代码进行调试的,官方示例代码:Telnet示例. 开始我的第一个Telnet控制台项目之旅: 创建控 ...
- 用WSDL4J解析types标签中的内容
WSDL4J是一种用来解析WSDL文本的常用工具. 但网络上用WSDL4J来解析wsdl文档complexType标签中内容的问题一大堆也没有有效的解决方法.今天在我“遍历”wsdl4j的api文档和 ...