PlayerGLWidget(副本).cpp_ 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. #include "PlayerGLWidget.h"
  2. PlayerGLWidget::PlayerGLWidget(QWidget *parent) : QOpenGLWidget(parent)
  3. {
  4. }
  5. PlayerGLWidget::~PlayerGLWidget()
  6. {
  7. }
  8. /* 刷新一帧 */
  9. void PlayerGLWidget::updateFrame(Image_YUV420& image)
  10. {
  11. yData = image.yData;
  12. uData = image.uData;
  13. vData = image.vData;
  14. update();
  15. }
  16. void PlayerGLWidget::initShaders()
  17. {
  18. // 顶点着色器
  19. const char *vshader = R"(
  20. #version 330 core
  21. layout(location = 0) in vec4 vertexIn;
  22. layout(location = 1) in vec2 textureIn;
  23. out vec2 textureOut;
  24. void main(void)
  25. {
  26. gl_Position = vertexIn;
  27. textureOut = textureIn;
  28. })";
  29. // 片段着色器(YUV420P 转 RGB)
  30. const char *fshader = R"(
  31. #version 330 core
  32. in vec2 textureOut;
  33. out vec4 fragColor;
  34. uniform sampler2D tex_y;
  35. uniform sampler2D tex_u;
  36. uniform sampler2D tex_v;
  37. void main(void)
  38. {
  39. float y = texture(tex_y, textureOut).r;
  40. float u = texture(tex_u, textureOut).r - 0.5;
  41. float v = texture(tex_v, textureOut).r - 0.5;
  42. float r = y + 1.403 * v;
  43. float g = y - 0.344 * u - 0.714 * v;
  44. float b = y + 1.770 * u;
  45. fragColor = vec4(r, g, b, 1.0);
  46. })";
  47. // 创建着色器程序
  48. program.addShaderFromSourceCode(QOpenGLShader::Vertex, vshader);
  49. program.addShaderFromSourceCode(QOpenGLShader::Fragment, fshader);
  50. program.link();
  51. }
  52. void PlayerGLWidget::initTextures()
  53. {
  54. // 创建 YUV 纹理
  55. textureY = new QOpenGLTexture(QOpenGLTexture::Target2D);
  56. textureU = new QOpenGLTexture(QOpenGLTexture::Target2D);
  57. textureV = new QOpenGLTexture(QOpenGLTexture::Target2D);
  58. textureY->create();
  59. textureU->create();
  60. textureV->create();
  61. }
  62. // void PlayerGLWidget::initVertex()
  63. // {
  64. // }
  65. // void PlayerGLWidget::initFrameBuffer()
  66. // {
  67. // }
  68. void PlayerGLWidget::renderYUV420P()
  69. {
  70. if (yData.isEmpty() || uData.isEmpty() || vData.isEmpty())
  71. return;
  72. // 绑定纹理
  73. textureY->bind(0);
  74. textureU->bind(1);
  75. textureV->bind(2);
  76. // 上传 YUV 数据到纹理
  77. textureY->setData(QOpenGLTexture::Red, QOpenGLTexture::UInt8, yData.constData());
  78. textureU->setData(QOpenGLTexture::Red, QOpenGLTexture::UInt8, uData.constData());
  79. textureV->setData(QOpenGLTexture::Red, QOpenGLTexture::UInt8, vData.constData());
  80. // 绑定着色器程序
  81. program.bind();
  82. program.setUniformValue("tex_y", 0);
  83. program.setUniformValue("tex_u", 1);
  84. program.setUniformValue("tex_v", 2);
  85. // 绘制矩形
  86. static const GLfloat vertices[] = {
  87. -1.0f, -1.0f, 0.0f,
  88. 1.0f, -1.0f, 0.0f,
  89. -1.0f, 1.0f, 0.0f,
  90. 1.0f, 1.0f, 0.0f
  91. };
  92. static const GLfloat texCoords[] = {
  93. 0.0f, 1.0f,
  94. 1.0f, 1.0f,
  95. 0.0f, 0.0f,
  96. 1.0f, 0.0f
  97. };
  98. glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertices);
  99. glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, texCoords);
  100. glEnableVertexAttribArray(0);
  101. glEnableVertexAttribArray(1);
  102. glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  103. program.release();
  104. }
  105. void PlayerGLWidget::initializeGL()
  106. {
  107. initializeOpenGLFunctions();
  108. glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
  109. // 初始化着色器
  110. initShaders();
  111. initTextures();
  112. }
  113. void PlayerGLWidget::resizeGL(int w, int h)
  114. {
  115. glViewport(0, 0, w, h);
  116. }
  117. void PlayerGLWidget::paintGL()
  118. {
  119. glClear(GL_COLOR_BUFFER_BIT);
  120. // 渲染 YUV 数据
  121. renderYUV420P();
  122. }