#c #opengl #lighting
#c #opengl #Освещение
Вопрос:
Мне нужна помощь с моим кодом на C с использованием OpenGL API. Я написал программу, которая рисует 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();
}
Ответ №1:
OpenGL — это конечный автомат, что означает, что он сохраняет состояние до тех пор, пока вы явно не измените его снова. Поэтому, если вы позаботитесь о том, чтобы установить освещение только после рисования текста во время рисования одного кадра, это произойдет до рисования текста в следующем кадре.
Решение заключается в том, что вы всегда устанавливаете каждое соответствующее состояние для того, что вы рисуете, прямо перед тем, как нарисовать это. В случае текста это так же просто, как отключить освещение, прямо перед рисованием текста (фактически перед вызовом glRasterPos
).