1
votes

I have a Model2D class which contains the following:

class Model2D
{
    public: //it's private, but I'm shortening it here
    unsigned char* bitmapImage;
    unsigned int textureID;
    int imageWidth, imageHeight;

    void Load(char* bitmapFilename);
}
void Model2D::Load(char* bitmapFilename)
{
    ifstream readerBMP;
    readerBMP.open(bitmapFilename, ios::binary);
    //I get the BMP header and fill the width, height

    bitmapImage = new GLubyte[imageWidth * imageHeight * 4];
    //Loop to read all the info in the BMP and fill the image array, close reader

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

    glGenTextures(1, &textureID);
    glBindTexture(GL_TEXTURE_2D, textureID);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imageWidth, imageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, bitmapImage);
}
void Model2D::Draw()
{
    glBegin(GL_QUADS);          
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
    glBindTexture(GL_TEXTURE_2D, textureID);

    float texScale = 500.0; //this is just so I don't have to resize images

    glTexCoord2f(0.0, 0.0); glVertex3f(-(imageWidth / texScale), -(imageHeight / texScale), 0.0);
    glTexCoord2f(0.0, 1.0); glVertex3f(-(imageWidth / texScale), (imageHeight / texScale), 0.0);
    glTexCoord2f(1.0, 1.0); glVertex3f((imageWidth / texScale), (imageHeight / texScale), 0.0);
    glTexCoord2f(1.0, 0.0); glVertex3f((imageWidth / texScale), -(imageHeight / texScale), 0.0);    
}

And in my main loop, I have:

Model2D spritest;
spritest.LoadFromScript("FirstBMP.bmp");
spritest.Z(-5); spritest.X(-2);

Model2D spritest2;
spritest2.LoadFromScript("SecondBMP.bmp");
spritest2.X(+2); spritest2.Z(-6);

//...
//main loop
spritest.Draw();
spritest2.Draw();

While debugging it seems to be working fine, the addresses of the bitmaps are different, and so are the textureIDs that OpenGL generates, and they're being called correctly as well, and the X, Y and Z positions are also correct while debugging, but for some unknown reason, spritest image data is being overwritten by spritest2. Even if I don't call Draw() from spritest2, the image is being displayed instead of spritest.

What could be causing this?

1

1 Answers

1
votes

glBegin must come after your texture binding functions in Draw:

glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glBindTexture(GL_TEXTURE_2D, textureID);
glBegin(GL_QUADS);          

In the documentation for glBindTexture it states:

When a texture is bound to a target, the previous binding for that target is automatically broken.

You'll also find that in the documentation for glBegin it states:

Only a subset of GL commands can be used between glBegin and glEnd. The commands are glVertex, glColor, glSecondaryColor, glIndex, glNormal, glFogCoord, glTexCoord, glMultiTexCoord, glVertexAttrib, glEvalCoord, glEvalPoint, glArrayElement, glMaterial, and glEdgeFlag. Also, it is acceptable to use glCallList or glCallLists to execute display lists that include only the preceding commands. If any other GL command is executed between glBegin and glEnd, the error flag is set and the command is ignored.

Because of this, in your Draw function, you're going to need to place glBindTexture(GL_TEXTURE_2D, textureID); and glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); before glBegin(GL_QUADS). Otherwise, glBindTexture does nothing because it's within a glBegin and therefore SecondBMP.bmp is still bound to the target GL_TEXTURE_2D