Render AVPicture in QGLWidget
-
Hi,
i want to learn how create video player using ffmpeg. after successfully render AVPicture using QPainter + QImage, then i decide to try opengl. but i don't know anything about opengl. using Qt opengl example as reference and google, i come up with this code.
@#include "videoglrenderer.h"#include <QGLShaderProgram>
#include <QGLShader>#include "picture.h"
static const GLfloat vertices[] = {
-1.0f, 1.0f,
1.0f, 1.0f,
1.0f, -1.0f,
-1.0f, -1.0f
};static const GLfloat texCoordsVertices[] = {
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
};VideoGLRenderer::VideoGLRenderer(QWidget *parent)
: QGLWidget(parent)
{
}QSize VideoGLRenderer::size()
{
return QGLWidget::size();
}void VideoGLRenderer::initializeGL()
{
glEnable(GL_TEXTURE_2D);
glDisable(GL_BLEND);#define PROGRAM_POSITION_ATTRIBUTE 0
#define PROGRAM_TEXCOORD_ATTRIBUTE 1QGLShader *vshader = new QGLShader(QGLShader::Vertex, this); const char *vsrc = "attribute vec4 position;\n" "attribute vec2 texCoord;\n" "varying vec2 v_texCoord;\n" "void main()\n" "{\n" "gl_Position = position;\n" "v_texCoord = texCoord;\n" "}\n"; vshader->compileSourceCode(vsrc); QGLShader *fshader = new QGLShader(QGLShader::Fragment, this); const char *fsrc = "varying highp vec2 v_texCoord;\n" "uniform sampler2D texture;\n" "void main()\n" "{\n" "gl_FragColor = texture2D(texture, v_texCoord);\n" "}\n"; fshader->compileSourceCode(fsrc); mProgram = new QGLShaderProgram(this); mProgram->addShader(vshader); mProgram->addShader(fshader); mProgram->bindAttributeLocation("position", PROGRAM_POSITION_ATTRIBUTE); mProgram->bindAttributeLocation("texCoord", PROGRAM_TEXCOORD_ATTRIBUTE); mProgram->link(); mProgram->bind(); glGenTextures(1, &mTexture); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, mTexture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width(), height(), 0, GL_RGB, GL_UNSIGNED_BYTE, 0); mProgram->setUniformValue("texture", 0);
}
void VideoGLRenderer::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);mProgram->enableAttributeArray(PROGRAM_POSITION_ATTRIBUTE); mProgram->enableAttributeArray(PROGRAM_TEXCOORD_ATTRIBUTE); mProgram->setAttributeArray(PROGRAM_POSITION_ATTRIBUTE, vertices, 2); mProgram->setAttributeArray(PROGRAM_TEXCOORD_ATTRIBUTE, texCoordsVertices, 2); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
void VideoGLRenderer::resizeGL(int width, int height)
{
glViewport(0, 0, width, height);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
}void VideoGLRenderer::setFrame(Picture *frame)
{
if (!frame)
return;glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, mTexture); for (int y = 0; y < frame->height; y++) glTexSubImage2D(GL_TEXTURE_2D, 0, 0, y, frame->width, 1, GL_RGB, GL_UNSIGNED_BYTE, frame->picture.data[0] + (y * frame->picture.linesize[0]));
}
@
it doesn't render anything yet, i know there must be something that not right. so maybe someone can help me. can someone give me a little explanation about why it doesn't render anything....?
FYI frame that will be rendered already in AV_PIX_FMT_RGB24 format.