Texture problems (many different ones)

I have been learning OpenGL (with C++) for a week now, and have run into a strange issue with textures.

I was adding textures to some buttons in a menu, and at first it seemed to work fine. Then I realized, the image is shifted to the right, and looped around the other end for some reason. Also, when I attempt to load another texture, it seems to return an inverted or strangely-colored texture. I have rooted through my code and found nothing that raises a flag (for me, anyway), so I’d like to know if anyone else finds issues.

Here is the first texture I loaded…

Uploaded with ImageShack.us

Here is the second texture I loaded…

Uploaded with ImageShack.us

This is the screen I got (The last button is not supposed to be textured anyway, but the first and second are supposed to have the first and second textures, respectively)


Uploaded with ImageShack.us

Notice how the left end of each button drops down by one pixel, and is actually looped from the other end of the texture.

Does OpenGL’s glTexImage2D() require that the data be extracted from a specific file format (like RAW)?
These texture’s data were extracted from .bmp files.

If so, how would I change my code to load a texture from a .bmp?

This code is called once per frame on the menu in question…


int mainMenuStep(GLint w, GLint h)
{
    static GLuint texture;
    static GLuint texture1;
    static bool init = true;

    glfwSetTime(0);

    if(init) //Loading textures (see loadTexture() same post)
    {
        texture = loadTexture("texture.bmp", 400, 86);
        texture1 = loadTexture("text.bmp", 400, 86);
    }

    if(!glIsTexture( texture )) cerr << "Texture doesn't exist!
";
    if(!glIsTexture( texture1 )) cerr << "Texture1 doesn't exist!
";

    extern bool twoD;
    extern bool mouseActed; //used to prevent individual
// clicks from performing multiple actions

    if(!glfwGetMouseButton(GLFW_MOUSE_BUTTON_LEFT) && mouseActed) mouseActed = false;

    if(!twoD) set2D();
    else glLoadIdentity();

    //START: LOGIC
    extern GLint width;
    extern GLint height;
    int mx, my;
    int highlighted;

    static Rect2D startButton(-width / 4, width / 4, 2.5 * 
height / 7, 1.5 * height / 7, false);
    static Rect2D settButton(-width / 4, width / 4, 0.5 * 
height / 7, -0.5 * height / 7, false);
    static Rect2D quitButton(-width / 4, width / 4, -1.5 * 
height / 7, -2.5 * height / 7, false);

    glfwGetMousePos(&mx, &my);
    if(startButton.intersect(mx, my, true))
    {
        highlighted = 1;
        if(glfwGetMouseButton(GLFW_MOUSE_BUTTON_LEFT) && !mouseActed)
        {
            init = true;
            glDeleteTextures(1, &texture);
            glDeleteTextures(1, &texture1);
            return INGAME;
        }
    }
    else if(settButton.intersect(mx, my, true))
    {
        highlighted = 2;
        if(glfwGetMouseButton(GLFW_MOUSE_BUTTON_LEFT) && !mouseActed)
        {
            init = true;
            glDeleteTextures(1, &texture);
            glDeleteTextures(1, &texture1);
            return SETTMENU;
        }
    }
    else if(quitButton.intersect(mx, my, true))
    {
        highlighted = 3;
        if(glfwGetMouseButton(GLFW_MOUSE_BUTTON_LEFT) && !mouseActed)
        {
            glDeleteTextures(1, &texture);
            glDeleteTextures(1, &texture1);
            return QUITTING;
        }
    }
    else highlighted = 0;
    //END: LOGIC

    //START: RENDERING
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Clear the background of our window to black
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //Clear the colour buffer

    glPushMatrix();
        //START BUTTON
        if(highlighted == 1) glColor3f(0.2f, 1.0f, 0.2f);
        else glColor3f(0.0f, 0.8f, 0.0f);
        startButton.draw(texture);
        //SETTINGS BUTTON
        if(highlighted == 2) glColor3f(1.0f, 1.0f, 0.2f);
        else glColor3f(0.8f, 0.8f, 0.0f);
        settButton.draw(texture1);
        //CLOSE BUTTON
        if(highlighted == 3) glColor3f(1.0f, 0.2f, 0.2f);
        else glColor3f(0.8f, 0.0f, 0.0f);
        quitButton.draw();

        static GLubyte letterF[24] = {
   0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00,
   0xff, 0x00, 0xff, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00,
   0xff, 0xc0, 0xff, 0xc0};

        glColor3f (1.0f, 0.0f, 1.0f);
        glRasterPos2i ((-width / 2) + 20, (height / 2) - 20);
        glBitmap (10, 12, //width and height of bitmap
                  0.0, 0.0, //origin point of bitmap
                  11.0, 0.0, //x and y shift
                  letterF); //bitmap
        glBitmap (10, 12, 0.0, 0.0, 11.0, 0.0, letterF);
        glBitmap (10, 12, 0.0, 0.0, 11.0, 0.0, letterF);

    glfwSwapBuffers();
    glPopMatrix();
    //END: RENDERING

    glfwSleep(0.01 - glfwGetTime());
    init = false;
    return MAINMENU;
}

This is the code for loadTexture(char*, int, int)


GLuint loadTexture(char* file, GLint w, GLint h)
{
    GLuint texture;
    unsigned char* data = new unsigned char[w * h * 3];
    fstream fileIn;
    fileIn.open(file, ios::in);
    int fileNameLen = strlen(file);
    if(fileIn.good())
    {
        fileIn >> data;
        fileIn.close();
    }
    else
    {
        cerr << "Failed to load texture from file: ";
        for(int i = 0; i < fileNameLen; i++)
        {
            cerr << file[i];
        }
        cerr << endl;
    }

    glGenTextures(1, &texture);
    glBindTexture( GL_TEXTURE_2D, texture );
    glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, data);

    delete[] data;

    return texture;
}

This is the code for Rect2D::draw(GLuint);


void Rect2D::draw(GLuint texture)
{
    if(scrnCoords) toGLCoords();
    glBindTexture(GL_TEXTURE_2D, texture);

    glBegin(GL_TRIANGLES);

        glTexCoord2d(0.0f, 1.0f);
        glVertex3f(left, top, 0.0f);
        glTexCoord2d(1.0f, 1.0f);
        glVertex3f(right, top, 0.0f);
        glTexCoord2d(1.0f, 0.0f);
        glVertex3f(right, bottom, 0.0f);

        glTexCoord2d(1.0f, 0.0f);
        glVertex3f(right, bottom, 0.0f);
        glTexCoord2d(0.0f, 0.0f);
        glVertex3f(left, bottom, 0.0f);
        glTexCoord2d(0.0f, 1.0f);
        glVertex3f(left, top, 0.0f);
    glEnd();
}

This is the code for Rect2D::draw(char*, GLint, GLint);

No it isn’t; that’s loadTexture again. :wink:

It’s fixed now. Thank you SO MUCH for pointing that out quickly.
:slight_smile:

GL_CLAMP

This should be GL_CLAMP_TO_EDGE.

I tried that…it says “GL_CLAMP_TO_EDGE was not declared in this scope”
Do I have to include more headers?
I’m using GLFW, so I only included glfw.h.

Should be available on glext.h :
http://www.opengl.org/registry/api/glext.h

Otherwise use an extension loader like Glew.

Ok, I included glext.h, and that solved that problem, but now the textures aren’t being rendered at all!