OpenGL 中颜色命令的问题

Issues with the color comand in OpenGL

#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[]={"?1-Copia de Criatura: Faz uma replica perfeita de qualquer"/* criatura contra a qual voce esteja lutando. A replica tera os mesmos poderes do orignal, mas estara sob seu controle@2-Percepcao Extra-Sensorial: Sintoniza ondas psiquicas. Isso podera ajuda-lo a ler a mente de uma criatura ou descobrir o que esta por tras de uma porta trancada. Mas este encanto pode dar informacoes equivokdas, se houver + de a font psikica perto de uma outra.@3-Fogo: Tds as criaturas tm medo d fogo, e ste enknto da o podr d fazr aparecr fogo o sua vontad. Vc pdera causr a pkena xplosao n chao q keimara pr varios os ou criar a brreira d fogo p mantr criaturas a dstancia.@4-Ouro dos Tolos: Trnsforma pdra comum em a plha do q parece sr ouro. Mas eh apnas a ilusao - embora + confiavl q o Enknto d ilusao abaixo - e a plha d ouro logo voltara a sr pdra.@5-Ilusao: Ste e  enknto podroso, mas q n e mto confiavl. Prmit criar a ilusao convncnte (pr exemplo, q o chao sta cobrto d krvao em brasa) p enganr a criatura. O enknto fikra imediatamnt sm efeito s acontcr qlqr coisa q dsfaca a ilusao (pr exemplo, vc convnc a criatura q s trnsformou em a serpnt e entao imediatamnt atnge sua kbca c  golp d spada!). e efcient sbre td c criaturas intlignts.@6-Levitacao: Vc pde lancr ste enknto sbre objtos, advrsarios ou ate sbre si msm. Fara cm q tdo q estja sob sua influencia flutue livremnt no ar, sob o seu cntrole.@7-Escudo: Cria um scudo invsivl à sua frent q o protgera d objtos fsicos, cm flechas, spadas ou criaturas. O scudo n tm efeito cntra a magia e, evdntmnte, s nd fora dle pod tokr em vc, vc tbm n podra tokr em nd fora dle.@8-Sorte: Este enknto e spcial pq pod sr lancado a qlqr momnto durante a sua avntura, a n sr durant a batalha. a vz lancado, recuperara o seu indce d SORTE em metad d seu indce d SORTE Inicial, arredondado p baixo. Ste enknto nunk lvara o seu indce d SORTE a  nmro suprior a seu nivl Inicial.@9-Habilidade: Restabelecera o seu indce d HABILIDADE. Funciona exatamnt cm o enknto d Sort.@10-Energia: Recuperara o seu indce d Energia, aumentando-o em metad d seu vlr Inicial. Funciona cmo o enknto d Sort@11-Forca: Ste enknto tm o efeito d aumentr mto a sua frca, e e mto utl qnd s luta cntra criaturas forts. Porm, dv sr utlizado c cautla, ja q e dfcil controlr a sua prpria frca qnd ela aumnta d+@12-Fraqueza: N tm efeito cntra tds as criatras, ms qnd tm, a criatra s trna fragl e mto mnos prigosa em a btalha"*/};

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*/
        {
          /*if(*(p+1)!='1' && *(p+1)!='2' && *(p+1)!='3' && *(p+1)!='4' && *(p+1)!='5' && *(p+1)!='6' && *(p+1)!='7' && *(p+1)!='8' && *(p+1)!='9' && *(p+1)!='0')/*testa se o proximo nao e 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();
} 

前面的代码应该将 escolha_de_magias 中的文本绘制成红色,但一直绘制成绿色。
我在第一次调用 glutBitmapCharacter() 之前用 glGetFloatv(GET_CURRENT_COLOR, cor) 函数进行了测试,它返回绘图的颜色设置为红色。

我不知道发生了什么

glutBitmapCharacter is set by glRasterPos. glRasterPos takes the current color set by glColor用于绘制字符并与之关联的颜色。

您必须在 glRasterPos2f 之前选择红色才能绘制红色文本。

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

您的文本显示为绿色,因为调用 glRasterPos2f 之前设置的最后颜色是 GL_LINE_STRIP 基元的颜色。

如果你想用不同的颜色绘制文本,那么当文本颜色改变时,你必须在每个点多次调用 glRasterPos


当前光栅位置可以通过glGetFloatv使用参数GL_CURRENT_RASTER_POSITION:

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

遗憾的是,您可能无法获得您通过glRasterPos设置的位置,因为传递给glRasterPos的坐标是由当前模型视图矩阵和投影矩阵转换的,但是当您回读位置,然后您将获得转换后的坐标,并且坐标是 window 坐标而不是归一化的设备坐标。


如果你想改变关联的颜色,但要保持光栅位置,那么你必须读取光栅当前位置glGetFloatv(GL_CURRENT_RASTER_POSITION, ...)
这将 return window 坐标。
所以你必须设置一个正交投影,它从 window 坐标转换为标准化设备坐标,然后才能再次调用 glRasterPos 以关联新颜色。模型视图矩阵必须是单位矩阵。

按如下方式更改函数 escritoura,以解决您的问题:

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;
}