PlayerGLWidget.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. #include "PlayerGLWidget.h"
  2. #include "spdlog/spdlog.h"
  3. #include <qopenglext.h>
  4. #include <QVariant>
  5. PlayerGLWidget::PlayerGLWidget(QWidget *parent) : QOpenGLWidget(parent)
  6. {
  7. }
  8. PlayerGLWidget::~PlayerGLWidget()
  9. {
  10. if(m_shaderRGBA != nullptr) {
  11. delete m_shaderRGBA;
  12. m_shaderRGBA = nullptr;
  13. }
  14. }
  15. /* 显示RGBA图片 */
  16. void PlayerGLWidget::showOneRGBAImage(const QImage& image)
  17. {
  18. if(!m_isInit)
  19. {
  20. SPDLOG_WARN("OpenGLWidget未初始化");
  21. return;
  22. }
  23. if(image.format() == QImage::Format_RGBA8888)
  24. {
  25. m_shaderRGBA->refreshFrameRGBA(image);
  26. } else
  27. {
  28. QImage imageRGBA = image.convertToFormat(QImage::Format_RGBA8888);
  29. // SPDLOG_DEBUG("image format {}", (int)image.format());
  30. // SPDLOG_DEBUG("{}", imageRGBA.isNull());
  31. m_shaderRGBA->refreshFrameRGBA(imageRGBA);
  32. }
  33. m_shaderCurr = m_shaderRGBA; // 设置当前着色器为显示RGBA图片的着色器
  34. update(); // 更新界面,触发paintGL函数
  35. }
  36. /* 显示一张YUV420的图片 */
  37. void PlayerGLWidget::showOneYUV420Image(const Image_YUV420P& yuvData)
  38. {
  39. if(!m_isInit)
  40. {
  41. SPDLOG_WARN("OpenGLWidget未初始化");
  42. return;
  43. }
  44. if(!yuvData.isValid()) {
  45. SPDLOG_WARN("YUV420数据无效");
  46. return;
  47. }
  48. m_shaderYUV420->refreshFrameYUV420(yuvData);
  49. m_shaderCurr = m_shaderYUV420; // 设置当前着色器为显示YUV420图片的着色器
  50. update(); // 更新界面,触发paintGL函数
  51. }
  52. void PlayerGLWidget::testShowYUV420Image(const QImage& image)
  53. {
  54. m_shaderYUV420->refreshFrameRGBA(image);
  55. m_shaderCurr = m_shaderYUV420; // 设置当前着色器为显示YUV420图片的着色器
  56. update(); // 更新界面,触发paintGL函数
  57. }
  58. /* 初始化RGBA的Shader */
  59. void PlayerGLWidget::initShaderRGBA()
  60. {
  61. if(m_shaderRGBA != nullptr) {
  62. delete m_shaderRGBA; // 删除旧的着色器对象
  63. m_shaderRGBA = nullptr;
  64. }
  65. m_shaderRGBA = new ShaderRect();
  66. m_shaderRGBA->initShape(); // 初始化形状
  67. /* 初始化RGBA着色器 */
  68. QString vertexShaderFile = ":/shaderCode/vertexShaderRGBA.glsl";
  69. QString fragmentShaderFile = ":/shaderCode/fragmentShaderRGBA.glsl";
  70. if (!m_shaderRGBA->loadShaderCode(vertexShaderFile, fragmentShaderFile))
  71. {
  72. SPDLOG_ERROR("加载着色器代码失败");
  73. return;
  74. }
  75. /* 编译着色器 */
  76. m_shaderRGBA->compileShader();
  77. /* 初始化纹理 */
  78. m_shaderRGBA->initTextures();
  79. }
  80. /* 初始化YUV420的Shader */
  81. void PlayerGLWidget::initShaderYUV420()
  82. {
  83. if(m_shaderYUV420 != nullptr) {
  84. delete m_shaderYUV420; // 删除旧的着色器对象
  85. m_shaderYUV420 = nullptr;
  86. }
  87. m_shaderYUV420 = new ShaderYUV420();
  88. m_shaderYUV420->initShape(); // 初始化形状
  89. /* 初始化RGBA着色器 */
  90. QString vertexShaderFile = ":/shaderCode/vertexShaderYUV420.glsl";
  91. QString fragmentShaderFile = ":/shaderCode/fragmentShaderYUV420.glsl";
  92. if (!m_shaderYUV420->loadShaderCode(vertexShaderFile, fragmentShaderFile))
  93. {
  94. SPDLOG_ERROR("加载着色器代码失败");
  95. return;
  96. }
  97. /* 编译着色器 */
  98. m_shaderYUV420->compileShader();
  99. /* 初始化纹理 */
  100. m_shaderYUV420->initTextures();
  101. }
  102. void PlayerGLWidget::initializeGL()
  103. {
  104. SPDLOG_DEBUG("编译着色器...");
  105. /* 初始化OpenGL函数,OpenGL的函数是在运行时才确定函数指针的 */
  106. initializeOpenGLFunctions();
  107. /* 初始化显示RGBA图片的着色器 */
  108. initShaderRGBA();
  109. /* 初始化显示YUV420图片的着色器 */
  110. initShaderYUV420();
  111. SPDLOG_DEBUG("着色器编译完成");
  112. m_isInit = true; // 标记OpenGL已经初始化完成
  113. }
  114. void PlayerGLWidget::resizeGL(int w, int h)
  115. {
  116. /* 设置视口 */
  117. glViewport(0, 0, w, h);
  118. /* 设置投影矩阵 */
  119. // m_shaderObj->setProjectionMatrix(w, h);
  120. // SPDLOG_INFO("resizeGL: width = {}, height = {}", w, h);
  121. }
  122. void PlayerGLWidget::paintGL()
  123. {
  124. /* glClearColor函数是一个状态设置函数,而glClear函数则是一个状态使用的函数,
  125. * 它使用了当前的状态来获取应该清除为的颜色。 */
  126. glClearColor(0.1f, 0.3f, 0.3f, 1.0f);
  127. glClear(GL_COLOR_BUFFER_BIT);
  128. if(m_shaderCurr == nullptr)
  129. {
  130. // SPDLOG_WARN("当前着色器对象为空");
  131. return;
  132. }
  133. m_shaderCurr->useShader(); // 使用着色器
  134. m_shaderCurr->drawShape(); // 绘制图形
  135. }