【问题标题】:Render FFmpeg AVFrame as OpenGL texture?将 FFmpeg AVFrame 渲染为 OpenGL 纹理?
【发布时间】:2019-03-05 18:26:57
【问题描述】:

我正在尝试以 FFmpeg AVFrame 的形式将 jpeg 图像(1024x1024 像素)渲染为 OpenGL 中的纹理。我得到的是显示为 1024x1024 深绿色四边形的东西:

在 OpenGL 中渲染 AVFrame 数据的代码如下所示。我已经说服自己,FFmpeg AVFrame 数据中保存的原始 RGB 数据不仅仅是深绿色。

GLuint g_texture = {};

//////////////////////////////////////////////////////////////////////////
void display()
{
    // Clear color and depth buffers
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);     // Operate on model-view matrix

    glEnable(GL_TEXTURE_2D);
    GLuint texture = g_texture;
    glBindTexture(GL_TEXTURE_2D, texture);

    // Draw a quad
    glBegin(GL_QUADS);
    glVertex2i(0, 0); // top left
    glVertex2i(1024, 0); // top right
    glVertex2i(1024, 1024); // bottom right
    glVertex2i(0, 1024); // bottom left
    glEnd();

    glDisable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, 0);

    glFlush();
}

/* Initialize OpenGL Graphics */
void initGL(int w, int h)
{
    glViewport(0, 0, w, h); // use a screen size of WIDTH x HEIGHT
    glEnable(GL_TEXTURE_2D);     // Enable 2D texturing

    glMatrixMode(GL_PROJECTION);     // Make a simple 2D projection on the entire window
    glOrtho(0.0, w, h, 0.0, 0.0, 100.0);
    glMatrixMode(GL_MODELVIEW);    // Set the matrix mode to object modeling
    //glTranslatef( 0, 0, -15 );

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClearDepth(0.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear the window
}

//////////////////////////////////////////////////////////////////////////
int main(int argc, char *argv[])
{
    std::shared_ptr<AVFrame> apAVFrame;
    if (!load_image_to_AVFrame(apAVFrame, "marble.jpg"))
    {
        assert(false);
        return 1;
    }

    // From here on out, the AVFrame is RGB interleaved
    // and is sized to 1,024 x 1,024 (power of 2).

    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
    glutInitWindowSize(1060, 1060);
    glutInitWindowPosition(0, 0);
    glutCreateWindow("OpenGL - Creating a texture");

    glGenTextures(1, &g_texture);

    //glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glBindTexture(GL_TEXTURE_2D, g_texture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, apAVFrame->width,
                 apAVFrame->height, 0, GL_RGB, GL_UNSIGNED_BYTE,
                 apAVFrame->data[0]);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); /* We will use linear interpolation for magnification filter */
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); /* We will use linear interpolation for minifying filter */

    initGL(1060, 1060);

    glutDisplayFunc(display);

    glutMainLoop();

    return 0;
}

环境:

  • Ubuntu 18.04
  • GCC v8.2

编辑:根据@immibis 下面的建议,当我将四边形的渲染更改为:

// Draw a quad
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex2i(0, 0); // top left
glTexCoord2f(1, 0);
glVertex2i(1024, 0); // top right
glTexCoord2f(1, 1);
glVertex2i(1024, 1024); // bottom right
glTexCoord2f(0, 1);
glVertex2i(0, 1024); // bottom left
glEnd();

【问题讨论】:

    标签: c++ opengl ffmpeg


    【解决方案1】:

    您忘记为顶点提供纹理坐标,因此屏幕上的所有像素都从纹理中读取相同的像素。 (左上角,或默认纹理坐标所在的位置)

    在 glVertex2i 之前使用 glTexCoord2f 来设置顶点的纹理坐标。它们从纹理顶部/左侧的 0 到底部/右侧的 1,因此纹理的角分别为 0,0、1,0、1,1 和 0,1。

    【讨论】:

    • 谢谢。没错!
    猜你喜欢
    • 2013-12-27
    • 1970-01-01
    • 1970-01-01
    • 2014-08-09
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 2011-05-06
    相关资源
    最近更新 更多