Search code examples
c++openglloadingtexture-mappingtexture2d

OpenGL loading binds the last loaded texture to all textureID's


So my problem is that I try to load multiple textures at start up and then store all of the ID's so that I can bind them to use them. Now I know that the ID's are being stored correctly because I can debug it and see in both assigning and usage that the ID's are the same. Just for every binding it uses the last texture that I load. Here is my code:

GLuint TextureLoader::LoadTexture (const char* fileName,Material& material,int width,int height) {
    GLuint textureImage;

    FILE* textureFile;
    textureFile = fopen(fileName, "rb");
    unsigned char* imageData;

    if (textureFile == NULL) {
        return 0;
    }
    imageData = (unsigned char*)malloc(width * height * 3);
    char header[54];
    fread(header,1,54,textureFile);
    fread(imageData, width * height * 3, 1, textureFile);

    fclose(textureFile);

    for (int i = 0; i < width * height; ++i) {
        int nextIndex = i * 3;
        unsigned char a = imageData[nextIndex];
        unsigned char b = imageData[nextIndex+2];

        imageData[nextIndex] = b;
        imageData[nextIndex+2] = a;
    }

    glEnable(GL_TEXTURE_2D);
    glGenTextures( 1, &textureImage );
    glBindTexture( GL_TEXTURE_2D, textureImage );
    glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,GL_MODULATE );
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);


    /*glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST );


    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_REPEAT );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_REPEAT );
    glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
    gluBuild2DMipmaps( GL_TEXTURE_2D, 3, width, height,GL_RGB, GL_UNSIGNED_BYTE, imageData );*/
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, imageData);
    glGenerateMipmap(GL_TEXTURE_2D);
    free(imageData);

    return textureImage;
}

Here is my usage of this code:

if (showTexture) {
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, material.texture);
}

Here is my load call:

green1.texture = TextureLoader::LoadTexture("/Users/hewitt/Desktop/OpenGLImages/face6.bmp",green1, 256, 256);

And then I just use:

glTexCoord2f(1.0f,0.0f);

to draw depending on the corner it changes. And this draws the one texture correctly it just repeats the texture even when I glBind a different number.

Any help is greatly appreciated.

Edit ----------

glBegin(mode);
            Spatial::Vector3 normal = Mesh::calculateNormal (pointGroup);
            glNormal3f(normal.x, normal.y, normal.z);

            Material material = mesh.getMaterial();

            if (showTexture) {
                glEnable(GL_TEXTURE_2D);
                glBindTexture(GL_TEXTURE_2D, material.texture);
            }

            int counter = 0;
            for (Spatial::Vector3 point : pointGroup) {
                if (showTexture == false) {
                    Material::Colour colour = material.getColour();
                    glColor3f(colour.red, colour.green, colour.blue);
                } else {

                    if (counter == 0) {
                        glTexCoord2f(1.0f,0.0f);
                    } else if (counter == 1) {
                        glTexCoord2f(1.0f,1.0f);
                    } else if (counter == 2) {
                        glTexCoord2f(0.0f,1.0f);
                    } else if (counter == 3) {
                        glTexCoord2f(0.0f,0.0f);
                    }
                }

                glVertex3f(point.x,point.y,point.z);
                counter ++;
            }


            glEnd();

Solution

  • You cannot call glEnable or glBindTexture while in between glBegin and glEnd. You must bind your texture before glBegin. In fact the set of OpenGL functions you can call between glBegin and glEnd is limited to those transferring vertex attributes (glVertex, glColor, glTexCoord, etc...).

    Note that the immediate mode API (that is glBegin/glEnd and friends) is legacy and was deprecated for more than 10 years. I suggest you switch to the modern OpenGL pipeline, that will sort many things out for you.