Search code examples
c++user-interfaceopenglglut

openGL, text changes when I load textures


I'm developing a C++ application and I need to use an interface made in openGL. I have a grey background, some squared textures over the background and some text written next to the textures. The text is yellow but when I click with mouse on the window or I change the textures, the text turns grey (a different grey from the background) and I don't know why! Here is the code and screenshots:

int main(int argc, char** argv){
    [...]
    glEnable(GL_DEPTH_TEST); 
    glDepthFunc(GL_LEQUAL);  
    glShadeModel(GL_FLAT);   
    glEnable(GL_BLEND);
    glEnable(GL_POINT_SMOOTH);

    // Render the scene
    glutDisplayFunc(display);   
    glutReshapeFunc(reshape);   

    // Turn the flow of control over to GLUT 
    glutMainLoop();

    [...]
}

void display(void){
    glClearColor(0.2f, 0.2f, 0.2f, 0.5f); //Background color
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    // Set up viewing transformation, looking down -Z axis
    glLoadIdentity();
    gluLookAt(posx, 0, -g_fViewDistance, 0, 0, -1, 0, 1, 0); 

    // Render the scene
    glMatrixMode(GL_COLOR);
    glColor3f(1.0f, 1.0f, 0.0f); // Textcolor

    drawOnScreen(); // Draw text on screen
    glMatrixMode(GL_MODELVIEW);

    loadSquare(); // Load texture
    glutSwapBuffers();
}

void reshape(GLint width, GLint height){
    interface->setWindowWidth(width);
    interface->setWindowHeight(height);
    glViewport(0, 0, g_Width, g_Height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(65.0, (float)g_Width / g_Height, g_nearPlane, g_farPlane);
    glMatrixMode(GL_MODELVIEW);
}

void printStringOnVideo(void* font, char* s){
    if (s && strlen(s)) {
        while (*s) {
            glutBitmapCharacter(font, *s);
            s++;
        }
    }
}

void drawOnScreen(){
    GLfloat x, y;
    // Draw the strings, according to the current mode and font. 
    x = 2.90f;
    y = 0.80f;
    glRasterPos2f(x, y);
    int len;
    char s[] = { 'H', 'E', 'L', 'L', 'O', '\0' };
    len = (int)strlen(s);
    printStringOnVideo(GLUT_BITMAP_TIMES_ROMAN_24, s);
}

The loadSquare() function applies texture to squares. Its main feature is calling the class method for loading textures on squares:

void P300Square::setTexture(bool func){
// Se func = 0 allora carico la texture, viceversa il flash

string tmp = "";

if (func == false)
    tmp = texturePath;
else
    tmp = textureFlashPath;

GLuint texture = SOIL_load_OGL_texture
    (
    tmp.c_str(),
    SOIL_LOAD_AUTO,
    SOIL_CREATE_NEW_ID,
    SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT
    );
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glColor3ub(50, 50, 50);


glEnable(GL_BLEND);
glBegin(GL_QUADS);
glColor4f(0.5f, 0.0, 0.0f, 0.8f);
// Top Left
glTexCoord2f(0, 1);
glVertex2f(u, v);
// Top Right
glTexCoord2f(1, 1);
glVertex2f(u + size, v);
// Bottom Right
glTexCoord2f(1, 0);
glVertex2f(u + size, v + size);
// Bottom Left
glTexCoord2f(0, 0);
glVertex2f(u, v + size);

glEnd();
glDisable(GL_BLEND);
}

Text on application startup

Text after clicking

Can please someone help me? Thank you!


Solution

  • You should disable GL_TEXTURE_2D before you draw the bitmap font.

    Internally, glutBitmapCharacter() uses glBitmap. This function maps the bitmap to a rectangle to the screen and generates a fragment for every framebuffer pixel in that rectangle where the bitmap is 1. Those fragments get the associated data from the values associated with the current raster position.

    The generated fragments are processed like every other fragment (i.e. the ones generated by drawing primitives like lines or triangles). So stuff like texturing, lighting, fog, blending and so on will also affect everything drawn by glBitmap. Due to the fact that all fragments generated by a single bitmap get the same associated data, they all will get the same texture coordinate. Since you left texturing on, the GL textures all of these fragments with the very same sample from the texture, so that they all appear in the same color.