Texture Management

Started by
10 comments, last by MGB 19 years, 6 months ago
Most of what I know about OpenGL, I learned from Nehe. But the examples tend to be rather "vanilla" (which is good), and don't fit every situation. One thing I'd like to do, that I can't seem to find an example of, is to have some sort of more dynamic texture management. Here is what I mean - in order to load textures into OpenGL, I need to tell it how many textures to make space for, like this:
glGenTextures(2, &texture[0]);
Those textures get referenced by storing an int in an array, and passing that value to reference the texture:
glBindTexture(GL_TEXTURE_2D, texture[1]);
Now I can draw a quad (or whatever) and apply the texture to that. What I'd LIKE to be able to do is something more like this:

CTextures Textures;
..
Textures.LoadImage("myimage.bmp","MyImage");
..
glBindTexture(GL_TEXTURE_2D, Textures.Texture("MyImage"));
Does that make sense? In other words, 2 things are going on here. First, I don't know ahead of time how many images I'm going to load, it happens dynamically. Second, I can reference the image by name instead of by integer, making things a little more clear, readable, and dynamic. Has anyone done this? Any examples you can share?
-Todd"Windows dectected that your mouse has moved. Please reboot for the changes to take effect"
Advertisement
Check out std::map in any decent c++ reference. Does exactly what you want.
Quote:Original post by janharal
Check out std::map in any decent c++ reference. Does exactly what you want.


Yeah, but how do I get past knowing how many textures I'll need ahead of time?

glGenTextures(2, &texture[0]);
-Todd"Windows dectected that your mouse has moved. Please reboot for the changes to take effect"
Quote:Original post by toddhd
Quote:Original post by janharal
Check out std::map in any decent c++ reference. Does exactly what you want.


Yeah, but how do I get past knowing how many textures I'll need ahead of time?

glGenTextures(2, &texture[0]);


Look up what he has told you first. Then ask questions if you still don't understand. I'm not familiar with std::map, but I think that it is like std::vector or std::list, which are both dynamic.
____________________________________________________________Programmers Resource Central
Quote:Original post by Tera_Dragon
Quote:Original post by toddhd
Quote:Original post by janharal
Check out std::map in any decent c++ reference. Does exactly what you want.


Yeah, but how do I get past knowing how many textures I'll need ahead of time?

glGenTextures(2, &texture[0]);


Look up what he has told you first. Then ask questions if you still don't understand. I'm not familiar with std::map, but I think that it is like std::vector or std::list, which are both dynamic.


I'm familiar with std::map, and that's where I started out when I started writing this class I'm working on. The real barrier is the glGenTextures(). If I understand correctly, I need to call it with the number of textures I'm going to load BEFORE I load those textures. When I don't know how many textures I'm going to load ahead of time, then what do I do? Am I wrong?

I'm aware that std::map will allow me to call the texture by name - I only mentioned it to make my concept clear.
-Todd"Windows dectected that your mouse has moved. Please reboot for the changes to take effect"
Ah, sorry. I misunderstood your problem.
____________________________________________________________Programmers Resource Central
I think what you're missing is that you can make sucessive calls to glGenTextures. Almost like a C++ 'new' it generates a texture object that you can then attach pixel data to. The method of generating multiple objects at once is just a convinience.

For example, you could write something like (psudeo code):
public int loadTexture(String filename){  int texObj = glGenTextures(1);  glBindTexture(texObj);    // load pixel data and copy to texture object  // ..  return texObj;}
Well, getting past the problem of not knowing how many textures you need is a simple one. Call glGenTextures once for every texture you create. Create a CTexture class, with a GLuint member called uiTexObject, or something. Then, and all you have to do is call glGenTextures with that, specifying that you want one texture:
...    glGenTextures(1, pTexture->uiTexObject);glBindTexture(GL_TEXTURE_2D, pTexture->uiTexObject);    // Set up texture environment, parameters,// then specify it with glTexImage2D...    ...
You can keep all your CTexture objects in an std::map, where the second parameter is the texture's name. Then, when it's time to render, and you want the CTexture object, search the std::map with the texture's name, retrieve the CTexture object from it, and bind the texture. MSDN will help you with std::map, or you can look for an STL tutorial on the net...
My opinion is a recombination and regurgitation of the opinions of those around me. I bring nothing new to the table, and as such, can be safely ignored.[ Useful things - Firefox | GLee | Boost | DevIL ]
Quote:Original post by OrangyTang
I think what you're missing is that you can make sucessive calls to glGenTextures. Almost like a C++ 'new' it generates a texture object that you can then attach pixel data to. The method of generating multiple objects at once is just a convinience.

For example, you could write something like (psudeo code):
public int loadTexture(String filename){  int texObj = glGenTextures(1);  glBindTexture(texObj);    // load pixel data and copy to texture object  // ..  return texObj;}


Ah... very cool. Thanks. I thought glGenTextures() was allocating a string of memory like an array. I didn't realize I could call it over and over.
-Todd"Windows dectected that your mouse has moved. Please reboot for the changes to take effect"
First, create some dynamiclly resizable list of integers. Some int*/new/delete magic, std::vector or something else will suffice. Then you keep count of how many textures you have "generated" so far, initially zero (duh!). When you use your Textures.LoadImage("myimage.bmp","MyImage") or whater, your class will generate new textures (if requried, that's what your counter will be used for) using glGenTextures(n, p), where n is the number of textures you want to generate (yeah, you know this already) and p is a pointer to the element right after the last one you used in your integer array. Make sure there's room for "n" new integers in the array before doing the call to glGenTextures and also remember to increase the counter of how many textures you've now generated by n (so you dont have to generate a new one every single time). Maybe you'll want some counter to keep track of the number of textures you're actually using as well, but if you're sticking with std::vector the size and allocation number will already be there for you.

Of course, you can generate a single texture every time you call glGenTextures as well. I would sure be simpler and not so messy, but then again, it may be slower as well, I dunno. Just experiment I guess :)

So, for the simple technique, take the std::vector for example. Your class maintains such an object (with 0 elements at first) and with every call to Textures.LoadImage[...] you simple allocate space for one more integer (yourvector.reserve(), or something like that, you probably know or know how to find out). Then just call glGenTextures(1, p) where p is the same old pointer to your newly allocated texture representative.

Hm.. on second thought, isn't it even possible to allocate that extra memory you're looking for directly using std::map? If it is, then you've just saved some more lines of code, otherwise forget what I just said :)

Anyway, I dont really see the problem here. It could be that I've forgotten how to use glGenTextures properly, but it seems to me that the only thing you have to do is using some dynamiclly resizable array of integers and allocate new elements (and generate textures for those) when needed.

Cheers, good luck and good night! :P

This topic is closed to new replies.

Advertisement