【QT项目:视频播放器——Qt opengl编程】通过shader完成显示yuv

通过Qt opengl不是为了3D绘制,而是为了将视频绘制起来
使用opengl 可以极大降低yuv转rgb的转换开销

使用Opengl需要考虑三大问题:

1、QOpenGLWidget(与界面如何交互)

1、为什么用QT的opengl
简单,界面可以自动叠加
void paintGL(); // 具体的绘制写在该函数里
void initializeGL(); // 材质初始化
void resizeGL(int width, int height); // 当窗口发生变化(缩放)
QOpenGLFunctions // 不需要手动添加库,直接继承该函数

2、Program GLSL 顶点和片元(如何与显卡交互)

GLSL是新的语言,通过GLSL与显卡进行交互,GLSL 跑在显卡上

QGLShaderProgram

Program用来编译和运行Shader代码,包括与shader的交互

编译和运行shader // shader两部分:顶点和片元
addShaderFromSourceCode // 加入shader代码
bindAttributeLocation // 设置传入的变量, 顶点和坐标
uniformLocation // 获取变量

GLSL着色器语言,专门针对opengl所设计,用于显卡运行

顶点着色器是针对每个顶点执行一次,用于确定顶点的位置;——三维
片元着色器是针对每个片元(可以理解为每个像素)执行一次,用于确定每个片元(像素)的颜色 ——平面
GLSL基本语法与C基本相同
它完美地支持向量和矩阵操作
GLSL提供了大量的内置函数来提供丰富的拓展功能
它是通过限定符操作来管理输入输出类型

顶点着色器(画两个三角形,形成一个矩形)

显卡运算能力:值以三角形为单位,所画的数量

顶点着色器被使用在传统的基于顶点的操作, 例如位移矩阵、计算光照方程、产生贴图坐标。
顶点着色器被应用指定, 应用于客户的顶点转化。
在这里插入图片描述

片元着色器

在片元着色器阶 段只有唯一的 varying 输出变量- 即内建变量: gl_FragColor(像素点颜色)
在这里插入图片描述

顶点信息

在这里插入图片描述
在这里插入图片描述

材质坐标信息(全部在第一象限)

在这里插入图片描述
在这里插入图片描述

传入顶点和材质坐标

glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, vertexVertices); 
	ATTRIB_VERTEX:顶点坐标 	2 :坐标数量 		GL_FLOAT:单位数
	0:法线		0:步宽	
glEnableVertexAttribArray(ATTRIB_VERTEX); 
	使生效
glVertexAttribPointer(ATTRIB_TEXTURE, 2, GL_FLOAT, 0, 0, textureVertices);
	材质坐标
glEnableVertexAttribArray(ATTRIB_TEXTURE);
	

三种GLSL变量类型

varying 顶点与片元共享 		// 算出顶点坐标
attribute 顶点使用,由bindAttributeLocation传入
uniform 程序传入 uniformLocation获取地址
glUniform1i(textureUniformY, 0); 设置

顶点shader

attribute vec4 vertexIn;   // 顶点输入
attribute vec2 textureIn;  // 材质输入

void main(void) 
 {
    gl_Position = vertexIn;
  textureOut = textureIn;  }

片元shader

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, 1, 1, 0, -0.39465, 2.03211, 1.13983, -0.58060, 0) * yuv; 
  gl_FragColor = vec4(rgb, 1);
 }

3、材质Texture(如何写入ffmpeg数据)

前面通过OpenGLWidget管理整个窗口,最终显示涉及在某个材质上,最终要把ffmpeg数据写入,要考虑如何在材质中写入ffmpeg数据

创建材质

glGenTextures(1, t); 		// 创建材质个数,指针地址
glBindTexture(GL_TEXTURE_2D, *t);  // 绑定材质类型成2D图像
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);  // 放大、缩小(通过线性插值)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glTexParameteri

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
GL_TEXTURE_2D: 操作2D纹理.
GL_TEXTURE_MIN_FILTE: 缩小过滤
GL_TEXTURE_MAG_FILTER: 放大过滤
GL_LINEAR: 线性过滤, 使用距离当前渲染像素中心最近的4个纹素加权平均值.
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值