Thread: Texture Management in OpenGL

  1. #1
    Making mistakes
    Join Date
    Dec 2008
    Posts
    476

    Texture Management in OpenGL

    Hi folks,

    I'm currently learning OpenGL by NeHe whilst packing all my knowledge into a C++ Engine. So far, I'm at chapter 6 (textures). The question is:
    How can I manage my textures dynamically?

    I thought of a dynamically allocated array holding the texture IDs.
    Well, I have two options:
    1. Allow the user to dynamically delete and add textures, which is practical but also kinda difficult to implement (fill in empty slots etc. so that the ID for a texture doesn't change) and a certain amount of overhead

    2. Allow the user to have one dynamically allocated array, only being able to add textures and clear the array entirely. This would be easier, but how can I increase the size of the array and still having old textures work? By repeatedly calling glGenTextures and glTexImage2D?

    3. Have one array of a specific size and being able to replace it completely (like number 2 without dynamically adding textures)

    I prefer the second choice. But I need help implementing it.

    EDIT: I have already searched in the forum, sorry if someone else's asked this before
    Last edited by Brafil; 07-09-2009 at 05:00 AM.

  2. #2
    Registered User
    Join Date
    Oct 2006
    Posts
    250
    How about std::vector<Texture>, where Texture is your Texture class/struct that contains all the information you require?

    If you pack this into a sort of texture manager class, you can make sure that any textures you request are loaded only once, e.g. by checking against the path of the texture in a call to TextureManager::loadTexture(), and also allows you to place limits on the number of textures that are allowed to be loaded at once, e.g. by checking against the size of your vector and popping of textures as needed.

  3. #3
    Making mistakes
    Join Date
    Dec 2008
    Posts
    476
    Does glGenTextures create new textures? I mean, are the old ones still valid?

  4. #4
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Vector will not allow you to remove any textures without invalidating all iterators past the point of removal. So if you have ID's or use the size_t index as a texture ID the moment you remove a texture that is not the last in the vector you will invalidate everyone's texture ID.

    A better solution is to use a hash table and hash on the filename of the texture since that is more than likely unique for each texture.

  5. #5
    Making mistakes
    Join Date
    Dec 2008
    Posts
    476
    Couldn't I just have a dynamic array (not vector), which I can grow as much as I want? Like

    Code:
    if (texture_count >= array_size) {
        array_size += 32;
        GLuint *temp = new GLuint[array_size];
        memcpy(temp, textures, texture_count);
        delete[] textures;
        textures = temp;
        glGenTextures(32, textures + array_size - 32);
    }
    then, when clearing:

    Code:
    glDeleteTextures(array_size, textures);
    So, can I delete two different but consecutive blocks of texture IDs at the same time?

  6. #6
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    How are you going to identify the textures? If you use a dynamic array you can use indices, however your array will have empty slots in it which makes iterating over it a bit inefficient.

  7. #7
    Making mistakes
    Join Date
    Dec 2008
    Posts
    476
    The texture IDs are returned by the function AddTexture. The user needs to keep track of them (I am currently implementing an auto-texturing Object class).

  8. #8
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    You are still going to run into the situation where your array can only grow in size b/c to shrink it would require expensive copy operations.

    For instance if your array looks like this:

    0. Object
    1. Object
    2. Object

    If you add an Object you will get:

    0. Object
    1. Object
    2. Object
    3. Object

    If you remove Object at array index 1 you get:

    0. Object
    1. NULL
    2. Object
    3. Object

    If you add another object without being smart about it:

    0. Object
    1. NULL
    2. Object
    3. Object
    4. Object

    Now your system must perform a pointer check prior to calling render or update on the object. Would it not be better if the system 'knew' which array indices were valid? If you try to shrink the array down to 4 elements then you must move everything from 2 up 1 index. This invalidates all the ID's you handed out to each object at startup and it is also slow. If you just allow this to happen without thinking about it your array is going to become very fragmented and your performance can only get worse as the game plays out.

    I have one solution to this but I'm trying to get you to think about this problem a bit more in depth.
    Last edited by VirtualAce; 07-11-2009 at 11:16 AM.

  9. #9
    Making mistakes
    Join Date
    Dec 2008
    Posts
    476
    I didn't mean removing textures. This would be too difficult.

  10. #10
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    So you just intend on storing everything in video memory? Somehow I don't think that is going to work as intended.

  11. #11
    Making mistakes
    Join Date
    Dec 2008
    Posts
    476
    Uh... I don't think I wanted this. The question has changed a little:

    I'm keeping texture IDs in an array. If the array is full, it is grown, and glGenTextures is called at the first position which isn't mapped, like:

    [1] [2] [3] [4] [5] // OpenGL Texture IDs, the array is full
    [1] [2] [3] [4] [5] [?] [?] [?] // Increase its size
    [1] [2] [3] [4] [5] [21] [22] [23] // glGenTextures called at position 5 (where 21 is)

    Now, can I delete all the texture IDs at one time?

    [0] [0] [0] [0] [0] [0] [0] [0] // glDeleteTextures called at position 1 with argument 8

    or do I have to delete each block separately?

    [0] [0] [0] [0] [0] [21] [22] [23] // glDeleteTextures(5, array)
    [0] [0] [0] [0] [0] [0] [0] [0] // glDeleteTextures(3, array + 5)

  12. #12
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    You can delete them all at once. However you are missing the fact that if you remove a texture at run-time that is not at the end of the list your list will become fragmented and after a few hours will probably slow your performance.

  13. #13
    Making mistakes
    Join Date
    Dec 2008
    Posts
    476
    No, I tried to say that removing textures is not allowed. You can only clear them all (which the engine will do automatically) or replace them with white.

  14. #14
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    I'm saying that is not going to work. You cannot continue to throw textures into video memory ad infinitum. You will run out of video RAM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Texture Binding with OpenGL
    By scwizzo in forum Game Programming
    Replies: 5
    Last Post: 07-01-2008, 11:02 AM
  2. Why only 32x32? (OpenGL) [Please help]
    By Queatrix in forum Game Programming
    Replies: 2
    Last Post: 01-23-2006, 02:39 PM
  3. Linking OpenGL in Dev-C++
    By linkofazeroth in forum Game Programming
    Replies: 4
    Last Post: 09-13-2005, 10:17 AM
  4. Pong is completed!!!
    By Shamino in forum Game Programming
    Replies: 11
    Last Post: 05-26-2005, 10:50 AM
  5. OpenGL Window
    By Morgul in forum Game Programming
    Replies: 1
    Last Post: 05-15-2005, 12:34 PM