#include #include // Definicja stalych #define DLUGOSC_BOKU 4.0 #define OBSERWATOR_ODLEGLOSC 20.0 #define OBSERWATOR_FOV_Y 30.0 float alfa; #define PI 3.1415926535 #define DEG2RAD(x) ((float)(x)*PI/180.0) // Zmienne globalne double bok = DLUGOSC_BOKU; // dlugosc boku szescianu int szerokoscOkna = 800; int wysokoscOkna = 600; float podzial = 5.0; float xx = 0.0; float yy = 0.0; float zz = 0.0; float x; float y; float xxx_obrot = 30.0; float yyy_obrot = 30.0; float zzz_obrot = 0.0; float r = 3.0; double i, j; // Prototypy funkcji void RysujSzescian(double a); void UstawParametryWidoku(int szer, int wys); void WyswietlObraz(void); void ObslugaKlawiatury(unsigned char klawisz, int x, int y); float radian(double a) { return (a * PI) / 180; } ////////////////////////////////////////////////////////////////////////////////////////// // Funkcja rysujaca sferę w trybie GL_TRIANGLES. // Srodek sfery znajduje się w punkcie (0,0,0). void RysujKolo(float R, float y, int n) { int i; float x; float z; glBegin(GL_TRIANGLE_FAN); glVertex3f(0, 0, 0); alfa = 360 / n; for (j = 0; j < 360; j += alfa) { float rad = radian(j); x = cos(rad); z = sin(rad); glVertex3f(x * R, y, z * R); } /*for (i = 0; i <= n; i++) { float rad = radian(i * alfa); x = cos(rad); z = sin(rad); glVertex3f(x * R, y , z * R); }*/ x = cos(0.0); z = sin(0.0); glVertex3f(x * R, y , z * R); glEnd(); } void RysujSzescian() { float angle; int i; int j; float x1, y1, z1, x2, y2, z2, x3, z3, y3; //Narysowanie linii pomocniczych glBegin(GL_LINES); // Os X glColor3f(0.3, 0.8, 0.3); glVertex3f(0.0, 0.0, 0.0); glVertex3f(10.0, 0.0, 0.0); // Os Y glColor3f(0.8, 0.3, 0.3); glVertex3f(0.0, 0.0, 0.0); glVertex3f(0.0, 10.0, 0.0); // Os Z glColor3f(0.1, 0.1, 0.8); glVertex3f(0.0, 0.0, 0.0); glVertex3f(0.0, 0.0, 10.0); glEnd(); //Narysowanie sfery glColor3f(1, 1, 1); RysujKolo(r, 0, podzial); glColor3f(1, 0, 1); glBegin(GL_TRIANGLES); alfa = 360 / podzial; for (i = 0; i < 180; i += alfa) { for (j = 0; j < 360; j += alfa) { glVertex3f(r * cos(radian(i + alfa)) * cos(radian(j)), r * sin(radian(i + alfa)), r * cos(radian(i + alfa)) * sin(radian(j))); glVertex3f(r * cos(radian(i)) * cos(radian(j + alfa)), r * sin(radian(i)), r * cos(radian(i)) * sin(radian(j + alfa))); glVertex3f(r * cos(radian(i )) * cos(radian(j)), r * sin(radian(i)), r * cos(radian(i)) * sin(radian(j)) ); /*x1 = r * cos(j) * cos(i); y1 = r * sin(i); z1 = r * sin(j) * cos(i); y2 = r * sin(i+alfa); x3 = r * cos(j+alfa) * cos(i); glVertex3f(x1, y1, z1); glVertex3f(x1, y2, z1); glVertex3f(x3, y1, z1);*/ /*if (i == 0) { glColor3f(0, 0, 1); glVertex3f(0.0, 0.0, 0.0); glVertex3f(r*cos(radian(i))*cos(radian(j)), r*sin(radian(i)), r*cos(radian(i))*sin(radian(j))); glVertex3f(r*cos(radian(i))*cos(radian(j + podzial)), r*sin(radian(i)), r*cos(radian(i))*sin(radian(j + podzial))); }*/ } } glEnd(); } ////////////////////////////////////////////////////////////////////////////////////////// // Funkcja ustawiajaca parametry rzutu perspektywicznego i rozmiary viewportu. Powinna // być wywolywana kazdorazowo po zmianie rozmiarow okna programu. void UstawParametryWidoku(int szer, int wys) { // Zapamietanie wielkosci widoku szerokoscOkna = szer; wysokoscOkna = wys; // Ustawienie parametrow viewportu glViewport(0, 0, szerokoscOkna, wysokoscOkna); // Przejscie w tryb modyfikacji macierzy rzutowania glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(OBSERWATOR_FOV_Y, (float)szerokoscOkna / (float)wysokoscOkna, 1.0, 1000.0); } ////////////////////////////////////////////////////////////////////////////////////////// // Funkcja wyswietlajaca pojedyncza klatke animacji void WyswietlObraz(void) { // Wyczyszczenie bufora koloru i bufora glebokosci glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Przejscie w tryb modyfikacji macierzy przeksztalcen geometrycznych glMatrixMode(GL_MODELVIEW); // Zastapienie aktywnej macierzy macierza jednostkowa glLoadIdentity(); // Ustalenie polozenia obserwatora glTranslatef(xx, yy, zz); // odległość obserwatora od osi X,Y,Z glTranslatef(0, 0, -OBSERWATOR_ODLEGLOSC); //Funkcje odpowiedzialne za obrót względem wybranej osi glRotatef(xxx_obrot, 1, 0, 0); glRotatef(yyy_obrot, 0, 1, 0); glRotatef(zzz_obrot, 0, 0, 1); // Narysowanie szescianu RysujSzescian(); // Przelaczenie buforow ramki glutSwapBuffers(); } ////////////////////////////////////////////////////////////////////////////////////////// // Funkcja obslugi klawiatury void ObslugaKlawiatury(unsigned char klawisz, int x, int y) { double a, c; int b; if (klawisz == 27) exit(0); else if (klawisz == '+') //zbliżenie obserwatora względem osi z zz++; else if (klawisz == '-') //oddalenie obserwatora względem osi z zz--; else if (klawisz == 'x') //obrot obserwatora względem osi x xxx_obrot++; else if (klawisz == 'z') //obrot obserwatora względem osi x w drugą stronę xxx_obrot--; else if (klawisz == 's') //obrot obserwatora względem osi y yyy_obrot++; else if (klawisz == 'a') //obrot obserwatora względem osi y w drugą stronę yyy_obrot--; else if (klawisz == 'q') //obrot obserwatora względem osi z zzz_obrot++; else if (klawisz == 'w') //obrot obserwatora względem osi z w drugą stronę zzz_obrot--; else if (klawisz == 'c') { podzial++; while (1) { a = 90 / podzial; b = 90 / podzial; c = a - b; if (podzial >= 45) { podzial = 45; break; } if (c != 0) { podzial++; } else break; } } else if (klawisz == 'v') { podzial--; while (1) { a = 90 / podzial; b = 90 / podzial; c = a - b; if (podzial <= 2) { podzial = 2; break; } if (c != 0) { podzial--; } else break; } } } ////////////////////////////////////////////////////////////////////////////////////////// // Glowna funkcja programu int main(int argc, char** argv) { // Zainicjowanie biblioteki GLUT glutInit(&argc, argv); // Ustawienie trybu wyswietlania glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); // Ustawienie polozenia dolenego lewego rogu okna glutInitWindowPosition(100, 100); // Ustawienie rozmiarow okna glutInitWindowSize(szerokoscOkna, wysokoscOkna); // Utworzenie okna glutCreateWindow("Sfera"); // Odblokowanie bufora glebokosci glEnable(GL_DEPTH_TEST); // Ustawienie wartosci czyszczacej zawartosc bufora glebokosci glClearDepth(1000.0); // Ustawienie koloru czyszczenia bufora ramki glClearColor(0.0f, 0.5f, 0.5f, 0.9f); // Wlaczenie wyswietlania wielokatow w postaci obrysow (przydatne w celach diagnostycznych). glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); // Zarejestrowanie funkcji (callback) odpowiedzialnej za glutDisplayFunc(WyswietlObraz); // Zarejestrowanie funkcji (callback) wywolywanej za kazdym razem kiedy // zmieniane sa rozmiary okna glutReshapeFunc(UstawParametryWidoku); // Zarejestrowanie funkcji wykonywanej gdy okno nie obsluguje // zadnych zadan glutIdleFunc(WyswietlObraz); // Zarejestrowanie funkcji obslugi klawiatury glutKeyboardFunc(ObslugaKlawiatury); // Obsluga glownej petli programu (wywolywanie zarejestrowanych callbackow // w odpowiedzi na odbierane zdarzenia lub obsluga stanu bezczynnosci) glutMainLoop(); return 0; }