如何在openGL中修复位图照明

How to fix bitmap lighting in openGL?

本文关键字:复位 位图 照明 openGL      更新时间:2023-10-16

我需要有关使用 OpenGL API 的C++代码的帮助。我编写了一个程序,可以在屏幕上绘制 4 个 3D 立方体和文本(使用位图(。现在我想添加照明。

我添加了glMaterial代码来描述立方体的材料。我不希望将材料属性应用于位图文本。 因此,我在绘制立方体之前放置了材质的代码,并且还将绘制立方体和材质的代码放在pushMatrix对和popMatrix对之间。但是,当我运行代码时,我发现文本改变了颜色。

以下是我正在使用的一些代码:

void init() {
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ligAmb);
glEnable(GL_LIGHTING);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lig[0][0]);
glLightfv(GL_LIGHT0, GL_SPECULAR, lig[0][1]);
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, ligDir);
glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, exp_one);
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, cutoff);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT1, GL_DIFFUSE, lig[1][0]);
glLightfv(GL_LIGHT1, GL_SPECULAR, lig[1][1]);
glEnable(GL_LIGHT1);
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
void drawCube(Point3D colors[], Point3D vertices[]) {
glBegin(GL_QUADS);
glColor3fv(colors[1]);
glVertex3fv(vertices[1]);
glColor3fv(colors[5]);
glVertex3fv(vertices[5]);
glColor3fv(colors[7]);
glVertex3fv(vertices[7]);
glColor3fv(colors[3]);
glVertex3fv(vertices[3]);
glColor3fv(colors[7]);
glVertex3fv(vertices[7]);
glColor3fv(colors[6]);
glVertex3fv(vertices[6]);
glColor3fv(colors[2]);
glVertex3fv(vertices[2]);
glColor3fv(colors[3]);
glVertex3fv(vertices[3]);
glColor3fv(colors[2]);
glVertex3fv(vertices[2]);
glColor3fv(colors[6]);
glVertex3fv(vertices[6]);
glColor3fv(colors[4]);
glVertex3fv(vertices[4]);
glColor3fv(colors[0]);
glVertex3fv(vertices[0]);
glColor3fv(colors[5]);
glVertex3fv(vertices[5]);
glColor3fv(colors[4]);
glVertex3fv(vertices[4]);
glColor3fv(colors[6]);
glVertex3fv(vertices[6]);
glColor3fv(colors[7]);
glVertex3fv(vertices[7]);
glColor3fv(colors[4]);
glVertex3fv(vertices[4]);
glColor3fv(colors[5]);
glVertex3fv(vertices[5]);
glColor3fv(colors[1]);
glVertex3fv(vertices[1]);
glColor3fv(colors[0]);
glVertex3fv(vertices[0]);
glColor3fv(colors[0]);
glVertex3fv(vertices[0]);
glColor3fv(colors[1]);
glVertex3fv(vertices[1]);
glColor3fv(colors[3]);
glVertex3fv(vertices[3]);
glColor3fv(colors[2]);
glVertex3fv(vertices[2]);
glEnd();

}
void displayObject() {
glPushMatrix();
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glLightfv(GL_LIGHT0, GL_POSITION, ligPos[0]);
glLightfv(GL_LIGHT1, GL_POSITION, ligPos[1]);
typedef GLint vertex3[3];
Point3D vertices[8] = { {-1.0, -1.0, -1.0},
                {-1.0, -1.0,  1.0},
                {-1.0,  1.0, -1.0},
                {-1.0,  1.0,  1.0},
                { 1.0, -1.0, -1.0},
                { 1.0, -1.0,  1.0},
                { 1.0,  1.0, -1.0},
                { 1.0,  1.0,  1.0} };
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_INT, 0, vertices);
GLubyte vertIndex[] = { 6,2,3,7,5,1,0,4,7,3,1,5,4,0,2,6,2,0,1,3,7,5,4,6 
};
glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, vertIndex);
glPopMatrix();


Point3D colorsb[8] = { {0.,0.,1.},
                    {0.,0.,1.},
                    {0.,0.,1.},
                    {0.,0.,1.},
                    {0.,0.,1.},
                    {0.,0.,1.},
                    {0.,0.,1.},
                    {0.,0.,1.} };
Point3D colorsg[8] = { {0.,1.,0.},
                    {0.,1.,0.},
                    {0.,1.,0.},
                    {0.,1.,0.},
                    {0.,1.,0.},
                    {0.,1.,0.},
                    {0.,1.,0.},
                    {0.,1.,0.} };
Point3D colorsr[8] = { {1.,0.,0.},
                    {1.,0.,0.},
                    {1.,0.,0.},
                    {1.,0.,0.},
                    {1.,0.,0.},
                    {1.,0.,0.},
                    {1.,0.,0.},
                    {1.,0.,0.} };
Point3D colorsy[8] = { {1.,1.,0.},
                    {1.,1.,0.},
                    {1.,1.,0.},
                    {1.,1.,0.},
                    {1.,1.,0.},
                    {1.,1.,0.},
                    {1.,1.,0.},
                    {1.,1.,0.} };

glPushMatrix();
glTranslatef(-0.5f, 4.0f, -6.0f);
glRotatef(10.0, 0.0, 1.0, 0.0);
glRotatef(loop, 0.0, 1.0, 0.0);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat[0][0]);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat[0][1]);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat[0][2]);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shi[0]);
drawCube(colorsb, vertices);
glPopMatrix();
glPushMatrix();
glTranslatef(6.0f, -0.5f, -6.0f);
glRotatef(10.0, 1.0, 0.0, 0.0);
glRotatef(loop, 0.0, 1.0, 0.0);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat[1][0]);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat[1][1]);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat[1][2]);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shi[1]);
drawCube(colorsg, vertices);
glPopMatrix();
glPushMatrix();
glTranslatef(-0.5f, -4.5f, -6.0f);
glRotatef(10.0, 0.0, 1.0, 0.0);
glRotatef(loop, 0.0, 1.0, 0.0);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat[2][0]);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat[2][1]);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat[2][2]);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shi[2]);
drawCube(colorsr, vertices);
glPopMatrix();
glPushMatrix();
glTranslatef(-6.0f, -0.5f, -6.0f);
glRotatef(10.0, 1.0, 0.0, 0.0);
glRotatef(loop, 0.0, 1.0, 0.0);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat[3][0]);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat[3][1]);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat[3][2]);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shi[3]);
drawCube(colorsy, vertices);
glPopMatrix();
}


void display() {

    displayObject();

    wordColor = "green";
    char str[] = { "Red" };
    glColor3f(0.0, 1.0, 0.0);
    glRasterPos2f(-0.5, 0.0);
    for (int i = 0; i < strlen(str); i++)
    {
        glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, str[i]);
    }
    glPopMatrix();
    loop += 0.05;
    glFlush();
    glutSwapBuffers();
    glutPostRedisplay();
    }

OpenGL是一个状态机,这意味着它会保持状态,直到你再次显式更改它。因此,当您在绘制一帧期间仅在绘制文本后注意设置照明时,它将在绘制下一帧的文本之前发生。

解决方案是,在绘制之前,您始终为正在绘制的任何内容设置每个相关状态。对于文本,就像在绘制文本之前(实际上是在调用glRasterPos之前(禁用照明一样简单。