将OpenGL纹理拉伸到窗口尺寸

时间:2012-04-04 21:42:20

标签: opengl video render draw rgb

我有一个将RGB视频帧渲染到窗口的功能。如果窗口尺寸相同但是当我调整窗口大小时渲染不正确,这适用于捕获的尺寸(640 x 480):

img http://img855.imageshack.us/img855/1694/screenshot20120404at536.png

编辑:现在正在运作的功能。

static inline void draw_rgb(
     unsigned char * buf, unsigned x, unsigned y, unsigned window_width,
     unsigned window_height, unsigned frame_width, unsigned frame_height
 )
{
    glEnable(GL_TEXTURE_RECTANGLE_EXT);
    glBindTexture(GL_TEXTURE_RECTANGLE_EXT, 1);

    glTextureRangeAPPLE(GL_TEXTURE_RECTANGLE_EXT, window_width * window_height * 2, buf);

    glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA, frame_width, frame_height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, buf);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_TEXTURE_2D);

    glViewport(x, y, window_width, window_height);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    glOrtho((GLfloat)0, (GLfloat)window_width, (GLfloat)0, (GLfloat)window_height, -1.0, 1.0);

    glBindTexture(GL_TEXTURE_RECTANGLE_EXT, 1);

    glMatrixMode(GL_TEXTURE);
    glLoadIdentity();

    glBegin(GL_QUADS);
    {
        glTexCoord2f(0.0f, 0.0f);
        glVertex2f(0.0f, window_height);
        glTexCoord2f(0.0f, frame_height);
        glVertex2f(0.0f, 0.0f);
        glTexCoord2f(frame_width, frame_height);
        glVertex2f(window_width, 0.0f);
        glTexCoord2f(frame_width, 0.0f);
        glVertex2f(window_width, window_height);
    }
    glEnd();
}

3 个答案:

答案 0 :(得分:3)

主要问题在这里

glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA, window_width, window_height, 0,
         GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, buf);

glTexImage采用纹理数据的大小,而不是窗口大小或所需输出的大小。

答案 1 :(得分:2)

您的问题是两个因素的结合。

首先,正如datenwolf指出的那样,纹理的宽度/高度是恒定的。窗口大小不会改变。顺便说一下,除非纹理数据发生变化,否则不应每帧重建纹理。即使这样,您也可以使用glTexSubImage2D而不是glTexImage上传更改。您也不需要调用glTexParameter内容。

其次,这也意味着纹理坐标不会改变。因此,您需要将四边形绘图更改为:

glBegin(GL_QUADS);
{
    glTexCoord2f(0.0f, 0.0f);
    glVertex2f(0.0f, window_height);
    glTexCoord2f(0.0f, texture_height);
    glVertex2f(0.0f, 0.0f);
    glTexCoord2f(texture_width, texture_height);
    glVertex2f(window_width, 0.0f);
    glTexCoord2f(texture_width, 0.0f);
    glVertex2f(window_width, window_height);
}
glEnd();

答案 2 :(得分:0)

您的glViewport来电正在使用相同的wh变量来代表其他地方的纹理大小。

尝试更改glViewport以使用您要渲染的窗口大小,而不是wh。其他一切都应该保持不变。

为了获得更好的效果,您可以通过缩小视口的宽度或高度来调整视口大小以保持视频的宽高比,以便视频看起来不会拉伸。