>
> 总结;QT音频播放基于三个类进行操作
> 先设置QAudioFormat音频格式,
> 再通过设置的音频格式创建QAudioOutput 音频输出设备启动设备和设置缓冲,
> 最后通过QAudioOutput 的启动得到具体声卡设备的抽象对象QIODevice ,通过向QIODevice 进行写入音频数据实现音频播放的。
>
>
>
### 3、QT视频绘制 QT openGL编程
[雷神博客介绍OpenGL基于纹理显示的流程]( )
因为视频显示存在像素格式的转换问题,要从解码出来的YUV格式转化为显示需要的RGB格式,视频的每一帧图像这么多像素点都需要转换,这是一个很大的开销,如果这一部分效率不高,那么对整体的视频播放性能都是十分有影响的,而QTopenGL也是效率很高的,直接操作显卡。
**Shader**有点类似于一个程序的编译器,
1)编写Vertex Shader和Fragment Shader源码。GLSL语言编写类似与C语言的一样的代码,它可以放在GPU里面被并行运行。
Vertex Shader(如果要存放到文件中就在.vsh)负责搞定像素位置,填写gl\_Posizion;
Fragment Shader(Fragment Shader fsh)负责搞定像素外观,填写 gl\_FragColor;
**Program**有点类似于一个程序的链接器。
program对象提供了把需要做的事连接在一起的机制,在一个program中,shader对象可以连接在一起。
**QTopenGL显示的几个关键点**
QOpenGLWidget (与界面如何交互)
Program GLSL 顶点与片元(如何与显卡交互的,GLSL 是跑在显卡上面的)
材质纹理Texture (如何写入ffmpeg数据的)
**顶点和纹理材质**
下面有相关介绍
**为什么要采用QT的OpenGL三维的来绘制**,直接使用QopenWidget、QWight也是可以的,但是如果使用后面的那么其实图像显示和界面的按钮是一套东西,当点击按钮刷新的时候就会存在闪屏的情况。因此采用三维的,QTOpenGL这种就是提供三维绘制,就可以自动在界面上叠加了。
使用的时候需要重载这些函数
void paintGL();//具体绘制在这里面实现
void initializeGL();//初始化
void resizeGL(int width,int height)//当窗口发生变化的时候调用,这个函数
还提供了很大的便利,如如果需要视频放缩的时候就可以直接调用OpenGL里面的函数,不然就需要在ffmpeg进行像素尺寸的转换效率就比较低了并且采用不同的算法效果可能也不一定好。而openGL中就是采用差值的算法来放缩,整体界面就减少失真的情况。
**封装了操作OpenGL对象的函数类QOpenGLFunctions**
QOpenGL相关的函数是单独有一个类来封装的,是QOpenGLFunctions
类,这里面就有很多与openGL相关的函数了,因此也可以进行QOpenGLFunctions继承来获取操作openGL的相关函数。
**QGLShaderProgram编译运行shader和shader交互**
shader 着色器
这个程序最终是在显卡上运行的,是通过QGLShaderProgram 来与显卡进行交互的。
QGLShaderProgram 主要封装的函数有
编译运行shader
addShaderFromSourceCode 把shader的源代码加载进来,有两部分代码,是顶点shader和片元shader(又称为像素shader)
bindAttributeLocation 设置传入的属性,只要是设置顶点坐标的属性和材质纹理Texture坐标的属性,后面可以传入顶点坐标或材质坐标然后对应坐标设置什么变量是通过他来设置的。
uniformLocation 获取shader变量 就是将显卡当中变量的一块地址取出来
总结;就是编译运行shader、传入shader程序,设置变量,获取变量
**GLSL着色器语言 基于openGL设计的,给显卡用的语言**
OpenGL Shader Language,简称GLSL。它是一种类似于C语言的专门为GPU设计的语言,它可以放在GPU里面被并行运行。
**顶点着色器**,就是针对每个顶点执行一次,用于确定顶点的位置,因为在三维空间中要将所有顶点的参数都获取。一般顶点着色器都是画三角形,如计算显卡的能力都是看他能画出多少个三角形,这里图片的显示我们采用画矩形,也就是两个三角形组合。因此我们这里顶点着色器的代码就是画两个三角形组成矩形。

代码填充就是
float *vertexData = new float[12]{
-1.0f,-1.0f,0.0f,
1.0f,-1.0f,0.0f,
-1.0f, 1.0f,0.0f,
1.0f,1.0f,0.0f
}
//也可以第三维的0这里不传入。再传入的时候告诉他填充的是二维的要他在内部填充
**片元着色器**,就是针对一个平面的,针对每个片元(可以理解为每个像素)执行一次,用于确定每个片元(像素)的颜色 。传入YUV的数据过来,至于至于转换可以到显卡自己那边转换。片元着色器他有一个内置变量gl\_FragColor,就是在遍历像素点的时候将这个值进行改变,那么他的颜色一会跟着变化的。
流程就是通过顶点着色器获取顶点的位置,再通过片元着色器对这些顶点构成的片元像素进行填充颜色。
**GLSL基本语法与C基本相同,这里只是做简单图像显示,真正的GLSL是用来做特效的,涉及算法的,**
GLSL 完美支持向量和矩阵操作,因此在像素格式的转换方面十分适合选用,并且提供了大量的内置函数来提供丰富的扩展功能的,
他是通过**限定符操作**来管理输入输出类型的,例如传入顶点坐标,传出材质纹理等。
**材质坐标信息**

与顶点不同的是他是二维的并且坐标都是正数。
代码设置;
float *textureVertexData = new float[8]{
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 0.0f,