-1

I have a single texture working, but I cannot figure out how to switch between 2, or how glBindTexture actually works.

I copied this from somewhere and it works, and I believe that I understand most of it. Problem is, I can uncomment glBindTexture(GL_TEXTURE_2D, texture[0].texID); and it works. Which I don't understand. This code shouldn't be a problem, I think it's something simple I am missing.

bool LoadTGA(TextureImage *texture, char *filename)         // Loads A TGA File Into Memory
{    
    GLubyte     TGAheader[12]={0,0,2,0,0,0,0,0,0,0,0,0};    // Uncompressed TGA Header
    GLubyte     TGAcompare[12];                             // Used To Compare TGA Header
    GLubyte     header[6];                                  // First 6 Useful Bytes From The Header
    GLuint      bytesPerPixel;                              // Holds Number Of Bytes Per Pixel Used In The TGA File
    GLuint      imageSize;                                  // Used To Store The Image Size When Setting Aside Ram
    GLuint      temp;                                       // Temporary Variable
    GLuint      type=GL_RGBA;                               // Set The Default GL Mode To RBGA (32 BPP)

    system("cd");

    FILE *file = fopen(filename, "r");                      // Open The TGA File

    if( file==NULL ||                                       // Does File Even Exist?
        fread(TGAcompare,1,sizeof(TGAcompare),file)!=sizeof(TGAcompare) ||  // Are There 12 Bytes To Read?
        memcmp(TGAheader,TGAcompare,sizeof(TGAheader))!=0               ||  // Does The Header Match What We Want?
        fread(header,1,sizeof(header),file)!=sizeof(header))                // If So Read Next 6 Header Bytes
    {

        if (file == NULL)                                   // Did The File Even Exist? *Added Jim Strong*
        {
            perror("Error");
            return false;                                   // Return False
        }
        else
        {
            fclose(file);                                   // If Anything Failed, Close The File
            perror("Error");
            return false;                                   // Return False
        }

    }

    texture->width  = header[1] * 256 + header[0];          // Determine The TGA Width  (highbyte*256+lowbyte)
    texture->height = header[3] * 256 + header[2];          // Determine The TGA Height (highbyte*256+lowbyte)

    if( texture->width  <=0 ||                              // Is The Width Less Than Or Equal To Zero
        texture->height <=0 ||                              // Is The Height Less Than Or Equal To Zero
        (header[4]!=24 && header[4]!=32))                   // Is The TGA 24 or 32 Bit?
    {
        fclose(file);                                       // If Anything Failed, Close The File
        return false;                                       // Return False
    }

    texture->bpp    = header[4];                            // Grab The TGA's Bits Per Pixel (24 or 32)
    bytesPerPixel   = texture->bpp/8;                       // Divide By 8 To Get The Bytes Per Pixel
    imageSize       = texture->width*texture->height*bytesPerPixel; // Calculate The Memory Required For The TGA Data

    texture->imageData=(GLubyte *)malloc(imageSize);        // Reserve Memory To Hold The TGA Data

    if( texture->imageData==NULL ||                         // Does The Storage Memory Exist?
        fread(texture->imageData, 1, imageSize, file)!=imageSize)   // Does The Image Size Match The Memory Reserved?
    {
        if(texture->imageData!=NULL)                        // Was Image Data Loaded
            free(texture->imageData);                       // If So, Release The Image Data

        fclose(file);                                       // Close The File
        return false;                                       // Return False
    }

    for(GLuint i=0; i<int(imageSize); i+=bytesPerPixel)     // Loop Through The Image Data
    {                                                       // Swaps The 1st And 3rd Bytes ('R'ed and 'B'lue)
        temp=texture->imageData[i];                         // Temporarily Store The Value At Image Data 'i'
        texture->imageData[i] = texture->imageData[i + 2];  // Set The 1st Byte To The Value Of The 3rd Byte
        texture->imageData[i + 2] = temp;                   // Set The 3rd Byte To The Value In 'temp' (1st Byte Value)
    }

    fclose (file);                                          // Close The File

    // Build A Texture From The Data
    glGenTextures(1, &texture[0].texID);                    // Generate OpenGL texture IDs

    //glBindTexture(GL_TEXTURE_2D, texture[0].texID);           // Bind Our Texture
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);   // Linear Filtered
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);   // Linear Filtered
    //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

    if (texture[0].bpp==24)                                 // Was The TGA 24 Bits
    {
        type=GL_RGB;                                        // If So Set The 'type' To GL_RGB
    }

    glTexImage2D(GL_TEXTURE_2D, 0, type, texture[0].width, texture[0].height, 0, type, GL_UNSIGNED_BYTE, texture[0].imageData);

    return true;

Now when I draw I have this:

glEnable(GL_TEXTURE_2D);
//glBindTexture(GL_TEXTURE_2D, texturesList[0].texID);
glColor4f(1, 1, 1, 1);
glBegin(GL_POLYGON);
    glTexCoord2f(0.0f, 0.0f);
    glVertex4f(-50, 0, 50, 1);
    glTexCoord2f(50.0f, 0.0f);
    glVertex4f(-50, 0, -50, 1);
    glTexCoord2f(50.0f, 50.0f);
    glVertex4f(50, 0, -50, 1);
    glTexCoord2f(0.0f, 50.0f);
    glVertex4f(50, 0, 50, 1);
glEnd();

glDisable(GL_TEXTURE_2D); 

And this at the start of the program:

LoadTGA(&texturesList[0], "\snow.tga");
LoadTGA(&texturesList[1], "\snow2.tga");

So after it loads them texturesList contains 2 textures with ids of 1 and 2. So do I not call glBindTexture(GL_TEXTURE_2D, texturesList[0].texID); before I draw to choose the right texture? Because I have to tell glTexCoord2f what to operate on?

It works perfectly if I never call glBind in my draw, but if I do nothing shows up. What I am more confused about is that it glBind doesn't need to be called for it to work.

But the last texture I create gets shown(snow2.tga).

If I can clear anything up let me know.

genpfault
  • 51,148
  • 11
  • 85
  • 139
Joey Gelpi
  • 31
  • 1
  • 1
  • 5
  • 1
    In your LoadTGA method I think you should do `glGenTextures(1, &texture->texID);` and you should also call `glBindTexture` after you have generated it. – Cyclonecode Dec 08 '13 at 01:30
  • Thanks that works! Don't know why some where texture[0] and some weren't. Any idea why I have to call glBind in LoadTGA though? – Joey Gelpi Dec 08 '13 at 01:40
  • I don't think you have to call `glBindTexture()` in the LoadTGA method, it was just a though. – Cyclonecode Dec 08 '13 at 01:43

1 Answers1

4

So do I not call glBindTexture (GL_TEXTURE_2D, texturesList[0].texID); before I draw to choose the right texture? Because I have to tell glTexCoord2f what to operate on?

glTexCoord2f (...) operates at the per-vertex level. It is independent of what texture you have loaded, that is actually the whole point. You can map any texture you want simply by changing which texture is bound when you draw.


It works perfectly if I never call glBind in my draw, but if I do nothing shows up. What I am more confused about is that it glBind doesn't need to be called for it to work.

You need to bind your texture in LoadTGA (...) because "generating" a name alone is insufficient.

All that glGenTextures (...) does is return one or more unused names from the list of names OpenGL has for textures and reserve them so that a subsequent call does not give out the same name.

It does not actually create a texture, the name returned does not become a texture until you bind it. Until that time the name is merely in a reserved state. Commands such as glTexParameterf (...) and glTexImage2D (...) operate on the currently bound texture, so in addition to generating a texture you must also bind one before making those calls.


Now, onto some other serious issues that are not related to OpenGL:

Do whatever possible to get rid of your system ("cd"); line. There are much better ways of changing the working directory.

  1. SetCurrentDirectory (...) (Windows)
  2. chdir (...)                             (Linux/OS X/BSD/POSIX)

Do not use the file name "\snow.tga" as a string literal, because a C compiler may see "\" and interpret whatever comes after it as part of an escape sequence. Consider "\\snow.tga" instead or "/snow.tga" (yes, this even works on Windows - "\" is a terrible character to use as a path separator).

"\s" is not actually a recognized escape sequence by C compilers, but using "\" to begin your path is playing with fire because there are a handful of reserved characters where it will actually matter. "\fire.tga", for instance, is actually shorthand for {0x0c} "ire.tga". The compiler will replace your string literal with that sequence of bytes and will leave you scratching your head trying to figure out what went wrong.

Andon M. Coleman
  • 42,359
  • 2
  • 81
  • 106