简体   繁体   中英

reusing an opengl texture

I am trying to teach myself OpenGL and and looking to reuse opengl textures. What I would like to do is load a video and then bind each of the video frame to a texture and just show it in an opengl window. I know there is a Pixel Buffer Object which might be more appropriate but the idea for me is to learn OpenGL.

So, I wrote a simple C++ texture class as follows:

class Texture
{
public:
    Texture(GLenum target=GL_TEXTURE_2D);
    ~Texture();

    void load(int rows, int cols, uchar * data);

protected:
    GLenum      _texture_target;
    GLuint      _texture_obj;
};

The implementation is as follows:

Texture::Texture(GLenum target)
{
    _texture_target = target;
    glGenTextures(1, &_texture_obj);
}

void Texture::load(int rows, int cols, uchar * data)
{
    glBindTexture(_texture_target, _texture_obj);
    glTexImage2D(_texture_target, 0, GL_BGRA, cols, rows, 0,
                 GL_BGRA, GL_UNSIGNED_BYTE, data);
    glTexParameterf(_texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameterf(_texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}

My question is that as I get subsequent video frames, can I make calls to my load() function with the new frame data and will this reuse the texture object correctly? Is this the preferred way to do this using textures or should I delete this texture with glDeleteTextures and generate new texture everytime?

One has to distinguish between two things: The texture object itself, and the graphic memory associated with it.

If you just want to reuse the texture object, then your code is fine. But this code allocates (depending on the implementation) new memory on each call of load, since glTexImage2D is used.

If you already now from the start that the texture size will not change (as it is the case for videos), then something like this code would be better. The difference here is, that in the initialization memory for the texture is requested. In subsequent calls to load only the content of this memory is updated, but no new memory is requested.

Texture::Texture(GLenum target, int rows, int cols)
{
    _texture_target = target;
    glGenTextures(1, &_texture_obj);

    glBindTexture(_texture_target, _texture_obj);
    glTexImage2D(_texture_target, 0, GL_BGRA, cols, rows, 0,
                 GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid*)NULL);
    glTexParameterf(_texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameterf(_texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}

void Texture::load(int rows, int cols, uchar * data)
{
    glBindTexture(_texture_target, _texture_obj);
    glTexSubImage2D(_texture_target, 0, 0, 0, cols, rows,
                    GL_BGRA, GL_UNSIGNED_BYTE, data);
}

For more details have a look at glTexSubImage2D .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM