PlayerGLWidget.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  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 =
  20. "#version 330 core\n"
  21. "layout(location = 0) in vec4 vertexIn;\n"
  22. "layout(location = 1) in vec2 textureIn;\n"
  23. "out vec2 textureOut;\n"
  24. "void main(void)\n"
  25. "{\n"
  26. " gl_Position = vertexIn;\n"
  27. " textureOut = textureIn;\n"
  28. "}\n";
  29. // 片段着色器(YUV420P 转 RGB)
  30. const char *fshader =
  31. "#version 330 core\n"
  32. "in vec2 textureOut;\n"
  33. "out vec4 fragColor;\n"
  34. "uniform sampler2D tex_y;\n"
  35. "uniform sampler2D tex_u;\n"
  36. "uniform sampler2D tex_v;\n"
  37. "void main(void)\n"
  38. "{\n"
  39. " float y = texture(tex_y, textureOut).r;\n"
  40. " float u = texture(tex_u, textureOut).r - 0.5;\n"
  41. " float v = texture(tex_v, textureOut).r - 0.5;\n"
  42. " float r = y + 1.403 * v;\n"
  43. " float g = y - 0.344 * u - 0.714 * v;\n"
  44. " float b = y + 1.770 * u;\n"
  45. " fragColor = vec4(r, g, b, 1.0);\n"
  46. "}\n";
  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. }