#include #include #include #include using namespace std; static int window; int LightType = 1; void init(void) { glClearColor(0.0, 0.0, 0.0, 0.0);//задает цвет, в который окно будет окрашиваться при его очистке glEnable(GL_LIGHTING); // включается расчет освещенности glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);// выбор модели освещения //расчет освещенности производится для всех полигонов, являются ли они лицевыми или обратными glEnable(GL_NORMALIZE); // автоматическое приведение нормалей к единичной длине } void reshape(int width, int height) // изменение размеров окна { glViewport(0, 0, width, height); // двухмерное окно вывода glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (width <= height) glOrtho(-1.5, 1.5, -1.5*(GLfloat)height / (GLfloat)width, 1.5*(GLfloat)height / (GLfloat)width, -10.0, 10.0); else glOrtho(-1.5*(GLfloat)width / (GLfloat)height, 1.5*(GLfloat)width / (GLfloat)height, -1.5, 1.5, -10.0, 10.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void display(void) { GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 0.0 };// цвет зеркального отблеска GLfloat mat_shininess[] = { 120.0 };//степень в формуле зеркального отражения (коэффициент блеска). Допускаются значения в интервале [0; 128]. glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);//для каких граней объекта задается свойство материала, зеркальный цвет материала glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);//показатель зеркального отражения if (LightType == 1) //направленный источник света { GLfloat Light0_diffuse[] = { 0.5, 0.2, 0.906, 0.0 };// цвет источника света (послед. координата равна нулю) GLfloat Light0_position[] = { -1.0, -1.0, 1.0, 1.0 };// позиция источника света glEnable(GL_LIGHT0); glLightfv(GL_LIGHT0, GL_DIFFUSE, Light0_diffuse); // для какого источника света; (свойства источника света) // компонента излучения (фоновая, рассеянная, зеркальная) glLightfv(GL_LIGHT0, GL_POSITION, Light0_position); glEnable(GL_DEPTH_TEST);//выполняет проверку видимости граней, если будет выключена, объекты не будут закрывать друг друга glEnable(GL_NORMALIZE); } if (LightType == 2) //точечный источник света { GLfloat Light1_diffuse[] = { 0.0, 0.19, 1.0, 1.0 }; GLfloat Light1_position[] = { -1.0, 1.0, 1.0, 1.0 }; glEnable(GL_LIGHT1); glLightfv(GL_LIGHT1, GL_DIFFUSE, Light1_diffuse); glLightfv(GL_LIGHT1, GL_POSITION, Light1_position); glEnable(GL_DEPTH_TEST); glEnable(GL_NORMALIZE); } if (LightType == 3) //точечный источник света с убыванием интенсивности { GLfloat Light2_diffuse[] = { 0.0, 1.0, 1.0, 1.0 }; GLfloat Light2_position[] = { -1.0, 1.0, 1.0, 1.0 }; glEnable(GL_LIGHT2); glLightfv(GL_LIGHT2, GL_DIFFUSE, Light2_diffuse);//интенсивность диффузного света glLightfv(GL_LIGHT2, GL_POSITION, Light2_position); glLightf(GL_LIGHT2, GL_CONSTANT_ATTENUATION, 0.3); //постоянная k_const в функции затухания f(d) glLightf(GL_LIGHT2, GL_LINEAR_ATTENUATION, 0.6); //коэффициент k_linear при линейном члене в функции затухания f(d) glLightf(GL_LIGHT2, GL_QUADRATIC_ATTENUATION, 1.2);//коэффициент k_quadratic при квадрате расстояния в функции затухания f(d) glEnable(GL_DEPTH_TEST); glEnable(GL_NORMALIZE); } if (LightType == 4) //несколько источников света { GLfloat Light3_diffuse[] = { 1.0, 0.0, 0.0, 1.0 }; GLfloat Light3_position[] = { 1.0, 1.0, 1.0, 1.0 }; glLightfv(GL_LIGHT3, GL_DIFFUSE, Light3_diffuse); glLightfv(GL_LIGHT3, GL_POSITION, Light3_position); glLightf(GL_LIGHT3, GL_CONSTANT_ATTENUATION, 0.0); glLightf(GL_LIGHT3, GL_LINEAR_ATTENUATION, 0.4); glLightf(GL_LIGHT3, GL_QUADRATIC_ATTENUATION, 0.8); glEnable(GL_LIGHT3); GLfloat Light5_diffuse[] = { 0.0, 1.0, 0.0, 1.0 }; GLfloat Light5_position[] = { -1.0, 1.0, 1.0, 1.0 }; glLightfv(GL_LIGHT5, GL_DIFFUSE, Light5_diffuse); glLightfv(GL_LIGHT5, GL_POSITION, Light5_position); glLightf(GL_LIGHT5, GL_CONSTANT_ATTENUATION, 0.0); glLightf(GL_LIGHT5, GL_LINEAR_ATTENUATION, 0.4); glLightf(GL_LIGHT5, GL_QUADRATIC_ATTENUATION, 0.8); glEnable(GL_LIGHT5); GLfloat Light4_diffuse[] = { 0.0, 0.0, 1.0, 1.0 }; GLfloat Light4_position[] = { -1.0, -1.0, 1.0, 1.0 }; glLightfv(GL_LIGHT4, GL_DIFFUSE, Light4_diffuse); glLightfv(GL_LIGHT4, GL_POSITION, Light4_position); glLightf(GL_LIGHT4, GL_CONSTANT_ATTENUATION, 0.0); glLightf(GL_LIGHT4, GL_LINEAR_ATTENUATION, 0.4); glLightf(GL_LIGHT4, GL_QUADRATIC_ATTENUATION, 0.8); glEnable(GL_LIGHT4); glEnable(GL_DEPTH_TEST); glEnable(GL_NORMALIZE); } if (LightType == 5) //рассеянный источник света //свет, который настолько распределен средой, что его направление определить невозможно { GLfloat Light7_ambient[] = { 0.0, 1.0, 0.0, 1.0 }; GLfloat Light7_position[] = { 1.0, 1.0, 1.0, 1.0 }; //GLfloat Light7_spec[] = { 1.0, 1.0, 1.0, 1.0 }; //GLfloat light7_diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; glEnable(GL_LIGHT7); glLightfv(GL_LIGHT7, GL_AMBIENT, Light7_ambient); // интенсивность фонового света,влияет на цвет зеркального блика на объект //glLightfv(GL_LIGHT7, GL_SPECULAR, Light7_spec); // цвет зеркального отблеска //glLightfv(GL_LIGHT6, GL_DIFFUSE, light7_diffuse); glLightfv(GL_LIGHT7, GL_POSITION, Light7_position); } if (LightType == 6) //прожектор { GLfloat light6_diffuse[] = { 0.4, 0.1, 0.2 }; GLfloat light6_position[] = { 0.0, 0.0, 1.0, 1.0 }; GLfloat light6_spot_direction[] = { 0.0, 0.2, -1.0 }; glEnable(GL_LIGHT6); glLightfv(GL_LIGHT6, GL_DIFFUSE, light6_diffuse); glLightfv(GL_LIGHT6, GL_POSITION, light6_position); glLightf(GL_LIGHT6, GL_SPOT_CUTOFF, 40); // угловая ширина светового луча glLightfv(GL_LIGHT6, GL_SPOT_DIRECTION, light6_spot_direction);// направление прожектора } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glutSolidSphere(0.8, 100, 100); // сплошная сфера: радиус, количество разбиений вдоль, поперек //glutSolidTorus(0.275, 0.85, 40, 40); glFlush(); glDisable(GL_LIGHT0); glDisable(GL_LIGHT1); glDisable(GL_LIGHT2); glDisable(GL_LIGHT3); glDisable(GL_LIGHT4); glDisable(GL_LIGHT5); glDisable(GL_LIGHT6); glDisable(GL_LIGHT7); glutSwapBuffers(); } void MenuCheck(int v) { if (v == 0) { glutDestroyWindow(window); exit(0); } else { LightType = v; } glutPostRedisplay(); } void SubMenuCheck(int v) { if (v == 0) { glutDestroyWindow(window); exit(0); } else { LightType = v; } glutPostRedisplay(); } void MenuInit() { int M = glutCreateMenu(MenuCheck);//функция, которая будет обрабатывать события для вновь созданного меню. //Возвращаемое значение этой функции является идентификатором. int Msub = glutCreateMenu(SubMenuCheck); glutSetMenu(M); glutAddMenuEntry("Включить направленный источник света", 1); glutAddSubMenu("Точечный источник", Msub); glutSetMenu(Msub); glutAddMenuEntry("Включит точечный источник света", 2); glutAddMenuEntry("Точечный источник с убыванием интенсивности", 3); glutSetMenu(M); glutAddMenuEntry("Включить несколько источников света", 4); glutAddMenuEntry("Включить рассеянный источник света", 5); glutAddMenuEntry("Включить прожектор", 6); glutAttachMenu(GLUT_LEFT_BUTTON); } int main(int argc, char** argv) { setlocale(LC_ALL, "rus"); cout << "Подождите, пожалуйста \n"; glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize(700, 700); glutInitWindowPosition(500, 100); glutCreateWindow(argv[0]); init(); glutDisplayFunc(display); glutReshapeFunc(reshape); MenuInit(); glutMainLoop(); return 0; }