首页 > 其他分享 >qtav shader处理

qtav shader处理

时间:2022-08-25 18:28:09浏览次数:55  
标签:frag const vert 处理 shader qtav prepend video

链接shader,标准opengl shader处理过程

bool VideoShader::build(QOpenGLShaderProgram *shaderProgram)
{
     if (shaderProgram->isLinked()) {
         qWarning("Shader program is already linked");
     }
     shaderProgram->removeAllShaders();
     shaderProgram->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShader());
     shaderProgram->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShader());

。。。

}


vertexShader这里把模板shaders/video.vert"));, 替换掉里面的 %userHeader%*,

const char* VideoShader::vertexShader() const
{
     DPTR_D(const VideoShader);
     // because we have to modify the shader, and shader source must be kept, so read the origin
     d.vert = shaderSourceFromFile(QStringLiteral("shaders/video.vert"));
     QByteArray& vert = d.vert;
     if (vert.isEmpty()) {
         qWarning("Empty vertex shader!");
         return 0;
     }
     if (textureTarget() == GL_TEXTURE_RECTANGLE && d.video_format.isPlanar()) {
         vert.prepend("#define MULTI_COORD\n");
#if YUVA_DONE
         if (d.video_format.hasAlpha())
             vert.prepend("#define HAS_ALPHA\n");
#endif
     }
     vert.prepend(OpenGLHelper::compatibleShaderHeader(QOpenGLShader::Vertex));

    if (userShaderHeader(QOpenGLShader::Vertex)) {
         QByteArray header("*/");
         header.append(userShaderHeader(QOpenGLShader::Vertex));
         header += "/*";
         vert.replace("%userHeader%", header);
     }

#ifdef QTAV_DEBUG_GLSL
     QString s(vert);
     s = OpenGLHelper::removeComments(s);
     qDebug() << s.toUtf8().constData();
#endif //QTAV_DEBUG_GLSL
     return vert.constData();
}

fragmentShader 这里把模板shaders/planar.f.glsl, 替换掉里面的 %userHeader%*, %userSample% 和 %userPostProcess% 部分内容

const char* VideoShader::fragmentShader() const
{
     DPTR_D(const VideoShader);
     // because we have to modify the shader, and shader source must be kept, so read the origin
     if (d.video_format.isPlanar()) {
         d.planar_frag = shaderSourceFromFile(QStringLiteral("shaders/planar.f.glsl"));
     } else {
         d.packed_frag = shaderSourceFromFile(QStringLiteral("shaders/packed.f.glsl"));
     }
     QByteArray& frag = d.video_format.isPlanar() ? d.planar_frag : d.packed_frag;
     if (frag.isEmpty()) {
         qWarning("Empty fragment shader!");
         return 0;
     }
     const int nb_planes = d.video_format.planeCount();
     if (nb_planes == 2) //TODO: nv21 must be swapped
         frag.prepend("#define IS_BIPLANE\n");
     if (OpenGLHelper::hasRG() && !OpenGLHelper::useDeprecatedFormats())
         frag.prepend("#define USE_RG\n");
     const bool has_alpha = d.video_format.hasAlpha();
     if (d.video_format.isPlanar()) {
         const int bpc = d.video_format.bitsPerComponent();
         if (bpc > 8) {
             //// has and use 16 bit texture (r16 for example): If channel depth is 16 bit, no range convertion required. Otherwise, must convert to color.r*(2^16-1)/(2^bpc-1)
             if (OpenGLHelper::depth16BitTexture() < 16 || !OpenGLHelper::has16BitTexture() || d.video_format.isBigEndian())
                 frag.prepend("#define CHANNEL16_TO8\n");
         }
#if YUVA_DONE
         if (has_alpha)
             frag.prepend("#define HAS_ALPHA\n");
#endif
     } else {
         if (has_alpha)
             frag.prepend("#define HAS_ALPHA\n");
         if (d.video_format.isXYZ())
             frag.prepend("#define XYZ_GAMMA\n");
     }

    if (d.texture_target == GL_TEXTURE_RECTANGLE) {
         frag.prepend("#extension GL_ARB_texture_rectangle : enable\n"
                      "#define sampler2D sampler2DRect\n");
         if (OpenGLHelper::GLSLVersion() < 140)
             frag.prepend("#undef texture\n"
                         "#define texture texture2DRect\n"
                         );
         frag.prepend("#define MULTI_COORD\n");
     }
     frag.prepend(OpenGLHelper::compatibleShaderHeader(QOpenGLShader::Fragment));

    QByteArray header("*/");
     if (userShaderHeader(QOpenGLShader::Fragment))
         header += QByteArray(userShaderHeader(QOpenGLShader::Fragment));
     header += "\n";
     header += "uniform vec2 u_texelSize[" + QByteArray::number(nb_planes) + "];\n";
     header += "uniform vec2 u_textureSize[" + QByteArray::number(nb_planes) + "];\n";
     header += "/*";
     frag.replace("%userHeader%", header);

    if (userSample()) {
         QByteArray sample_code("*/\n#define USER_SAMPLER\n");
         sample_code += QByteArray(userSample());
         sample_code += "/*";
         frag.replace("%userSample%", sample_code);
     }

    if (userPostProcess()) {
         QByteArray pp_code("*/");
         pp_code += QByteArray(userPostProcess()); //why the content is wrong sometimes if no ctor?
         pp_code += "/*";
        frag.replace("%userPostProcess%", pp_code);
     }
     frag.replace("%planes%", QByteArray::number(nb_planes));
#ifdef QTAV_DEBUG_GLSL
     QString s(frag);
     s = OpenGLHelper::removeComments(s);
     qDebug() << s.toUtf8().constData();
#endif //QTAV_DEBUG_GLSL
     return frag.constData();//返回组装好的frag
}


VideoShader 里面可以定制的部分:

/// User configurable shader APIs BEGIN
/*!
  * Keywords will be replaced in user shader code:
  * %planes% => plane count
  * Uniforms can be used: (N: 0 ~ planes-1)
  * u_Matrix (vertex shader),
  * u_TextureN, v_TexCoordsN, u_texelSize(array of vec2, normalized), u_textureSize(array of vec2), u_opacity, u_c(channel map), u_colorMatrix, u_to8(vec2, computing 16bit value with 8bit components)
  * Vertex shader in: a_Position, a_TexCoordsN (see attributeNames())
  * Vertex shader out: v_TexCoordsN
  */
/*!
  * \brief userShaderHeader
  * Must add additional uniform declarations here
  */
virtual const char* userShaderHeader(QOpenGLShader::ShaderType) const {return 0;}
/*!
  * \brief setUserUniformValues
  * Call program()->setUniformValue(...) here
  * You can upload a texture for blending in userPostProcess(),
  * or LUT texture used by userSample() or userPostProcess() etc.
  * \return false if use use setUserUniformValue(Uniform& u), true if call program()->setUniformValue() here
  */
virtual bool setUserUniformValues() {return false;}
/*!
  * \brief setUserUniformValue
  * Update value of uniform u. Call Uniform.set(const T& value, int count); VideoShader will call Uniform.setGL() later if value is changed
  */
virtual void setUserUniformValue(Uniform&) {}
/*!
  * \brief userSample
  * Fragment shader only. The custom sampling function to replace texture2D()/texture() (replace %1 in shader).
  * \code
  *     vec4 sample2d(sampler2D tex, vec2 pos, int plane) { .... }
  * \endcode
  * The 3rd parameter can be used to get texel/texture size of a given plane u_texelSize[plane]/textureSize[plane];
  * Convolution of result rgb and kernel has the same effect as convolution of input yuv and kernel, ensured by
  * Σ_i c_i* Σ_j k_j*x_j=Σ_i k_i* Σ_j c_j*x_j
  * Because because the input yuv is from a real rgb color, so no clamp() is required for the transformed color.
  */
virtual const char* userSample() const { return 0;}
/*!
  * \brief userPostProcess
  * Fragment shader only. Process rgb color
  * TODO: parameter ShaderType?
  */
virtual const char* userPostProcess() const {return 0;}
/// User configurable shader APIs END

标签:frag,const,vert,处理,shader,qtav,prepend,video
From: https://www.cnblogs.com/cute/p/16625265.html

相关文章

  • Pandas数据处理
    通用方法 pandas.melt =>选择一个列变量为列索引值为列数据dfABC0a121b342c56pd.melt(df,id_vars=['A'],value_vars=['B'],var......
  • 批处理文件管理员启动cmd运行程序
    @ECHOOFFsetlocalEnableDelayedExpansiontitle添加服务配置PUSHD%~DP0&cd/d"%~dp0"%1%2mshtavbscript:createobject("shell.application").shellexecu......
  • 后台返回10万条数据时,用什么方法处理
    (1)1.主要技术是应用虚拟列表2 什么是虚拟列表虚拟列表就是只对可见区域进行渲染,对非可见区域中的数据不渲染或部分渲染,以实现减少消耗,提高用户体验的技术。它是长列表......
  • java8流式处理
    查找allMatch,是否全部都满足指定的参数行为,返回值为布尔值,如:booleanallOver18=students.stream().allMatch(student->student.getAge()>=18);noneMatch,是否不存......
  • Sass预处理器 常见函数的基本使用
    Sass提供了许多内置模块,其中包含有用的函数(以及mixin)。这些模块可以像任何用户定义的样式表一样使用@use规则加载,它们的函数可以像任何其他模块成员一样调用。所有内置模块......
  • Q:windows系统如何开机启动批处理脚本
    方法11、win+r输入gpedit.msc进入本地策略管理器  2、点击windows设置下的脚本(启动/关机),然后双击启动。   3、点击添加,然后点击浏览,选择批处理文件然后点击......
  • 学习:python 异常处理 else 和 finall 语句 自定义异常
       自定义一个异常 ......
  • 七,DRF 过滤-排序-分页-异常处理
    一过滤Filtering对于列表数据可能需要根据字段进行过滤,我们可以通过添加django-fitlter扩展来增强支持。pipinstalldjango-filter在配置文件中增加过滤后端的设置:#......
  • for循环与Iterator处理相关问题
    如下:for循环里面不要进行remove操作,for循环里remove元素后,list的下标会减小,导致遍历不完全。使用Iterator循环进行remove    end......
  • 使用@ControllerAdvice实现统一异常处理
    工作空闲之余,学习一下项目中的各种写法,今天学习实现的是项目中的统一异常处理。controller层负责的是与用户界面交互的职责,但是当controller层抛出异常,并且未能够进行tryc......