I'm trying to use BlackMagic Decklink SDK to display a video from a Decklink card into a QtQuick application. I successfully managed to do the same using QWidgets, so the video stream aquisition part is working.
When using QWidgets (more specifically QOpenGLWidget), basically all we have to do is to create a subclass of QOpenGLWidget and override initializeGL & paintGL like this:
void DeckLinkOpenGLWidget::initializeGL()
{
if (m_deckLinkScreenPreviewHelper != nullptr)
{
m_mutex.lock();
m_deckLinkScreenPreviewHelper->InitializeGL();
m_mutex.unlock();
}
}
void DeckLinkOpenGLWidget::paintGL()
{
m_mutex.lock();
glLoadIdentity();
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
m_deckLinkScreenPreviewHelper->PaintGL();
m_mutex.unlock();
}
When doing the same in a custom renderer with QtQuick, nothing happens. I suppose I have to write my program & shaders, but I've no idea of what it needs. When using a shader coloring each pixel in a color, a square of that color is painted, so I guess I'm no to far (but could be wrong...).
Here's some code:
void VideoViewRenderer::initializeGL()
{
QOpenGLFunctions::initializeOpenGLFunctions();
const char* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
"}\n";
const char* fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
" FragColor = vec4(0.6f, 0.0f, 0.0f, 1.0f);\n"
"}\n";
m_program = new QOpenGLShaderProgram();
m_program->addCacheableShaderFromSourceCode(QOpenGLShader::Vertex,vertexShaderSource);
m_program->addCacheableShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);
m_program->link();
m_mutex.lock();
m_deckLinkScreenPreviewHelper->InitializeGL();
m_mutex.unlock();
}
void VideoViewRenderer::paintGL()
{
m_program->bind();
glLoadIdentity();
glClearColor(0.0f, 0.4f, 0.0f, 0.0f);
glViewport(0, 0, m_viewportSize.width(), m_viewportSize.height());
glClear(GL_COLOR_BUFFER_BIT);
m_mutex.lock();
m_deckLinkScreenPreviewHelper->PaintGL();
m_mutex.unlock();
m_program->release();
}
How am I supposed to update my shaders?
The easiest way to solve this problem is to render two triangles forming a square on the screen instead of points. Set those triangles to be textured and dynamically change the texture buffer contents with data from Decklink card.
Please see this thread for more information on using video frames in opengl: How to input video (frames) into a GLSL shader