#include "PlayerGLWidget.h" #include "spdlog/spdlog.h" #include #include PlayerGLWidget::PlayerGLWidget(QWidget *parent) : QOpenGLWidget(parent) { } PlayerGLWidget::~PlayerGLWidget() { if(m_shaderRGBA != nullptr) { delete m_shaderRGBA; m_shaderRGBA = nullptr; } } /* 显示RGBA图片 */ void PlayerGLWidget::showOneRGBAImage(const QImage& image) { if(!m_isInit) { SPDLOG_WARN("OpenGLWidget未初始化"); return; } if(image.format() == QImage::Format_RGBA8888) { m_shaderRGBA->refreshFrameRGBA(image); } else { QImage imageRGBA = image.convertToFormat(QImage::Format_RGBA8888); // SPDLOG_DEBUG("image format {}", (int)image.format()); // SPDLOG_DEBUG("{}", imageRGBA.isNull()); m_shaderRGBA->refreshFrameRGBA(imageRGBA); } m_shaderCurr = m_shaderRGBA; // 设置当前着色器为显示RGBA图片的着色器 update(); // 更新界面,触发paintGL函数 } /* 显示一张YUV420的图片 */ void PlayerGLWidget::showOneYUV420Image(const Image_YUV420P& yuvData) { if(!m_isInit) { SPDLOG_WARN("OpenGLWidget未初始化"); return; } if(!yuvData.isValid()) { SPDLOG_WARN("YUV420数据无效"); return; } m_shaderYUV420->refreshFrameYUV420(yuvData); m_shaderCurr = m_shaderYUV420; // 设置当前着色器为显示YUV420图片的着色器 update(); // 更新界面,触发paintGL函数 } void PlayerGLWidget::testShowYUV420Image(const QImage& image) { m_shaderYUV420->refreshFrameRGBA(image); m_shaderCurr = m_shaderYUV420; // 设置当前着色器为显示YUV420图片的着色器 update(); // 更新界面,触发paintGL函数 } /* 初始化RGBA的Shader */ void PlayerGLWidget::initShaderRGBA() { if(m_shaderRGBA != nullptr) { delete m_shaderRGBA; // 删除旧的着色器对象 m_shaderRGBA = nullptr; } m_shaderRGBA = new ShaderRect(); m_shaderRGBA->initShape(); // 初始化形状 /* 初始化RGBA着色器 */ QString vertexShaderFile = ":/shaderCode/vertexShaderRGBA.glsl"; QString fragmentShaderFile = ":/shaderCode/fragmentShaderRGBA.glsl"; if (!m_shaderRGBA->loadShaderCode(vertexShaderFile, fragmentShaderFile)) { SPDLOG_ERROR("加载着色器代码失败"); return; } /* 编译着色器 */ m_shaderRGBA->compileShader(); /* 初始化纹理 */ m_shaderRGBA->initTextures(); } /* 初始化YUV420的Shader */ void PlayerGLWidget::initShaderYUV420() { if(m_shaderYUV420 != nullptr) { delete m_shaderYUV420; // 删除旧的着色器对象 m_shaderYUV420 = nullptr; } m_shaderYUV420 = new ShaderYUV420(); m_shaderYUV420->initShape(); // 初始化形状 /* 初始化RGBA着色器 */ QString vertexShaderFile = ":/shaderCode/vertexShaderYUV420.glsl"; QString fragmentShaderFile = ":/shaderCode/fragmentShaderYUV420.glsl"; if (!m_shaderYUV420->loadShaderCode(vertexShaderFile, fragmentShaderFile)) { SPDLOG_ERROR("加载着色器代码失败"); return; } /* 编译着色器 */ m_shaderYUV420->compileShader(); /* 初始化纹理 */ m_shaderYUV420->initTextures(); } void PlayerGLWidget::initializeGL() { SPDLOG_DEBUG("编译着色器..."); /* 初始化OpenGL函数,OpenGL的函数是在运行时才确定函数指针的 */ initializeOpenGLFunctions(); /* 初始化显示RGBA图片的着色器 */ initShaderRGBA(); /* 初始化显示YUV420图片的着色器 */ initShaderYUV420(); SPDLOG_DEBUG("着色器编译完成"); m_isInit = true; // 标记OpenGL已经初始化完成 } void PlayerGLWidget::resizeGL(int w, int h) { /* 设置视口 */ glViewport(0, 0, w, h); /* 设置投影矩阵 */ // m_shaderObj->setProjectionMatrix(w, h); // SPDLOG_INFO("resizeGL: width = {}, height = {}", w, h); } void PlayerGLWidget::paintGL() { /* glClearColor函数是一个状态设置函数,而glClear函数则是一个状态使用的函数, * 它使用了当前的状态来获取应该清除为的颜色。 */ glClearColor(0.1f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); if(m_shaderCurr == nullptr) { // SPDLOG_WARN("当前着色器对象为空"); return; } m_shaderCurr->useShader(); // 使用着色器 m_shaderCurr->drawShape(); // 绘制图形 }