• ubuntu18.04 OpenGL开发(显示YUV)


    源码参考:https://download.csdn.net/download/weixin_55163060/88382816

    安装opengl

    sudo apt install libglu1-mesa-dev freeglut3-dev mesa-common-dev
    安装opengl工具包
    sudo apt install mesa-utils
    检查opengl版本信息(桌面终端执行)
    sudo glxinfo | grep "OpenGL version"
    显示:OpenGL version string: 3.3 (Compatibility Profile) Mesa 20.0.8
    安装glfw窗口管理器
    sudo apt-get install cmake xorg-dev libglu1-mesa-dev
    wget https://sourceforge.net/projects/glfw/files/glfw/3.3.5/glfw-3.3.5.zip(wget https://github.com/glfw/glfw/releases/download/3.3.5/glfw-3.3.5.zip)
    unzip glfw-3.3.5.zip
    cd glfw-3.3.5
    mkdir build
    cd build
    cmake -DCMAKE_INSTALL_PREFIX=/usr/local ..
    make -j8
    sudo make install
    【window.c】 
    1. #include <GLFW/glfw3.h>
    2. #include <stdio.h>
    3. int main(void)
    4. {
    5. GLFWwindow* window;
    6. /* Initialize the library */
    7. if (!glfwInit())
    8. return -1;
    9. /* Create a windowed mode window and its OpenGL context */
    10. window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
    11. if (!window)
    12. {
    13. glfwTerminate();
    14. return -1;
    15. }
    16. /* Make the window's context current */
    17. glfwMakeContextCurrent(window);
    18. /* Loop until the user closes the window */
    19. while (!glfwWindowShouldClose(window))
    20. {
    21. //glClearColor()命令指定了清除背景时用的颜色值,这里的(1,0,0,1)代表RGB中的红色,末尾的1表示不透明度
    22. glClearColor(1.0, 0.0, 0.0, 1.0);
    1. /* Render here */
    2. glClear(GL_COLOR_BUFFER_BIT);
    3. /* Swap front and back buffers */
    4. glfwSwapBuffers(window);
    5. /* Poll for and process events */
    6. glfwPollEvents();
    7. }
    8. glfwTerminate();
    9. return 0;
    10. }
    编译
    gcc -o window window.c -lglfw3 -lGL -lX11 -lm -lpthread -ldl
    执行显示一个红色窗口
    【linmath.h】
    一个精简的线性数学库,旨在进行图形编程。 支持vec3,vec4,mat4x4和四元数
    【GLAD库】(初始化后调用gl函数编译不会报错)
    GLAD是用来管理OpenGL的函数指针的,所以在调用任何OpenGL的函数之前我们需要初始化GLAD。GLAD也可以使OpenGL基础渲染变得简单。
    【triangle.c】
    1. //! [code]
    2. #include "glad.h"
    3. #define GLAD_GL_IMPLEMENTATION
    4. #include <GL/gl.h>
    5. //#include "glad.h"
    6. #define GLFW_INCLUDE_NONE
    7. #include <GLFW/glfw3.h>
    8. #include "linmath.h"
    9. #include <stdlib.h>
    10. #include <stddef.h>
    11. #include <stdio.h>
    12. typedef struct Vertex
    13. {
    14. vec2 pos;
    15. vec3 col;
    16. } Vertex;
    17. static const Vertex vertices[3] =
    18. {
    19. { { -0.6f, -0.4f }, { 1.f, 0.f, 0.f } },
    20. { { 0.6f, -0.4f }, { 0.f, 1.f, 0.f } },
    21. { { 0.f, 0.6f }, { 0.f, 0.f, 1.f } }
    22. };
    23. static const char* vertex_shader_text =
    24. "#version 330\n"
    25. "uniform mat4 MVP;\n"
    26. "in vec3 vCol;\n"
    27. "in vec2 vPos;\n"
    28. "out vec3 color;\n"
    29. "void main()\n"
    30. "{\n"
    31. " gl_Position = MVP * vec4(vPos, 0.0, 1.0);\n"
    32. " color = vCol;\n"
    33. "}\n";
    34. static const char* fragment_shader_text =
    35. "#version 330\n"
    36. "in vec3 color;\n"
    37. "out vec4 fragment;\n"
    38. "void main()\n"
    39. "{\n"
    40. " fragment = vec4(color, 1.0);\n"
    41. "}\n";
    42. static void error_callback(int error, const char* description)
    43. {
    44. fprintf(stderr, "Error: %s\n", description);
    45. }
    46. static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
    47. {
    48. if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
    49. glfwSetWindowShouldClose(window, GLFW_TRUE);
    50. }
    51. int main(void)
    52. {
    53. glfwSetErrorCallback(error_callback);
    54. if (!glfwInit())
    55. exit(EXIT_FAILURE);
    56. glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    57. glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    58. glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    59. GLFWwindow* window = glfwCreateWindow(640, 480, "OpenGL Triangle", NULL, NULL);
    60. if (!window)
    61. {
    62. glfwTerminate();
    63. exit(EXIT_FAILURE);
    64. }
    65. glfwSetKeyCallback(window, key_callback);
    66. glfwMakeContextCurrent(window);
    1. if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
    2. {
    3. return -1;
    4. }
    5. glfwSwapInterval(1);
    6. // NOTE: OpenGL error checks have been omitted for brevity
    7. GLuint vertex_buffer;
    8. glGenBuffers(1, &vertex_buffer);
    9. glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
    10. glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    11. const GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
    12. glShaderSource(vertex_shader, 1, &vertex_shader_text, NULL);
    13. glCompileShader(vertex_shader);
    14. const GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
    15. glShaderSource(fragment_shader, 1, &fragment_shader_text, NULL);
    16. glCompileShader(fragment_shader);
    17. const GLuint program = glCreateProgram();
    18. glAttachShader(program, vertex_shader);
    19. glAttachShader(program, fragment_shader);
    20. glLinkProgram(program);
    21. const GLint mvp_location = glGetUniformLocation(program, "MVP");
    22. const GLint vpos_location = glGetAttribLocation(program, "vPos");
    23. const GLint vcol_location = glGetAttribLocation(program, "vCol");
    24. GLuint vertex_array;
    25. glGenVertexArrays(1, &vertex_array);
    26. glBindVertexArray(vertex_array);
    27. glEnableVertexAttribArray(vpos_location);
    28. glVertexAttribPointer(vpos_location, 2, GL_FLOAT, GL_FALSE,
    29. sizeof(Vertex), (void*) offsetof(Vertex, pos));
    30. glEnableVertexAttribArray(vcol_location);
    31. glVertexAttribPointer(vcol_location, 3, GL_FLOAT, GL_FALSE,
    32. sizeof(Vertex), (void*) offsetof(Vertex, col));
    33. while (!glfwWindowShouldClose(window))
    34. {
    35. int width, height;
    36. glfwGetFramebufferSize(window, &width, &height);
    37. const float ratio = width / (float) height;
    38. glViewport(0, 0, width, height);
    39. glClear(GL_COLOR_BUFFER_BIT);
    40. mat4x4 m, p, mvp;
    41. mat4x4_identity(m);
    42. mat4x4_rotate_Z(m, m, (float) glfwGetTime());
    43. mat4x4_ortho(p, -ratio, ratio, -1.f, 1.f, 1.f, -1.f);
    44. mat4x4_mul(mvp, p, m);
    45. glUseProgram(program);
    46. glUniformMatrix4fv(mvp_location, 1, GL_FALSE, (const GLfloat*) &mvp);
    47. glBindVertexArray(vertex_array);
    48. glDrawArrays(GL_TRIANGLES, 0, 3);
    49. glfwSwapBuffers(window);
    50. glfwPollEvents();
    51. }
    52. glfwDestroyWindow(window);
    53. glfwTerminate();
    54. exit(EXIT_SUCCESS);
    55. }
    56. //! [code]
    编译
    gcc -o triangle glad.c triangle.c -lglfw3 -lGL -lX11 -lm -lpthread -ldl
    执行程序显示旋转的三角形
    【YUV描述】
    一般RGB用于渲染,YUV用于传输。
    YUV4:4:4:完全采用表示每个像素点都有一个Y,U,V。一个YUV占 8+8+8 = 24bits,3个字节。
    YUV4:2:2: 就是2:1的水平取样,垂直完全采样,表示水平的两个像素有两个Y但是只有一个U一个V的采用格式。一个YUV占 8+4+4 = 16bits 2个字节。
    YUV4:2:0:就是2:1的水平取样,2:1的垂直采样,表示上下左右四个像素点有4个Y但是只取一个U和一个V,一个YUV占 8+2+2 = 12bits 1.5个字节
    planar的YUV格式表示先连续存储所有像素点的Y,再紧接着存储所有的U,再就是V。Y、U和V组件存储为三个独立的数组中。
    packed的YUV格式表示每个像素点的YUV是连续交替存储的,先存储像素点1的YUV再存在像素点2的YUV像素点。Y、U和V组件存储在一个数组中。每个像素点的Y,U,V是连续交错存储的
    YUV420P(YU12和YV12)格式
    YU12:安卓的模式。存储顺序是先存Y,再存U,最后存V。YYYYYYYY UUVV (I420格式)
    YV12:存储顺序是先存Y,再存V,最后存U。YYYYYYYY VVUU
    YUV420SP(NV12和NV21)格式
    NV12 是 IOS 中有的模式,它的存储顺序是先存 Y 分量,再 UV 进行交替存储。
    NV21 是 安卓 中有的模式,它的存储顺序是先存 Y 分量,在 VU 交替存储
    【h264转YUV命令】
    ffmpeg -i C:\Users\Administrator\Desktop\test.h264 -y -an -frames 1 -s 1920x1080 out.yuv
    pause
    【GLSL】
    OpenGL着色语言(OpenGL Shading Language)是用来在OpenGL中着色编程的语言,也即开发人员写的短小的自定义程序,他们是在图形卡的GPU (Graphic Processor Unit图形处理单元)上执行的,代替了固定的渲染管线的一部分,使渲染管线中不同层次具有可编程性。比如:视图转换、投影转换等。GLSL(GL Shading Language)的着色器代码分成2个部分:Vertex Shader(顶点着色器)和Fragment(片断着色器),有时还会有Geometry Shader(几何着色器)。负责运行顶点着色的是顶点着色器。它可以得到当前OpenGL 中的状态,GLSL内置变量进行传递。GLSL其使用C语言作为基础高阶着色语言,避免了使用汇编语言或硬件规格语言的复杂性。
    【yuv_show.cpp】
    1. #include<string>
    2. #include<fstream>
    3. #include<sstream>
    4. #include<iostream>
    5. #include<stdio.h>
    6. #include "glad.h"
    7. #include <GLFW/glfw3.h>
    8. typedef unsigned char BYTE;
    9. const unsigned int SCR_WIDTH = 500;
    10. const unsigned int SCR_HEIGHT = 600;
    11. const int len = 1920*1080 * 3/2;
    12. BYTE YUVdata [len];
    13. unsigned int VBO = 0;
    14. unsigned int VAO = 0;
    15. unsigned int EBO = 0;
    16. unsigned int texturePIC = 0;
    17. int shaderProgram = 0;
    18. GLuint texIndexarray[3];
    19. GLuint texUniformY = 99;
    20. GLuint texUniformU = 99;
    21. GLuint texUniformV = 99;
    22. void LoadPicture()
    23. {
    24. glGenTextures(3, texIndexarray);//生成三个纹理索引
    25. glBindTexture(GL_TEXTURE_2D, texIndexarray[0]);
    26. //为bind的纹理设置环绕,过滤方式
    27. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    28. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    29. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    30. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    31. glBindTexture(GL_TEXTURE_2D, texIndexarray[1]);
    32. //为bind的纹理设置环绕,过滤方式
    33. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    34. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    35. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    36. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    37. glBindTexture(GL_TEXTURE_2D, texIndexarray[2]);
    38. //为bind的纹理设置环绕,过滤方式
    39. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    40. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    41. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    42. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    43. //使用着色器程序,返回采样器的序号
    44. glUseProgram(shaderProgram);//该语句必须要有;安装 指定着色器程序
    45. texUniformY = glGetUniformLocation(shaderProgram, "dataY");
    46. texUniformU = glGetUniformLocation(shaderProgram, "dataU");
    47. texUniformV = glGetUniformLocation(shaderProgram, "dataV");
    48. ----------加载数据--------------------------------------------------------
    49. FILE* fp = fopen("./out.yuv","rb+");//I420
    50. int returns =fread(YUVdata,1,len,fp);
    51. int w = 1920;
    52. int h = 1080;
    53. int ysize = w*h;
    54. int uvsize = w * h / 4;
    55. void* uptr = &YUVdata[ysize];
    56. void* vptr = &YUVdata[ysize * 5 / 4];
    57. //---------------------------------------------------------------------------
    58. glActiveTexture(GL_TEXTURE0);
    59. glBindTexture(GL_TEXTURE_2D, texIndexarray[0]);// texindexarray[0] =1
    60. //使用GL_red表示单通道,glfw3里边没有YUV那个GL属性;
    61. glTexImage2D(GL_TEXTURE_2D, 0 , GL_RED, w, h ,0, GL_RED,GL_UNSIGNED_BYTE ,YUVdata);
    62. glUniform1i(texUniformY,0); //通过 glUniform1i 的设置,保证每个 uniform 采样器对应着正确的纹理单元;注意这里不能用tesindexarray[0];
    63. glActiveTexture(GL_TEXTURE1);
    64. glBindTexture(GL_TEXTURE_2D, texIndexarray[1]);
    65. glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, w/2, h/2, 0, GL_RED, GL_UNSIGNED_BYTE,uptr);
    66. glUniform1i(texUniformU, 1);
    67. glActiveTexture(GL_TEXTURE2);
    68. glBindTexture(GL_TEXTURE_2D, texIndexarray[2]);
    69. glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, w/2, h/2, 0, GL_RED, GL_UNSIGNED_BYTE,vptr);
    70. glUniform1i(texUniformV,2);
    71. glUseProgram(0);
    72. }
    73. void render()
    74. {
    75. glBindVertexArray(VAO);
    76. glUseProgram(shaderProgram);
    77. glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,0);
    78. //glDrawArrays(GL_TRIANGLE_FAN,0,4);也可
    79. glUseProgram(0);
    80. glBindVertexArray(0);
    81. }
    82. void initmodule()
    83. {
    84. //做个一模型;正方形;映射了顶点坐标和纹理坐标的对应关系
    85. float vertexs[] = {
    86. //顶点坐标-------纹理坐标(屏幕坐标翻转)
    87. 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
    88. 1.0f, -1.0f, 0.0f, 1.0f, 1.0f,
    89. -1.0f, -1.0f, 0.0f, 0.0f, 1.0f,
    90. -1.0f, 1.0f, 0.0f, 0.0f, 0.0f
    91. };
    92. //一个正方形是由两个三角形得来的;记录顶点的索引顺序
    93. unsigned int indexs[] = {
    94. 0,1,3,
    95. 1,2,3,
    96. };
    97. //做VAO
    98. glGenVertexArrays(1,&VAO);
    99. glBindVertexArray(VAO);
    100. //做VBO
    101. glGenBuffers(1, &VBO);
    102. glBindBuffer(GL_ARRAY_BUFFER, VBO);
    103. //创建显存空间
    104. glBufferData(GL_ARRAY_BUFFER,sizeof(vertexs), vertexs, GL_STATIC_DRAW);
    105. //设置索引缓冲
    106. glGenBuffers(1,&EBO);
    107. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,EBO);
    108. glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(indexs),indexs,GL_STATIC_DRAW); //加载纹理图片,生成纹理
    109. LoadPicture();
    110. //设置第0个锚点,3个点,不需要归一化,跨度5个float可以读下一个点
    111. glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,5*sizeof(float),(void*)0);
    112. //打开顶点
    113. glEnableVertexAttribArray(0);
    114. //纹理属性设置,纹理在第一个锚点上(指定顶点数据)
    115. glVertexAttribPointer(1,2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
    116. //打开纹理
    117. glEnableVertexAttribArray(1);
    118. //解除绑定VBO
    119. glBindBuffer(GL_ARRAY_BUFFER,0);
    120. //解绑VAO
    121. glBindVertexArray(0);
    122. }
    123. void initshader(const char* verpath,const char* fragpath)
    124. {
    125. //编译shader,并记录shaderID
    126. std::string VerCode("");
    127. std::string fregCode("");
    128. //读文件
    129. std::ifstream vShaderFile;
    130. std::ifstream fShaderFile;
    131. vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
    132. fShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
    133. try
    134. {
    135. vShaderFile.open(verpath);
    136. fShaderFile.open(fragpath);
    137. std::stringstream vsstream, fsstream;
    138. vsstream << vShaderFile.rdbuf();
    139. fsstream << fShaderFile.rdbuf();
    140. VerCode = vsstream.str();
    141. fregCode = fsstream.str();
    142. }
    143. catch (const std::exception&)
    144. {
    145. std::cout << "read file error" << std::endl;
    146. }
    147. const char* vshader = VerCode.c_str();
    148. const char* fshader = fregCode.c_str();
    149. //shader 编译连接
    150. unsigned int vertexID = 0, fragID = 0;
    151. char infoLog[512];//存储错误信息
    152. int successflag = 0;
    153. vertexID = glCreateShader(GL_VERTEX_SHADER);
    154. glShaderSource(vertexID,1,&vshader,NULL );
    155. glCompileShader(vertexID);
    156. //获取编译是否成功
    157. glGetShaderiv(vertexID,GL_COMPILE_STATUS,&successflag);
    158. if (!successflag)
    159. {
    160. glGetShaderInfoLog(vertexID,512,NULL,infoLog);
    161. std::string errstr(infoLog);
    162. std::cout << "v shader err"<<infoLog;
    163. }
    164. //frag
    165. fragID = glCreateShader(GL_FRAGMENT_SHADER);
    166. glShaderSource(fragID, 1, &fshader, NULL);
    167. glCompileShader(fragID);
    168. //获取编译是否成功
    169. glGetShaderiv(fragID, GL_COMPILE_STATUS, &successflag);
    170. if (!successflag)
    171. {
    172. glGetShaderInfoLog(fragID, 512, NULL, infoLog);
    173. std::string errstr(infoLog);
    174. std::cout << "f shader err"<<infoLog;
    175. }
    176. //链接
    177. shaderProgram = glCreateProgram();
    178. glAttachShader(shaderProgram,vertexID);
    179. glAttachShader(shaderProgram,fragID);
    180. glBindAttribLocation(shaderProgram, 0, "aPos");
    181. glBindAttribLocation(shaderProgram, 1, "texCoord");
    182. glLinkProgram(shaderProgram);
    183. glGetProgramiv(shaderProgram,GL_LINK_STATUS,&successflag);
    184. if (!successflag)
    185. {
    186. glGetShaderInfoLog(shaderProgram, 512, NULL, infoLog);
    187. std::string errstr(infoLog);
    188. std::cout << "link error";
    189. }
    190. //编译完成后,可以把中间的步骤程序删除
    191. glDeleteShader(vertexID);
    192. glDeleteShader(fragID);
    193. }
    194. void processInput(GLFWwindow *window)
    195. {
    196. if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
    197. {
    198. //将窗口设置为关闭,跳出循环
    199. glfwSetWindowShouldClose(window, true);
    200. }
    201. }
    202. void framebuffer_size_callback(GLFWwindow* window, int width, int height)
    203. {
    204. glViewport(0, 0, width, height);
    205. }
    206. int main()
    207. {
    208. //glfw初始化
    209. glfwInit();
    210. glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    211. glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    212. glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    213. //glfw创建窗口
    214. GLFWwindow* window = glfwCreateWindow(500, 600, "LearnOpenGL", NULL, NULL);
    215. if (window == NULL)
    216. {
    217. printf("创建窗口失败");
    218. //终止
    219. glfwTerminate();
    220. return -1;
    221. }
    222. //显示窗口
    223. glfwMakeContextCurrent(window);
    224. //设置回调,当窗口大小调整后将调用该回调函数
    225. glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
    226. // glad初始化
    227. if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
    228. {
    229. printf("加载失败");
    230. return -1;
    231. }
    232. initshader("vertexShader.glsl", "fragmentShader.glsl");//先编译着色器
    233. initmodule();
    234. // 使用循环达到循环渲染效果
    235. while (!glfwWindowShouldClose(window))
    236. {
    237. //自定义输入事件
    238. processInput(window);
    239. glClearColor(0.0f,0.0f,0.0f,1.0f);
    240. glClear(GL_COLOR_BUFFER_BIT);
    241. render();
    242. //交互缓冲区,否则显示空白
    243. glfwSwapBuffers(window);
    244. //输入输出事件,否则无法对窗口进行交互
    245. glfwPollEvents();
    246. }
    247. //终止渲染 关闭并清理glfw本地资源
    248. glfwTerminate();
    249. return 0;
    250. }
    【vertexShader.glsl】
    1. #version 330 core
    2. layout(location = 0) in vec3 aPos;
    3. layout(location = 1) in vec2 texCoord;
    4. out vec2 TexCoord;
    5. void main()
    6. {
    7. gl_Position = vec4(aPos.x,aPos.y,aPos.z,1.0);
    8. TexCoord = texCoord;
    9. };
    【fragmentShader.glsl】
    1. #version 330 core
    2. layout(location = 0) out vec4 FragColor;
    3. in vec2 TexCoord;
    4. uniform sampler2D dataY;
    5. uniform sampler2D dataU;
    6. uniform sampler2D dataV;
    7. vec3 yuv;
    8. vec3 rgb;
    9. void main()
    10. {
    11. yuv.x = texture2D(dataY, TexCoord).r-0.0625;
    12. yuv.y = texture2D(dataU, TexCoord).r-0.5;
    13. yuv.z = texture2D(dataV, TexCoord).r-0.5;
    14. rgb = mat3(1, 1, 1,
    15. 0, -0.18732, 1.8556,
    16. 1.57481, -0.46813, 0) * yuv;
    17. FragColor = vec4(rgb.x, rgb.y,rgb.z,1);
    18. };
    【编译】
    g++ -o yuv_show glad.c yuv_show.cpp -lglfw3 -lGL -lX11 -lm -lpthread -ldl
    【运行】
    1、报错:v shader err0:2(1): error: shader output explicit location requires GL_ARB_separate_shader_objects extension or GLSL 4.20
    原因:fragmentShader.glsl和vertexShader.glsl搞反了
    2、报错:段错误
    解决方法:sudo ./yuv_show
    注:render()函数中增加LoadPicture()并修改其为读取不同的yuv数据可以实现视频流的播放。
  • 相关阅读:
    怎么恢复移走的u盘数据?可以尝试这三种方法
    Python 三维网格体素化
    全场景流量验证系统
    2021年数维杯数学建模C题运动会优化比赛模式探索求解全过程文档及程序
    新零售模式这么应用,太牛了
    Flutter开发GridView控件详解
    国产替代风潮下,电子元器件B2B商城系统如何助力企业突围市场竞争
    C语言中的结构体对齐是什么?如何控制结构体对齐方式?
    26、Nio(Selector(选择器))处理accept)
    css选择器优先级问题
  • 原文地址:https://blog.csdn.net/weixin_55163060/article/details/133385278