void GLWidgetRendererPrivate::updateShaderIfNeeded()
{
    const VideoFormat& fmt(video_frame.format());
    if (fmt != video_format) {
        qDebug("pixel format changed: %s => %s", qPrintable(video_format.name()), qPrintable(fmt.name()));
    }
    VideoMaterialType *newType = materialType(fmt);
    if (material_type == newType)
        return;
    material_type = newType;
    // http://forum.doom9.org/archive/index.php/t-160211.html
    ColorTransform::ColorSpace cs = ColorTransform::RGB;
    if (fmt.isRGB()) {
        if (fmt.isPlanar())
            cs = ColorTransform::GBR;
    } else {
        if (video_frame.width() >= 1280 || video_frame.height() > 576) //values from mpv
            cs = ColorTransform::BT709;
        else
            cs = ColorTransform::BT601;
    }
    if (!prepareShaderProgram(fmt, cs)) {
        qWarning("shader program create error...");
        return;
    } else {
        qDebug("shader program created!!!");
    }
}
Example #2
0
void BasicUsageScene::init()
{
    vao_.create();
    vao_.bind();

    prepareShaderProgram();
    prepareVertexBuffers();
}
void GLWidget::initializeGL()
{
    // get context opengl-version
    qDebug() << "Widget OpenGl: " << format().majorVersion() << "." << format().minorVersion();
    qDebug() << "Context valid: " << context()->isValid();
    qDebug() << "Really used OpenGl: " << context()->format().majorVersion() << "." << context()->format().minorVersion();
    qDebug() << "OpenGl information: VENDOR:       " << (const char*)glGetString(GL_VENDOR);
    qDebug() << "                    RENDERDER:    " << (const char*)glGetString(GL_RENDERER);
    qDebug() << "                    VERSION:      " << (const char*)glGetString(GL_VERSION);
    qDebug() << "                    GLSL VERSION: " << (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION);

    QGLFormat glFormat = QGLWidget::format();
    if ( !glFormat.sampleBuffers() )
        qWarning() << "Could not enable sample buffers";

    // Set the clear color to black
    glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );

    // Prepare a complete shader program...
    if ( !prepareShaderProgram( ":/simple.vert", ":/simple.frag" ) )
        return;

    // we need a VAO in core!
    GLuint VAO;
    PglGenVertexArrays glGenVertexArrays = (PglGenVertexArrays) context()->getProcAddress("glGenVertexArrays");
    PglBindVertexArray glBindVertexArray = (PglBindVertexArray) context()->getProcAddress("glBindVertexArray");
    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);

    // We need us some vertex data. Start simple with a triangle ;-)
    float points[] = { -0.5f, -0.5f, 0.0f, 1.0f,
                        0.5f, -0.5f, 0.0f, 1.0f,
                        0.0f,  0.5f, 0.0f, 1.0f };
    m_vertexBuffer.create();
    m_vertexBuffer.setUsagePattern( QOpenGLBuffer::StaticDraw );
    if ( !m_vertexBuffer.bind() )
    {
        qWarning() << "Could not bind vertex buffer to the context";
        return;
    }
    m_vertexBuffer.allocate( points, 3 * 4 * sizeof( float ) );

    // Bind the shader program so that we can associate variables from
    // our application to the shaders
    if ( !m_shader.bind() )
    {
        qWarning() << "Could not bind shader program to context";
        return;
    }

    // Enable the "vertex" attribute to bind it to our currently bound
    // vertex buffer.
    m_shader.setAttributeBuffer( "vertex", GL_FLOAT, 0, 4 );
    m_shader.enableAttributeArray( "vertex" );
}
Example #4
0
void GLWidgetRendererPrivate::updateTexturesIfNeeded()
{
    const VideoFormat &fmt = video_frame.format();
    bool update_textures = false;
    if (fmt != video_format) {
        update_textures = true;
        qDebug("pixel format changed: %s => %s", qPrintable(video_format.name()), qPrintable(fmt.name()));
        // http://forum.doom9.org/archive/index.php/t-160211.html
        ColorTransform::ColorSpace cs = ColorTransform::BT601;
        if (video_frame.width() >= 1280 || video_frame.height() > 576) //values from mpv
            cs = ColorTransform::BT709;
        if (!prepareShaderProgram(fmt, cs)) {
            qWarning("shader program create error...");
            return;
        } else {
            qDebug("shader program created!!!");
        }
    }
    // effective size may change even if plane size not changed
    if (update_textures
            || video_frame.bytesPerLine(0) != plane0Size.width() || video_frame.height() != plane0Size.height()
            || (plane1_linesize > 0 && video_frame.bytesPerLine(1) != plane1_linesize)) { // no need to check hieght if plane 0 sizes are equal?
        update_textures = true;
        //qDebug("---------------------update texture: %dx%d, %s", video_frame.width(), video_frame.height(), video_frame.format().name().toUtf8().constData());
        const int nb_planes = fmt.planeCount();
        texture_size.resize(nb_planes);
        texture_upload_size.resize(nb_planes);
        effective_tex_width.resize(nb_planes);
        for (int i = 0; i < nb_planes; ++i) {
            qDebug("plane linesize %d: padded = %d, effective = %d", i, video_frame.bytesPerLine(i), video_frame.effectiveBytesPerLine(i));
            qDebug("plane width %d: effective = %d", video_frame.planeWidth(i), video_frame.effectivePlaneWidth(i));
            qDebug("planeHeight %d = %d", i, video_frame.planeHeight(i));
            // we have to consider size of opengl format. set bytesPerLine here and change to width later
            texture_size[i] = QSize(video_frame.bytesPerLine(i), video_frame.planeHeight(i));
            texture_upload_size[i] = texture_size[i];
            effective_tex_width[i] = video_frame.effectiveBytesPerLine(i); //store bytes here, modify as width later
            // TODO: ratio count the GL_UNPACK_ALIGN?
            //effective_tex_width_ratio = qMin((qreal)1.0, (qreal)video_frame.effectiveBytesPerLine(i)/(qreal)video_frame.bytesPerLine(i));
        }
        plane1_linesize = 0;
        if (nb_planes > 1) {
            texture_size[0].setWidth(texture_size[1].width() * effective_tex_width[0]/effective_tex_width[1]);
            // height? how about odd?
            plane1_linesize = video_frame.bytesPerLine(1);
        }
        effective_tex_width_ratio = (qreal)video_frame.effectiveBytesPerLine(nb_planes-1)/(qreal)video_frame.bytesPerLine(nb_planes-1);
        qDebug("effective_tex_width_ratio=%f", effective_tex_width_ratio);
        plane0Size.setWidth(video_frame.bytesPerLine(0));
        plane0Size.setHeight(video_frame.height());
    }
    if (update_textures) {
        initTextures(fmt);
    }
}
void GLES2Lesson::render() {
    clearBuffers();
    prepareShaderProgram();
    setPerspective();
    resetTransformMatrices();

    drawGeometry(vboCubeVertexDataIndex,
                 vboCubeVertexIndicesIndex,
                 36,
                 cubeTransformMatrix
    );
}
Example #6
0
void GLWidget::initializeGL()
{
 QGLFormat glFormat = QGLWidget::format();
 if ( !glFormat.sampleBuffers() )
 qWarning() << "Could not enable sample buffers";

 // Set the clear color to black
 glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );

 // Prepare a complete shader program…
 if ( !prepareShaderProgram( ":/simple.vert", ":/simple.frag" ) )
 return;

 // We need us some vertex data. Start simple with a triangle ;-)
 float points[] = {-0.5f, -0.5f, 0.0f, 1.0f,
 0.5f, -0.5f, 0.0f, 1.0f,
 0.0f, 0.5f, 0.0f, 1.0f};
 m_vertexBuffer.create();
 m_vertexBuffer.setUsagePattern( QGLBuffer::StaticDraw );
 if ( !m_vertexBuffer.bind() )
 {
 qWarning() << "Could not bind vertex buffer to the context";
 return;
 }
 m_vertexBuffer.allocate( points, 3 * 4 * sizeof( float ) );

 // Bind the shader program so that we can associate variables from
 // our application to the shaders
 if ( !m_shader.bind() )
 {
 qWarning() << "Could not bind shader program to context";
 return;
 }

 // Enable the "vertex" attribute to bind it to our currently bound
 // vertex buffer.
 m_shader.setAttributeBuffer( "vertex", GL_FLOAT, 0, 4 );
 m_shader.enableAttributeArray( "vertex" );

 /*glfuncs = m_context->versionFunctions();
 if (!glfuncs) {
   qDebug()<<"Не поддерживается версия OpenGL этой программой.";
   exit(1); //Хъюстон, у нас проблема номер раз
 }
 glfuncs->initializeOpenGLFunctions();

 uint vao;
 glGenVertexArrays(1, &vao);
 glBindVertexArray(vao);//*/

 qDebug() << QString((const char*)glGetString(GL_VERSION)) << "\n" << QString((const char*)glGetString(GL_VENDOR))<< "\n" << QString((const char*)glGetString(GL_RENDERER));//<< "\n" << glGetString(GL_EXTENTIONS);

}
Example #7
0
ncGraphics::ncGraphics()
:   ibo_(QOpenGLBuffer::IndexBuffer)
,   vbo_(QOpenGLBuffer::VertexBuffer) {
    indexes_    = new GLushort[VERTEX_BUFFER_SIZE*6/4];
    vertArray_  = new ncVertex[VERTEX_BUFFER_SIZE];

    GLushort* iptr  = indexes_;
    GLushort n      = 0;
    for (int i=0; i<VERTEX_BUFFER_SIZE/4; ++i) {
        *iptr++ = n;
        *iptr++ = n+1;
        *iptr++ = n+2;
        *iptr++ = n+2;
        *iptr++ = n+3;
        *iptr++ = n;
        n+=4;
    }

    vao_.create();

    ibo_.create();
    ibo_.bind();
    ibo_.setUsagePattern(QOpenGLBuffer::StaticDraw);
    ibo_.allocate(indexes_, sizeof(GLushort)*VERTEX_BUFFER_SIZE*6/4);
    ibo_.release();

    vbo_.create();
    vbo_.bind();
    vbo_.setUsagePattern(QOpenGLBuffer::DynamicDraw);
    vbo_.allocate(sizeof(ncVertex)*VERTEX_BUFFER_SIZE);
    vbo_.release();

    program_ = new QOpenGLShaderProgram();
    if (!prepareShaderProgram(":/vertex.glsl", ":/fragment.glsl")) {
        return;
    }

    numPrim_        = 0;
    curPrimType_    = PRIM_QUADS;
    curBlendMode_   = NC_BLEND_DEFAULT;
    curTexture_     = 0;
    program_->bind();
    program_->setUniformValue("texIsInvalid", true);
    program_->release();

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
    void GLES2Lesson::render() {
        clearBuffers();
        prepareShaderProgram();
        setPerspective();
        resetTransformMatrices();

        for (auto &star : mStars) {

            glUniform4fv(fragmentTintPosition, 1, &star->mColor[0]);

            drawGeometry(vboCubeVertexDataIndex,
                         vboCubeVertexIndicesIndex,
                         4,
                         star->mTransform
            );
        }
    }
Example #9
0
void TextRenderer::renderImmediate(int fbWidth, int fbHeight, float x, float y, const std::string &text, FontType fontType, HAlign hAlign, VAlign vAlign) {
   if (pixelDensity != targetPixelDensity) {
      loadFontAtlas(targetPixelDensity);
   }

   ASSERT(atlas, "Font atlas not loaded");
   if (!atlas) {
      return;
   }

   ASSERT(atlas->fontRangeMap.count(fontType) != 0, "Invalid font type");
   if (atlas->fontRangeMap.count(fontType) == 0) {
      return;
   }
   FontRange &fontRange = atlas->fontRangeMap.at(fontType);

   float width = 0.0f, height = fontRange.fontSize;
   processText(text, fontRange, atlas->bitmapSize, &width, &height, [](const stbtt_aligned_quad &q){});

   float xOffset = 0.0f;
   if (hAlign == HAlign::Center) {
      xOffset = -width / 2.0f;
   } else if (hAlign == HAlign::Right) {
      xOffset = -width;
   }

   float yOffset = 0.0f;
   if (vAlign == VAlign::Center) {
      yOffset = height * 0.25f; // Approximate (offset from baseline)
   } else if (vAlign == VAlign::Top) {
      yOffset = height;
   }

   prepareShaderProgram(*gameObject, fbWidth, fbHeight);

   glDisable(GL_DEPTH_TEST);

   float absX = fbWidth * x;
   float absY = fbHeight * y;
   processText(text, fontRange, atlas->bitmapSize, &absX, &absY, [&](const stbtt_aligned_quad &q) {
      renderQuad(*gameObject, *mesh, q, xOffset, yOffset);
   });

   glEnable(GL_DEPTH_TEST);
}
    void GLES2Lesson::render() {
        clearBuffers();
        prepareShaderProgram();
        setPerspective();
        resetTransformMatrices();

        if (enableBlending) {
            enableAlphaBlending();
        } else {
            disableAlfaBlending();
        }


        drawGeometry(vboCubeVertexDataIndex,
                     vboCubeVertexIndicesIndex,
                     36,
                     cubeTransformMatrix
        );
    }
void GLES2Lesson::render() {

    clearBuffers();
    prepareShaderProgram();
    setPerspective();

    drawGeometry( triangleVertices,
                  triangleColours,
                  triangleIndices,
                  3,
                  triangleTransformMatrix
                );

    drawGeometry( squareVertices,
                  squareColours,
                  squareIndices,
                  4,
                  squareTransformMatrix
                );
}
Example #12
0
SPtr<Texture> TextRenderer::renderToTexture(const std::string &text, Resolution *resolution, FontType fontType) {
   if (pixelDensity != targetPixelDensity) {
      loadFontAtlas(targetPixelDensity);
   }

   ASSERT(atlas, "Font atlas not loaded");
   if (!atlas) {
      return nullptr;
   }

   ASSERT(atlas->fontRangeMap.count(fontType) != 0, "Invalid font type");
   if (atlas->fontRangeMap.count(fontType) == 0) {
      return nullptr;
   }
   FontRange &fontRange = atlas->fontRangeMap.at(fontType);

   float width = 0.0f, height = fontRange.fontSize;
   processText(text, fontRange, atlas->bitmapSize, &width, &height, [](const stbtt_aligned_quad &q){});

   prepareShaderProgram(*gameObject, width, height);
   framebuffer->init(glm::ceil(width), glm::ceil(height));

   framebuffer->use();
   glClear(GL_COLOR_BUFFER_BIT);
   glDisable(GL_DEPTH_TEST);

   float x = 0.0f, y = 0.0f;
   processText(text, fontRange, atlas->bitmapSize, &x, &y, [&](const stbtt_aligned_quad &q) {
      renderQuad(*gameObject, *mesh, q, 0.0f, height * 0.75f);
   });

   glEnable(GL_DEPTH_TEST);
   framebuffer->disable();

   if (resolution) {
      resolution->width = width;
      resolution->height = height;
   }

   return framebuffer->getTexture();
}
Example #13
0
void GLWidgetRendererPrivate::upload(const QRect &roi)
{
    const VideoFormat &fmt = video_frame.format();
    bool update_textures = false;
    if (fmt != video_format) {
        update_textures = true;
        qDebug("pixel format changed: %s => %s", qPrintable(video_format.name()), qPrintable(fmt.name()));
        if (!prepareShaderProgram(fmt)) {
            qWarning("shader program create error...");
            return;
        } else {
            qDebug("shader program created!!!");
        }
    }
    // effective size may change even if plane size not changed
    if (update_textures || video_frame.size() != plane0Size) { //
        update_textures = true;
        //qDebug("---------------------update texture: %dx%d, %s", video_frame.width(), video_frame.height(), video_frame.format().name().toUtf8().constData());
        texture_size.resize(fmt.planeCount());
        effective_tex_width.resize(fmt.planeCount());
        for (int i = 0; i < fmt.planeCount(); ++i) {
            qDebug("plane linesize %d: padded = %d, effective = %d", i, video_frame.bytesPerLine(i), video_frame.effectiveBytesPerLine(i));
            qDebug("plane width %d: effective = %d", video_frame.planeWidth(i), video_frame.effectivePlaneWidth(i));
            qDebug("planeHeight %d = %d", i, video_frame.planeHeight(i));
            // we have to consider size of opengl format. set bytesPerLine here and change to width later
            texture_size[i] = QSize(video_frame.bytesPerLine(i), video_frame.planeHeight(i));
            effective_tex_width[i] = video_frame.effectiveBytesPerLine(i); //store bytes here, modify as width later
            // TODO: ratio count the GL_UNPACK_ALIGN?
            effective_tex_width_ratio = qMin((qreal)1.0, (qreal)video_frame.effectiveBytesPerLine(i)/(qreal)video_frame.bytesPerLine(i));
        }
        qDebug("effective_tex_width_ratio=%f", effective_tex_width_ratio);
        plane0Size = video_frame.size();
    }
    if (update_textures) {
        initTextures(fmt);
    }

    for (int i = 0; i < video_frame.planeCount(); ++i) {
        uploadPlane(i, internal_format[i], data_format[i], roi);
    }
}
void Scene::initialize()
{
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

    // Récupération des fonctions d'OpenGL 3.1
    m_funcs = m_context->versionFunctions<QOpenGLFunctions_3_1>();

    if ( ! m_funcs )
    {
        qFatal("Requires OpenGL >= 3.1");
        exit(1);
    }

    m_funcs->initializeOpenGLFunctions();

    // Charge, compile et link le Vertex et Fragment Shader
    prepareShaderProgram();

    // Initialisation des buffers
    prepareVertexBuffers();
    prepareIndexBuffer();
}
Example #15
0
void GlWidget::initializeGL()
{
  glEnable(GL_DEPTH_TEST);
  glEnable(GL_CULL_FACE);

  qglClearColor(QColor(Qt::lightGray));

  if (!prepareShaderProgram( ":/vertex_shader.vert", ":/fragment_shader.frag")) {
    return;
  }

  vertices
    << QVector3D(-0.5f, -0.5f,  0.5f) << QVector3D( 0.5f, -0.5f,  0.5f) << QVector3D( 0.5f,  0.5f,  0.5f) // Front
    << QVector3D( 0.5f,  0.5f,  0.5f) << QVector3D(-0.5f,  0.5f,  0.5f) << QVector3D(-0.5f, -0.5f,  0.5f)
    << QVector3D( 0.5f, -0.5f, -0.5f) << QVector3D(-0.5f, -0.5f, -0.5f) << QVector3D(-0.5f,  0.5f, -0.5f) // Back
    << QVector3D(-0.5f,  0.5f, -0.5f) << QVector3D( 0.5f,  0.5f, -0.5f) << QVector3D( 0.5f, -0.5f, -0.5f)
    << QVector3D(-0.5f, -0.5f, -0.5f) << QVector3D(-0.5f, -0.5f,  0.5f) << QVector3D(-0.5f,  0.5f,  0.5f) // Left
    << QVector3D(-0.5f,  0.5f,  0.5f) << QVector3D(-0.5f,  0.5f, -0.5f) << QVector3D(-0.5f, -0.5f, -0.5f)
    << QVector3D( 0.5f, -0.5f,  0.5f) << QVector3D( 0.5f, -0.5f, -0.5f) << QVector3D( 0.5f,  0.5f, -0.5f) // Right
    << QVector3D( 0.5f,  0.5f, -0.5f) << QVector3D( 0.5f,  0.5f,  0.5f) << QVector3D( 0.5f, -0.5f,  0.5f)
    << QVector3D(-0.5f,  0.5f,  0.5f) << QVector3D( 0.5f,  0.5f,  0.5f) << QVector3D( 0.5f,  0.5f, -0.5f) // Top
    << QVector3D( 0.5f,  0.5f, -0.5f) << QVector3D(-0.5f,  0.5f, -0.5f) << QVector3D(-0.5f,  0.5f,  0.5f)
    << QVector3D(-0.5f, -0.5f, -0.5f) << QVector3D( 0.5f, -0.5f, -0.5f) << QVector3D( 0.5f, -0.5f,  0.5f) // Bottom
    << QVector3D( 0.5f, -0.5f,  0.5f) << QVector3D(-0.5f, -0.5f,  0.5f) << QVector3D(-0.5f, -0.5f, -0.5f);

  colors
    << QVector3D(0.5f, 0.3f, 0.3f) << QVector3D(0.5f, 0.3f, 0.3f) << QVector3D(0.5f, 0.3f, 0.3f) // Front
    << QVector3D(0.5f, 0.3f, 0.3f) << QVector3D(0.5f, 0.3f, 0.3f) << QVector3D(0.5f, 0.3f, 0.3f)
    << QVector3D(0.5f, 0.3f, 0.3f) << QVector3D(0.5f, 0.3f, 0.3f) << QVector3D(0.5f, 0.3f, 0.3f) // Back
    << QVector3D(0.5f, 0.3f, 0.3f) << QVector3D(0.5f, 0.3f, 0.3f) << QVector3D(0.5f, 0.3f, 0.3f)
    << QVector3D(0.1f, 0.5f, 0.3f) << QVector3D(0.1f, 0.5f, 0.3f) << QVector3D(0.1f, 0.5f, 0.3f) // Left
    << QVector3D(0.1f, 0.5f, 0.3f) << QVector3D(0.1f, 0.5f, 0.3f) << QVector3D(0.1f, 0.5f, 0.3f)
    << QVector3D(0.1f, 0.5f, 0.3f) << QVector3D(0.1f, 0.5f, 0.3f) << QVector3D(0.1f, 0.5f, 0.3f) // Right
    << QVector3D(0.1f, 0.5f, 0.3f) << QVector3D(0.1f, 0.5f, 0.3f) << QVector3D(0.1f, 0.5f, 0.3f)
    << QVector3D(0.1f, 0.3f, 0.5f) << QVector3D(0.1f, 0.3f, 0.5f) << QVector3D(0.1f, 0.3f, 0.5f) // Top
    << QVector3D(0.1f, 0.3f, 0.5f) << QVector3D(0.1f, 0.3f, 0.5f) << QVector3D(0.1f, 0.3f, 0.5f)
    << QVector3D(0.1f, 0.3f, 0.5f) << QVector3D(0.1f, 0.3f, 0.5f) << QVector3D(0.1f, 0.3f, 0.5f) // Bottom
    << QVector3D(0.1f, 0.3f, 0.5f) << QVector3D(0.1f, 0.3f, 0.5f) << QVector3D(0.1f, 0.3f, 0.5f);
}
void ScreenWidget::initializeGL(){
    glClearColor(1,1,1,1);
    glClear(GL_COLOR_BUFFER_BIT);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0,1280,0,720,-1,1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glDisable(GL_DEPTH_TEST);
    //static GLfloat lightPosition[4] = { 0, 0, 10, 1.0 };
    //glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
    //QDir::setCurrent(QCoreApplication::applicationDirPath());

    QDir absoluteDirectory = QDir::currentPath();
    //qDebug() << absoluteDirectory.cdUp();
    qDebug() << absoluteDirectory.cd("Shader");
    QString vertexShader = absoluteDirectory.path() + "/vertexShader.vsh";
    QString fragmentShader = absoluteDirectory.path() + "/fragmentShader.fsh";
    qDebug() << vertexShader << " AND " << fragmentShader;

    QFileInfo checkFile(vertexShader);
    QFileInfo checkFile2(fragmentShader);
    if(!checkFile.exists()){
        qDebug() << "Can't find the file...";
    }else{
        qDebug() << "The file exists!";
    }

    if(!checkFile2.exists()){
        qDebug() << "Can't find the file...";
    }else{
        qDebug() << "The file2 exists!";
    }

    if (!prepareShaderProgram(vertexShader, fragmentShader)){
        return;
    }

}
    void GLES2Lesson::render() {
        clearBuffers();
        prepareShaderProgram();
        setPerspective();
        resetTransformMatrices();

        glUniformMatrix4fv(modelMatrixAttributePosition, 1, false, &glm::mat4(1.0f)[0][0]);
        checkGlError("before drawing");


        glEnableVertexAttribArray(vertexAttributePosition);
        glEnableVertexAttribArray(textureCoordinatesAttributePosition);

        for (auto &pair  : mBatches) {
            glBindTexture(GL_TEXTURE_2D, pair.first);
            pair.second->draw(vertexAttributePosition, textureCoordinatesAttributePosition);
        }

        glDisableVertexAttribArray(vertexAttributePosition);
        glDisableVertexAttribArray(textureCoordinatesAttributePosition);


        checkGlError("after drawing");
    }
void SimpleTextureScene::initialise()
{
    m_funcs = m_context->functions();
    m_funcs->initializeOpenGLFunctions();

    // mplayer's output is definitely easier to parse than ffmpeg's...
    QProcess movieFileParameters;
    movieFileParameters.start("mplayer",
                              QStringList()
                              << "-identify"
                              << "-vo" << "null"
                              << "-ao" << "null"
                              << "-frames" << "0"
                              << "-vc" << "null"
                              << "--"
                              << m_movieFile,
                              QIODevice::ReadOnly);
    movieFileParameters.waitForFinished();
    QString mplayerOutput = QString::fromLocal8Bit(movieFileParameters.readAllStandardOutput());

    QRegularExpression widthRe("^ID_VIDEO_WIDTH=(.*)", QRegularExpression::MultilineOption);
    QRegularExpressionMatch widthMatch = widthRe.match(mplayerOutput);
    if (widthMatch.hasMatch())
        m_frameSize.setWidth(widthMatch.captured(1).toInt());

    QRegularExpression heightRe("^ID_VIDEO_HEIGHT=(.*)", QRegularExpression::MultilineOption);
    QRegularExpressionMatch heightMatch = heightRe.match(mplayerOutput);
    if (heightMatch.hasMatch())
        m_frameSize.setHeight(heightMatch.captured(1).toInt());

    if (m_frameSize.width() <= 0 || m_frameSize.height() <= 0)
        qFatal("Cannot determine the input file frame size!");

    qDebug() << "Got frame size:" << m_frameSize;

    // Set the clear color to black
    glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );

    // Prepare a complete shader program...
    prepareShaderProgram( ":/shaders/simpletexture.vert",
                          ":/shaders/simpletexture.frag" );

    // Prepare the vertex, texture and index buffers
    prepareVertexBuffers();

    // Prepare the VAO
    prepareVertexArrayObject();

    // Prepare the texture data itself (textures and pixel unpack buffer objects)
    prepareTexture();

    // Link texture unit 0 to the "ySampler" variable in the fragment shader
    m_shader.setUniformValue( "ySampler", 0 );

    // Link texture unit 1 to the "uvSampler" variable in the fragment shader
    m_shader.setUniformValue( "uvSampler", 1 );

    m_videoDecoder.start("ffmpeg",
                         QStringList()
                         << "-i" << m_movieFile
                         << "-f" << "rawvideo"
                         << "-vcodec" << "rawvideo"
                         << "-pix_fmt" << "nv12"
                         << "-an"
                         << "-ss" << "180" // jump to 3m
                         << "-",
                         QIODevice::ReadOnly);

    m_videoDecoder.closeWriteChannel();
    m_videoDecoder.closeReadChannel(QProcess::StandardError);
}