help with multiple texture loading please

Hi,

I am working on a demo programme and the problem I have been working on for the last week is as follows, I am loasing in a texture which is devided into smaller images as a tga file. I use these images throughout the game and it works fine. I have now come to load a .3ds model into my game and need to put another texture into memory for the skin of the mesh but when I init that texture using the following code, it overwrites the first tex (. The function does not return a pointer to the texture so I can’t increment this for the second image.

Can anyone help me out with this and tell me how I can adapt it to load in multiple textures? Any help or tips would be greatly appreciated, thanks in advance for any advice )

BennUK

int Ctexture::LoadTGAFile(const char* filename)
{
FILE *filePtr;
unsigned char ucharBad;
short int sintBad;
long imageSize;
int colorMode;
long imageIdx;
unsigned char colorSwap;
TGAFILE *tgaFile;

filePtr =fopen(filename, “rb”); // open the file for binary reading
if(!filePtr) // if file doesn’t exist, exit
{
cout << "File %s not found
" << filename << endl;

  return 0; }

fread(&ucharBad, sizeof(unsigned char), 1, filePtr);
fread(&ucharBad, sizeof(unsigned char), 1, filePtr);

// create new targa file storage in memory
tgaFile = new TGAFILE;

fread(&tgaFile->imageType, sizeof(unsigned char), 1, filePtr);

if((tgaFile->imageType != 2) && (tgaFile->imageType != 3))
{
fclose(filePtr);
return 0;
}

fread(&sintBad, sizeof(short int), 1, filePtr);
fread(&sintBad, sizeof(short int), 1, filePtr);

fread(&ucharBad, sizeof(unsigned char), 1, filePtr);
fread(&sintBad, sizeof(short int), 1, filePtr);
fread(&sintBad, sizeof(short int), 1, filePtr);

fread(&tgaFile->imageWidth, sizeof(short int), 1, filePtr);
fread(&tgaFile->imageHeight, sizeof(short int), 1, filePtr);

fread(&tgaFile->bitDepth, sizeof(unsigned char), 1, filePtr);

fread(&ucharBad, sizeof(unsigned char), 1, filePtr);

colorMode = tgaFile->bitDepth / 8;
imageSize = tgaFile->imageWidth * tgaFile->imageHeight * colorMode;

tgaFile->imageData = (unsigned char*)malloc(sizeof(unsigned char)*imageSize);

fread(tgaFile->imageData, sizeof(unsigned char), imageSize, filePtr);

for(imageIdx=0; imageIdx < imageSize; imageIdx += colorMode)
{
colorSwap = tgaFile->imageData[imageIdx];
tgaFile->imageData[imageIdx] = tgaFile->imageData[imageIdx + 2];
tgaFile->imageData[imageIdx + 2] = colorSwap;

}

cout << “bit depth:” << tgaFile->bitDepth << endl;

glTexImage2D(GL_TEXTURE_2D, 0, 3
, tgaFile->imageWidth, tgaFile->imageHeight, 0,
GL_RGBA, GL_UNSIGNED_BYTE, tgaFile->imageData);

fclose(filePtr); // close file

return TRUE;

}

[This message has been edited by dorbie (edited 01-22-2004).]

You never call glGenTextures or glBindTexture. Look up these functions first, you need them for handling more than one texture.

What you need to do is declare a variable inside your function

GLuint textureID;

Then call glGenTextures and glBindTexture and then return this variable.

So for each texture you load, let’s say you want 4 textures, you’d declare some global array or however you want to put it.

GLuint textues[4];

Then for each one simply do

texture[0] = CreateTexture(“blah blah”);

Or whatever your texture loading function was. That’s the basic jist of it, and everytime you need to switch textures, you have to call glBindTexture with the appropriate texture ID.

This shouldn’t be needed.

Before you call the load function just set the active texture with a call to glActiveTexture, the texture load will then load to that texture target.

You should not have to modify the function at all as it is already compatible with multitexture.

Any texture binds could and should be done outside the function also, but texbinds are only needed is you want to optimize the code to store & reuse multiple textures besides the ones already assigned to the available texture units. It is not essential to use texbinds to use multitexture. It’s just good practice. Even if you do use binds I’d strongly recommend keeping the bind calls out of that function. Obviously it’ll need some higher level program control for the binds and texture handle management.

P.S. you have a memory leak, you don’t free the tgafile. It’s a big leak since you have the entire image data there.

[This message has been edited by dorbie (edited 01-22-2004).]

I am creating two pointers to textures in the class and then initialising them with the following:

ptr-&gt;LoadTGAFile("image.tga");
    ptr2-&gt;LoadTGAFile("image2.tga");

But whichever order I put these two lines of code in determines which texture is in memory, the way shown renders ptr2 even if I call ptr1->render?. Arrgh.

So what you are saying is that I should call the glActiveTexture before the texture I want to use initially and change it when I need to render the next ptr?

Thanks again

BennUK

int texID1;
ith texID2;

ptr->LoadTGAFile(“image.tga”);
glGenTexture(1, &texID1);
glBindTexture(GL_TEXTURE_2D, texID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, smile_tex->width, smile_tex->height, GL_RGB, GL_UNSIGNED_BYTE, ptr1->data);

ptr2->LoadTGAFile(“image2.tga”);
// and so on

Thanx styxxo, thats done the job, your’e a star :o)

BennUK

No worries mate

Glad I could help

Here is a great article on texture objects that my boss wrote. check it out and it should clear some stuff up for you. http://www.gamasutra.com/features/19990723/opengl_texture_objects_01.htm

Oh and the Texture enviroment does not bind to a texture object. Its a “global” setting. Its a bummer but makes sense

[This message has been edited by SofaSurfa (edited 01-28-2004).]