copenglglutopengl-compat

Issues with the color comand in OpenGL


The code ahead is supposed to draw the text in escolha_de_magias in red, but keeps drawing it in green.

#include<GL/glut.h>

#include <stdio.h>

const int posicao=28.0;/*esta constante sera usada para fixar a posicao do inicio do texto para a funcao de escrita*/

float VERTICAL=30.0, HORIZ=30.0;

int seletor=1;

char escolha_de_magias[]={"A whole bunch of text"};

void escritoura (char *p)/* FUNCAO QUE ESCREVE NA TELA. Esta pronta mas sujeita a mudanças*/
{
    int contcarac=0, position=posicao, selecao=0;
    
    float cor[4]={ 0.0, 0.0, 0.0, 0.0};
    
    p++;
    
    glRasterPos2f(-28.0, position);
    
    while(*p)
    {
        if(*p=='1' || *p=='2' || *p=='3' || *p=='4' || *p=='5' || *p=='6' || *p=='7' || *p=='8' || *p=='9' || *p=='0')/* testa se eu estou olhando para um algarismo*/
        {
            glColor3d(1.0, 0.0, 0.0);
        }
    }
    
    glutBitmapCharacter(GLUT_BITMAP_8_BY_13, *p);
    
    p++;
    
    contcarac++;
    return;
}

void ABACAXI()
{
    glClearColor(1.0,1.0,1.0,0.0);
    glClear(GL_COLOR_BUFFER_BIT);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(HORIZ-60.0, HORIZ, VERTICAL-60.0, VERTICAL,1,100);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(0.0, 0.0, -5.0);

    glColor3d(0.0, 1.0, 0.0);

    glBegin(GL_LINE_STRIP);
    glVertex3d(-30.0, -30.0, 0.0);
    glVertex3d(-30.0, 30.0, 0.0);
    glVertex3d(30.0, 30.0, 0.0);
    glVertex3d(30.0, -30.0, 0.0);
    glEnd();

    escritoura(escolha_de_magias);

    glFlush();
}

void teclado(int tecla, int x, int y)
{
    switch(tecla)
    {
        case GLUT_KEY_UP:
        VERTICAL++;
        break;

        case GLUT_KEY_DOWN:
        VERTICAL--;
        break;

        case GLUT_KEY_RIGHT:
        HORIZ++;
        break;

        case GLUT_KEY_LEFT:
        HORIZ--;
        break;
    }
    
    glutPostRedisplay();
}

int main(int argc, char **argv)
{
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(1000,700);
    glutCreateWindow("Alo!");
    glutDisplayFunc(ABACAXI);
    glutSpecialFunc(teclado);
    glutPostRedisplay();
    glutMainLoop();
} 

I made a test with glGetFloatv(GET_CURRENT_COLOR, cor) function right before the first calling of glutBitmapCharacter() and it returned that the color of drawing is set to red.

I don't know whats happening


Solution

  • The color which is use for drawing characters by glutBitmapCharacter is set by glRasterPos. glRasterPos takes the current color set by glColor and associates it.

    You have to se the the red color before glRasterPos2f, to draw a red text.

    glColor3d(1.0, 0.0, 0.0);
    glRasterPos2f(-28.0, position);
    

    Your text appears in green, because the last color set before the call of glRasterPos2f, was the color for the GL_LINE_STRIP primitive.

    If you want to draw a text with different colors, then you have to do multiple calls to glRasterPos at every point when the color of the text changes.


    The current raster position can be get by glGetFloatv using the parameter GL_CURRENT_RASTER_POSITION:

    float pos[4];
    glGetFloatv( GL_CURRENT_RASTER_POSITION, pos );
    

    Sadly you may not get the position which you have set by glRasterPos, because the coordinates which are passed to glRasterPos are transformed by the current model view matrix and projection matrix, but when you read back the position, then you will get the transformed coordinates and the coordinates are window coordinates rather than normalized device coordinates.


    If you want to change the associated color, but to keep the raster position, then you have to read the raster current position glGetFloatv(GL_CURRENT_RASTER_POSITION, ...).
    This will return window coordinates.
    So you have to set an orthographic projection, which transforms from window coordinates to normalized device coordinates, before glRasterPos can be called again to associate a new color. the model view matrix has to be the identity matrix.

    Change the function escritoura somehow as follows, to solve your issue:

    void escritoura (char *p)
    {
        int contcarac=0, position=posicao, selecao=0;
        p++; 
        glRasterPos2f(-28.0f, position);
        while(*p)
        {
            if(*p=='1' || *p=='2' || *p=='3' || *p=='4' || *p=='5' || *p=='6' || *p=='7' || *p=='8' || *p=='9' || *p=='0')
            {
                // get the current raster position in window coordinates
                float pos[4];
                glGetFloatv( GL_CURRENT_RASTER_POSITION, pos );    
    
                // push model view matrix and set identity matrix
                glMatrixMode(GL_MODELVIEW);
                glPushMatrix();
                glLoadIdentity();
    
                // push projection matrix and set transformation form window coordinates to NDC
                glMatrixMode(GL_PROJECTION);
                glPushMatrix();
                glLoadIdentity();
                glOrtho( 0, 1000, 0, 700, -1, 1 ); // (1000, 700) is the window size!
    
                // change current color
                glColor3d( 1.0, 0.0, 0.0 );
    
                // associate new color, but keep position
                glRasterPos4fv( pos );
    
                // restore (pop) model view and projection matrix
                glMatrixMode(GL_PROJECTION);
                glPopMatrix();
                glMatrixMode(GL_MODELVIEW);
                glPopMatrix();
            }
            glutBitmapCharacter(GLUT_BITMAP_8_BY_13, *p);
            p++; contcarac++;
        }
        return;
    }