Browse Source

V0.7.10
1、封装完成了显示RGB图片的Shader类

Apple 2 weeks ago
parent
commit
6948c82d59

+ 1 - 1
External

@@ -1 +1 @@
-Subproject commit 00488484172ab54906da1dcc5fc5148211b48974
+Subproject commit de168bfdac56a7cf68c7478629f3925991b9fac2

+ 28 - 1
demo/VideoPlayerGL/GLShader/ShaderBase.cpp

@@ -179,7 +179,34 @@ bool ShaderBase::createTexture(const QString &imageFile, const QString uniformNa
     
     texture->generateMipMaps(); // 生成多级渐远纹理
 
-    printGLerror("ShaderBase::createTexture");
+    printGLerror("ShaderBase::createTextureFile");
+    /* 将纹理存储到数组中 */
+    m_listTexture.push_back(QPair<QString, QOpenGLTexture*>(uniformName, texture));
+
+    return true;
+}
+
+/* 初始化纹理,直接传入图片 */
+bool ShaderBase::createTexture(const QImage &image, const QString uniformName)
+{
+    if(image.isNull()) {
+        SPDLOG_WARN("Texture Image is null");
+        return false;
+    }
+    QOpenGLTexture* texture = new QOpenGLTexture(QOpenGLTexture::Target2D);
+    texture->setSize(image.width(), image.height(), 1); // 设置纹理大小
+    texture->setFormat(QOpenGLTexture::RGBA8_UNorm); // 设置纹理格式
+    texture->allocateStorage(); // 分配纹理存储空间
+    texture->setData(QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, image.convertToFormat(QImage::Format_RGBA8888).bits()); // 设置纹理数据
+    /* 设置纹理参数 */
+    texture->setWrapMode(QOpenGLTexture::Repeat); // S轴环绕方式
+    texture->setMinificationFilter(QOpenGLTexture::LinearMipMapLinear); // 纹理缩小过滤方式
+    texture->setMagnificationFilter(QOpenGLTexture::Linear); // 纹理放大过滤方式
+    
+    
+    texture->generateMipMaps(); // 生成多级渐远纹理
+
+    printGLerror("ShaderBase::createTextureImage");
     /* 将纹理存储到数组中 */
     m_listTexture.push_back(QPair<QString, QOpenGLTexture*>(uniformName, texture));
 

+ 7 - 7
demo/VideoPlayerGL/GLShader/ShaderBase.h

@@ -29,6 +29,8 @@ public:
     virtual bool compileShader();
     /* 初始化纹理,返回值是生成的纹理ID */
     virtual bool createTexture(const QString &imageFile, const QString uniformName);
+    /* 初始化纹理,直接传入图片 */
+    virtual bool createTexture(const QImage &image, const QString uniformName);
     /* 清空纹理 */
     virtual void clearTexture();
 
@@ -41,13 +43,11 @@ protected:
     void printGLerror(const std::string functionName);
 
 protected:
-    // QOpenGLShader* m_vertexShaderObj = nullptr;         /* 顶点着色器对象 */
-    // QOpenGLShader* m_fragmentShaderObj = nullptr;       /* 片段着色器对象 */
-    QByteArray m_vertexShaderCode;                         /* 顶点着色器文件 */
-    QByteArray m_fragmentShaderCode;                       /* 片段着色器文件 */
-    QOpenGLShaderProgram* m_shaderProgramObj = nullptr; /* 着色器程序对象 */
-    // QMap<QString, QOpenGLTexture*> m_mapTexture;        /* uniform和纹理的映射 */
-    QList<QPair<QString, QOpenGLTexture*>> m_listTexture; /* uniform和纹理的映射 */
+    QByteArray m_vertexShaderCode;                          /* 顶点着色器文件 */
+    QByteArray m_fragmentShaderCode;                        /* 片段着色器文件 */
+    QOpenGLShaderProgram* m_shaderProgramObj = nullptr;     /* 着色器程序对象 */
+    
+    QList<QPair<QString, QOpenGLTexture*>> m_listTexture;   /* uniform和纹理的映射 */
 };
 
 

+ 8 - 0
demo/VideoPlayerGL/GLShader/ShaderRect.h

@@ -3,6 +3,12 @@
 
 #include "ShaderBase.h"
 
+/**
+ * @brief 显示矩形RGBA图片
+ * 
+ */
+
+
 class ShaderRect : public ShaderBase
 {
 public:
@@ -14,6 +20,8 @@ public:
     /* 绘制图形 */
     void drawShape() override;
 
+    
+
 private:
     GLuint m_VAO = 0;              // 顶点数组对象的ID
     GLuint m_VBO = 0;              // 顶点缓冲对象的ID

+ 36 - 28
demo/VideoPlayerGL/GLWidget/PlayerGLWidget.cpp

@@ -2,7 +2,6 @@
 #include "spdlog/spdlog.h"
 #include <qopenglext.h>
 #include <QVariant>
-#include <QDateTime>
 
 
 
@@ -13,66 +12,75 @@ 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)
+{
+    m_shaderRGBA->clearTexture(); // 清空纹理
+    m_shaderRGBA->createTexture(image, "textureRGBA"); // 创建纹理
+
+    m_shaderCurr = m_shaderRGBA; // 设置当前着色器为显示RGBA图片的着色器
+    update(); // 更新界面,触发paintGL函数
+}
 
 
 void PlayerGLWidget::initializeGL()
 {
+    SPDLOG_DEBUG("编译着色器...");
     /* 初始化OpenGL函数,OpenGL的函数是在运行时才确定函数指针的 */
     initializeOpenGLFunctions();
 
-    m_shaderObj = new ShaderRect();
+    /* 初始化显示RGBA图片的着色器 */
+    m_shaderRGBA = new ShaderRect();
+
+    m_shaderRGBA->initShape(); // 初始化形状
 
-    m_VAO1 = m_shaderObj->initShape(); // 初始化形状
-    if(m_VAO1 == 0) 
-    {
-        SPDLOG_ERROR("初始化形状失败");
-        return;
-    }
     /* 初始化着色器 */
-    QString vertexShaderFile = ":/shader/vertexShader.glsl";
-    QString fragmentShaderFile = ":/shader/fragmentShader.glsl";
-    if (!m_shaderObj->loadShaderCode(vertexShaderFile, fragmentShaderFile)) 
+    QString vertexShaderFile = ":/shaderCode/vertexShaderRGBA.glsl";
+    QString fragmentShaderFile = ":/shaderCode/fragmentShaderRGBA.glsl";
+    if (!m_shaderRGBA->loadShaderCode(vertexShaderFile, fragmentShaderFile)) 
     {
         SPDLOG_ERROR("加载着色器代码失败");
         return;
     }
     /* 编译着色器 */
-    m_shaderObj->compileShader();
-    /* 创建纹理 */
-    QString imageFile1 = QString(":/Image/image/1.jpg");
-    QString imageFile2 = QString(":/Image/image/awesomeface.png");
+    m_shaderRGBA->compileShader();
 
-    if (!m_shaderObj->createTexture(imageFile1, "ourTexture1")) 
-    {
-        SPDLOG_ERROR("创建纹理失败");
-        return;
-    }
-    if (!m_shaderObj->createTexture(imageFile2, "ourTexture2")) 
-    {
-        SPDLOG_ERROR("创建纹理失败");
-        return;
-    }
 
+    SPDLOG_DEBUG("着色器编译完成");
 }
 
 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_shaderObj->useShader(); // 使用着色器
-    m_shaderObj->drawShape(); // 绘制图形
+    m_shaderCurr->useShader(); // 使用着色器
+    m_shaderCurr->drawShape(); // 绘制图形
     
 }

+ 6 - 2
demo/VideoPlayerGL/GLWidget/PlayerGLWidget.h

@@ -23,6 +23,9 @@ public:
     explicit PlayerGLWidget(QWidget *parent = nullptr);
     ~PlayerGLWidget();
 
+    /* 显示RGBA图片 */
+    void showOneRGBAImage(const QImage& image);
+    
 
 private:
  
@@ -33,9 +36,10 @@ protected:
 
 private:
 
-    GLuint m_VAO1 = 0; // 顶点数组对象的ID
+    // GLuint m_VAO1 = 0; // 顶点数组对象的ID
     
-    ShaderBase* m_shaderObj = nullptr; // 着色器对象
+    ShaderBase* m_shaderCurr = nullptr;     /* 当前使用的着色器对象 */
+    ShaderBase* m_shaderRGBA = nullptr;     /* 显示RGBA图片的着色器对象 */
 
 };
 

+ 1 - 5
demo/VideoPlayerGL/res.qrc

@@ -1,10 +1,6 @@
 <RCC>
-    <qresource prefix="/Image">
+    <qresource prefix="/">
         <file>image/1.jpg</file>
         <file>image/awesomeface.png</file>
     </qresource>
-    <qresource prefix="/">
-        <file>shader/vertexShader.glsl</file>
-        <file>shader/fragmentShader.glsl</file>
-    </qresource>
 </RCC>

+ 6 - 0
demo/VideoPlayerGL/resShaderCode.qrc

@@ -0,0 +1,6 @@
+<RCC>
+    <qresource prefix="/">
+        <file>shaderCode/vertexShaderRGBA.glsl</file>
+        <file>shaderCode/fragmentShaderRGBA.glsl</file>
+    </qresource>
+</RCC>

+ 0 - 0
demo/VideoPlayerGL/shader/fragmentShader.glsl → demo/VideoPlayerGL/shaderCode/fragmentShader.glsl


+ 14 - 0
demo/VideoPlayerGL/shaderCode/fragmentShaderRGBA.glsl

@@ -0,0 +1,14 @@
+#version 330 core
+
+in vec3 vertexColor;    //输入颜色数据
+in vec2 TexCoord;       //输入纹理坐标数据
+
+out vec4 FragColor;     //输出颜色数据
+
+uniform sampler2D textureRGBA; //纹理采样器
+
+void main()
+{
+    //FragColor = vec4(1,0,0,1);
+    FragColor = texture(textureRGBA, TexCoord);
+}

+ 0 - 0
demo/VideoPlayerGL/shader/vertexShader.glsl → demo/VideoPlayerGL/shaderCode/vertexShader.glsl


+ 15 - 0
demo/VideoPlayerGL/shaderCode/vertexShaderRGBA.glsl

@@ -0,0 +1,15 @@
+#version 330 core
+layout(location = 0) in vec3 aPos;
+layout(location = 1) in vec3 aColor;
+layout(location = 2) in vec2 aTexCoord; // 纹理坐标
+
+out vec3 vertexColor;       //向片段着色器传递颜色数据
+out vec2 TexCoord;          //向片段着色器传递纹理坐标数据
+
+void main()
+{
+    gl_Position = vec4(aPos, 1.0);
+    vertexColor = aColor;
+    /* 传递纹理数据,并将垂直坐标翻转 */
+    TexCoord = vec2(aTexCoord.x, 1.0 - aTexCoord.y);
+}

+ 1 - 1
demo/VideoPlayerGL/widget.cpp

@@ -24,7 +24,7 @@ Widget::Widget(QWidget *parent)
 
     connect(&m_timer, &QTimer::timeout, this, [=]() {
         // SPDLOG_DEBUG("刷新一帧");
-        m_playerGLWidget->update();
+        m_playerGLWidget->showOneRGBAImage(QImage(":/image/1.jpg")); // 显示一张测试图片
     });
     m_timer.setSingleShot(false);
     m_timer.start(10); // 60 FPS