![]() |
| | #1 |
| Making mistakes Join Date: Dec 2008
Posts: 347
| Texture Management in OpenGL 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. |
| Brafil is offline | |
| | #2 |
| Registered User Join Date: Oct 2006
Posts: 103
| 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. |
| MWAAAHAAA is offline | |
| | #3 |
| Making mistakes Join Date: Dec 2008
Posts: 347
| Does glGenTextures create new textures? I mean, are the old ones still valid? |
| Brafil is offline | |
| | #4 |
| Super Moderator Join Date: Aug 2001
Posts: 7,470
| 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.
__________________ If you aim at everything you will hit something but you won't know what it is. |
| Bubba is offline | |
| | #5 |
| Making mistakes Join Date: Dec 2008
Posts: 347
| 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);
}
Code: glDeleteTextures(array_size, textures); |
| Brafil is offline | |
| | #6 |
| Super Moderator Join Date: Aug 2001
Posts: 7,470
| 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.
__________________ If you aim at everything you will hit something but you won't know what it is. |
| Bubba is offline | |
| | #7 |
| Making mistakes Join Date: Dec 2008
Posts: 347
| 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). |
| Brafil is offline | |
| | #8 |
| Super Moderator Join Date: Aug 2001
Posts: 7,470
| 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.
__________________ If you aim at everything you will hit something but you won't know what it is. Last edited by Bubba; 07-11-2009 at 11:16 AM. |
| Bubba is offline | |
| | #9 |
| Making mistakes Join Date: Dec 2008
Posts: 347
| I didn't mean removing textures. This would be too difficult. |
| Brafil is offline | |
| | #10 |
| Super Moderator Join Date: Aug 2001
Posts: 7,470
| So you just intend on storing everything in video memory? Somehow I don't think that is going to work as intended.
__________________ If you aim at everything you will hit something but you won't know what it is. |
| Bubba is offline | |
| | #11 |
| Making mistakes Join Date: Dec 2008
Posts: 347
| 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) |
| Brafil is offline | |
| | #12 |
| Super Moderator Join Date: Aug 2001
Posts: 7,470
| 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.
__________________ If you aim at everything you will hit something but you won't know what it is. |
| Bubba is offline | |
| | #13 |
| Making mistakes Join Date: Dec 2008
Posts: 347
| 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. |
| Brafil is offline | |
| | #14 |
| Super Moderator Join Date: Aug 2001
Posts: 7,470
| 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.
__________________ If you aim at everything you will hit something but you won't know what it is. |
| Bubba is offline | |
![]() |
| Thread Tools | |
| Display Modes | |
|
Similar Threads | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Texture Binding with OpenGL | scwizzo | Game Programming | 5 | 07-01-2008 11:02 AM |
| Why only 32x32? (OpenGL) [Please help] | Queatrix | Game Programming | 2 | 01-23-2006 02:39 PM |
| Linking OpenGL in Dev-C++ | linkofazeroth | Game Programming | 4 | 09-13-2005 10:17 AM |
| Pong is completed!!! | Shamino | Game Programming | 11 | 05-26-2005 10:50 AM |
| OpenGL Window | Morgul | Game Programming | 1 | 05-15-2005 12:34 PM |