Удаление невидимых поверхностей
Удаление невидимых – сложная задача. Зачастую, с целью получения эффективной программы, программисту приходится комбинировать возможности, предоставляемые OpenGL (использование буфера глубины), с собственными алгоритмическими приемами. Ниже приведены те действия, которые необходимо включить в программу, для решения задачи удаления невидимых с использованием только буфера глубины. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) – вместе с очисткой буфера цвета предусмотреть очистку буфера глубины. glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH) – устанавливая режим дисплея в функции main(), предусмотреть использование буфера глубины. glEnable(GL_DEPTH_TEST) – включение режима удаления невидимых. glDisable(GL_DEPTH_TEST) – выключение режима удаления невидимых. Ниже приведен текст программы, иллюстрирующий изложенный материал. #include <gl\glut.h> #include <math.h> GLfloat angle=0; void init(void) { glClearColor(1.0, 1.0, 0.0, 0.0); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60, 1, 1, 10); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void myDisplay() { glPushMatrix(); //Сохраняем VM = 1 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); gluLookAt(3, 2, 1, 0, 0, 0, 0, 1, 0); // VM=Fwe GLfloat myLightPosition[] = {3.0, 3.0, 3.0, 1.0}; // Источник света в CKw glLightfv(GL_LIGHT0, GL_POSITION, myLightPosition); /*Позиция источника света будет преобразована в CKe*/ glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glPushMatrix(); //Сохраняем VM=Fwe glRotatef(angle, 0, 1, 0); // VM=Fwe*R glRotatef(angle, 0, 1, 0); // VM=Fwe*R*R glRotatef(angle, 0, 0, 1); // VM=Fwe*R*R*R glutSolidCube(0.95); //glutWireCube(0.95); glPopMatrix(); // Восстанавливаем VM=Fwe glDisable(GL_LIGHTING); //Выключаем освещение glBegin(GL_LINES); glColor3f(1,0,0); glVertex3f(0, 0, 0); glVertex3f(1, 0, 0); glColor3f(0,1,0); glVertex3f(0, 0, 0); glVertex3f(0, 1, 0); glColor3f(0,0,1); glVertex3f(0, 0, 0); glVertex3f(0, 0, 1); glEnd(); glBegin(GL_LINES); glColor3f(1,1,1); glVertex3f(3, 3, 3); glVertex3f(0.0, 0.0, 0.0); glEnd(); glPopMatrix();
glutSwapBuffers(); } void myReshape(int width, int height) { if(width/height<1) glViewport(0, 0, width, width); else glViewport(0, 0, height, height); } void myIdle() { angle+=0.5; if(angle > 360.0) angle=0; glutPostRedisplay(); } int main(int argc, char* argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowSize(800, 800); glutInitWindowPosition(0, 0); glutCreateWindow("my window"); glutDisplayFunc(myDisplay); glutReshapeFunc(myReshape); glutIdleFunc(myIdle); init(); glutMainLoop(); }
|