PDA

View Full Version : Storing multiple textures in an array/vector



fiodis
03-19-2013, 09:03 AM
A model I'm loading might or might not use multiple textures (in tga format) for different segments. I don't know in advance how many it will use. So what I do is I count the number of textures at loadtime, then create an std::vector<GLuint> of size numTextures to hold all the texture ids. Then I cycle through the textures and load them one at a time, using the SOIL library.

The problem comes when I try to use them. If I do glBindTexture(GL_TEXTURE_2D, texIds[0]) everything works fine, but if I try to use a texture other than the first, glBindTexture(GL_TEXTURE_2D, texIds[1]) I get a solid black shape, as if the texture isn't loading properly. I know it's not a problem with the texture file itself, because if I switch the order of them so it's the first one loaded, it works fine, and still the others in the list are broken.

So is there some fundamental problem with storing texture ids in an std::vector that I, as a newbie, don't realize? Or is it some peculiarity of SOIL? Or is it something else?

Here's the code for generating the texture list (texList) is a list of just the texture filenames, for example "texture.tga"):

vector<GLuint> modelTools::loadTextures(vector<string> texList, string filePath){
string directory;
const size_t last_slash_idx = filePath.rfind('/');
if (string::npos != last_slash_idx){
directory = filePath.substr(0, last_slash_idx);
}
int numTextures = texList.size();
vector<GLuint> texIdList;
texIdList.reserve(numTextures);
texIdList.resize(numTextures, 0);

int curIter = 0;
int maxIter = numTextures;
while (curIter < maxIter){
string curDir = directory + '/' + texList[curIter];
texIdList[curIter] = SOIL_load_OGL_texture(curDir.c_str(), SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_MIPMAPS);
curIter++;
}

return texIdList;
}

tonyo_au
03-19-2013, 05:21 PM
texIdList.resize(numTextures, 0);


resize frees the memory for the array

use



texIdList.clear();

Alfonse Reinheart
03-19-2013, 05:50 PM
He's not trying to free the array. He's creating the array. He's resizing it to fill it up with zeros.

Remember: vectors have a distinction between "size" (number of active elements) and "capacity" (size of memory allocated). Really, there's no point in him reserving the capacity, and there's no point in the resize. It could have been condensed into one line:



vector<GLuint> texIdList(numTextures, 0);

pwnstar23
03-19-2013, 06:06 PM
texIdList.resize(numTextures, 0);


resize frees the memory for the array

use



texIdList.clear();


Resize will never make the underlying array smaller. If you have an array with a capacity of 100 and you say resize 50, the capacity will still be 100. Only the size ( number of active elements ) will shrink. Resize will grow the array if neccessary.

tonyo_au
03-19-2013, 07:10 PM
Sorry I mis-read resize(numTextures,0) as resize(0)

But I thought resize(0) actually shrunk the buffer. Is there a function to actually release space in a vector buffer?

fiodis
03-21-2013, 07:29 AM
There isn't, as far as I know. Most people do this (http://stackoverflow.com/questions/2695552/how-to-shrink-to-fit-an-stdvector-in-a-memory-efficient-way).

tonyo_au
03-21-2013, 04:54 PM
thanks for that