ShaderManager::ShaderManager(QOpenGLContext *ctx) :
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
    QObject(ctx)
#else
    QObject(0)
#endif
  , m_ctx(ctx)
{
}

ShaderManager::~ShaderManager()
{
    invalidated();
}

VideoShader* ShaderManager::prepareMaterial(VideoMaterial *material)
{
    const char* type = material->type();
    VideoShader *shader = shader_cache.value(type, 0);
    if (shader)
        return shader;
    qDebug("[ShaderManager] cache a new shader material type: %s", type);
    shader = material->createShader();
    shader->initialize();
    shader_cache[type] = shader;
    return shader;
}

void ShaderManager::invalidated()
{
    // TODO: thread safe required?
    qDeleteAll(shader_cache.values());
    shader_cache.clear();
}
Beispiel #2
0
void OpenGLVideo::render(const QRectF &target, const QRectF& roi, const QMatrix4x4& transform)
{
    DPTR_D(OpenGLVideo);
    Q_ASSERT(d.manager);
    Q_EMIT beforeRendering();
    DYGL(glViewport(d.rect.x(), d.rect.y(), d.rect.width(), d.rect.height())); // viewport was used in gpu filters is wrong, qt quick fbo item's is right(so must ensure setProjectionMatrixToRect was called correctly)
    const qint64 mt = d.material->type();
    if (d.material_type != mt) {
        qDebug() << "material changed: " << VideoMaterial::typeName(d.material_type) << " => " << VideoMaterial::typeName(mt);
        d.material_type = mt;
    }
    VideoShader *shader = d.user_shader;
    if (!shader)
        shader = d.manager->prepareMaterial(d.material, mt); //TODO: print shader type name if changed. prepareMaterial(,sample_code, pp_code)
    shader->update(d.material);
    d.material->setDirty(false); //
    shader->program()->setUniformValue(shader->matrixLocation(), transform*d.matrix);
    d.gr.setShaderProgram(shader->program());
    // uniform end. attribute begin
    d.bindAttributes(shader, target, roi);
    // normalize?
    const bool blending = d.material->hasAlpha();
    if (blending) {
        DYGL(glEnable(GL_BLEND));
        DYGL(glBlendFunc(GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA));
    }
    d.gr.render(&d.geometry);
    if (blending)
        DYGL(glDisable(GL_BLEND));
    // d.shader->program()->release(); //glUseProgram(0)
    d.unbindAttributes(shader);
    d.material->unbind();

    Q_EMIT afterRendering();
}
Beispiel #3
0
VideoShader* VideoMaterial::createShader() const
{
    DPTR_D(const VideoMaterial);
    VideoShader *shader = new VideoShader();
    const VideoFormat fmt(d.frame.format());
    shader->setVideoFormat(fmt);
    return shader;
}
Beispiel #4
0
VideoShader* VideoMaterial::createShader() const
{
    DPTR_D(const VideoMaterial);
    VideoShader *shader = new VideoShader();
    const VideoFormat fmt(d.frame.format());
    shader->setVideoFormat(fmt);
    //resize texture locations to avoid access format later
    return shader;
}
Beispiel #5
0
void OpenGLVideo::render(const QRectF &target, const QRectF& roi, const QMatrix4x4& transform)
{
    DPTR_D(OpenGLVideo);
    Q_ASSERT(d.manager);
    const qint64 mt = d.material->type();
    if (d.material_type != mt) {
        qDebug() << "material changed: " << VideoMaterial::typeName(d.material_type) << " => " << VideoMaterial::typeName(mt);
        d.material_type = mt;
    }
    VideoShader *shader = d.manager->prepareMaterial(d.material); //TODO: print shader type name if changed. prepareMaterial(,sample_code, pp_code)
    shader->update(d.material);
    shader->program()->setUniformValue(shader->opacityLocation(), (GLfloat)1.0);
    shader->program()->setUniformValue(shader->matrixLocation(), transform*d.matrix);
    // uniform end. attribute begin
    d.bindAttributes(shader, target, roi);
    // normalize?
    const bool blending = d.material->hasAlpha();
    if (blending) {
        DYGL(glEnable(GL_BLEND));
        DYGL(glBlendFunc(GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA));
    }
    DYGL(glDrawArrays(d.geometry.mode(), 0, d.geometry.textureVertexCount()));
    if (blending)
        DYGL(glDisable(GL_BLEND));
    // d.shader->program()->release(); //glUseProgram(0)
    d.unbindAttributes(shader);
    d.material->unbind();
}
Beispiel #6
0
void OpenGLVideo::render(const QRectF &target, const QRectF& roi, const QMatrix4x4& transform)
{
    DPTR_D(OpenGLVideo);
    Q_ASSERT(d.manager);
    VideoShader *shader = d.manager->prepareMaterial(d.material);
    shader->update(d.material);
    shader->program()->setUniformValue(shader->matrixLocation(), transform*d.matrix);
    // uniform end. attribute begin
    if (target.isValid())
        d.geometry.setRect(target, d.material->normalizedROI(roi));
    else
        d.geometry.setRect(d.rect, d.material->normalizedROI(roi));

    // normalize?
#if 1
    shader->program()->setAttributeArray(0, GL_FLOAT, d.geometry.data(0), 2, d.geometry.stride());
    shader->program()->setAttributeArray(1, GL_FLOAT, d.geometry.data(1), 2, d.geometry.stride());
#else
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
    static QGLFunctions *glf = new QGLFunctions();
    glf->initializeGLFunctions();
#else
    QOpenGLFunctions *glf = QOpenGLContext::currentContext()->functions();
#endif
    glf->glVertexAttribPointer(0, 2, GL_FLOAT, GL_TRUE, d.geometry.stride(), d.geometry.data(0));
    glf->glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, d.geometry.stride(), d.geometry.data(1));
#endif
    char const *const *attr = shader->attributeNames();
    for (int i = 0; attr[i]; ++i) {
        shader->program()->enableAttributeArray(i); //TODO: in setActiveShader
    }

   glDrawArrays(d.geometry.mode(), 0, d.geometry.vertexCount());

   // d.shader->program()->release(); //glUseProgram(0)
   for (int i = 0; attr[i]; ++i) {
       shader->program()->disableAttributeArray(i); //TODO: in setActiveShader
   }

   d.material->unbind();
}
Beispiel #7
0
void OpenGLVideo::render(const QRectF &target, const QRectF& roi, const QMatrix4x4& transform)
{
    DPTR_D(OpenGLVideo);
    Q_ASSERT(d.manager);
    VideoShader *shader = d.manager->prepareMaterial(d.material);
    shader->update(d.material);
    shader->program()->setUniformValue(shader->opacityLocation(), (GLfloat)1.0);
    shader->program()->setUniformValue(shader->matrixLocation(), transform*d.matrix);
    // uniform end. attribute begin
    d.bindAttributes(shader, target, roi);
    // normalize?
    const bool blending = d.material->hasAlpha();
    if (blending) {
        DYGL(glEnable(GL_BLEND));
        DYGL(glBlendFunc(GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA));
    }
    DYGL(glDrawArrays(d.geometry.mode(), 0, d.geometry.textureVertexCount()));
    if (blending)
        DYGL(glDisable(GL_BLEND));
    // d.shader->program()->release(); //glUseProgram(0)
    d.unbindAttributes(shader);
    d.material->unbind();
}