Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * GRAFIKA KOMPUTEROWA I KOMUNIKACJA CZLOWIEK-KOMPUTER
- * Cwiczenie 5 - oświetlanie scen 3D (5.1 - oświetlone, ruchome jajko)
- *
- * Sterowanie:
- * PPM + ruch - zoom
- *
- * Autor: Michał Kaczara 181132
- * Data: 12/01/12
- **/
- //Zalaczenie plikow naglowkowych
- #include <windows.h>
- #include <gl/gl.h>
- #include <gl/glut.h>
- #include <math.h>
- #include <time.h>
- //Definicja typu point3 - punkt w przestrzeni 3D
- typedef float point3[3];
- //Stala PI
- const float PI = 3.14159265;
- //Tablica na punkty
- point3 **pointsTab;
- //Tablica na wektory normalne
- point3 **pointsNorms;
- static GLfloat viewer[]= {0.0, 0.0, 10.0};
- // inicjalizacja położenia obserwatora
- static GLfloat fi = 0.0, // kąty obrotu, elewacja i azymut
- theta = 0.0;
- static GLfloat pix2angle_x = 0.0, // przelicznik pikseli na stopnie
- pix2angle_y = 0.0;
- static GLint status = 0; // stan klawiszy myszy
- // 0 - nie naciśnięto żadnego klawisza
- // 1 - naciśnięty został lewy klawisz, 2 - prawy
- static int x_pos_old = 0, // poprzednia pozycja kursora myszy
- y_pos_old = 0;
- static int delta_x = 0, // różnica pomiędzy pozycją bieżącą
- delta_y = 0; // i poprzednią kursora myszy
- //Parametry programu
- int N = 50; //Liczba punktow na jaka dzielimy kwadrat jednostkowy
- float verLength = 1.0; //Dlugosc boku kwadratu
- float viewerR = 10.0; //Promien sfery obserwatora
- //Tablica katow obrotu
- static GLfloat angle[] = {0.0, 0.0, 0.0};
- //Funkcja wyliczajaca wspolrzedna X punktu (u,v) w przestrzeni 3D
- float calc3Dx(float u, float v) {
- float x, a = v*PI;
- x = (-90*pow(u, 5) +225*pow(u, 4) -270*pow(u, 3) +180*pow(u, 2) -45*u) * cos(a);
- return x;
- }
- //Funkcja wyliczajaca wspolrzedna Y punktu (u,v) w przestrzeni 3D
- float calc3Dy(float u, float v) {
- float y;
- y = 160*pow(u, 4) -320*pow(u, 3) +160*pow(u, 2);
- return y - 5;
- }
- //Funkcja wyliczajaca wspolrzedna Z punktu (u,v) w przestrzeni 3D
- float calc3Dz(float u, float v) {
- float z, a = v*PI;
- z = (-90*pow(u, 5) +225*pow(u, 4) -270*pow(u, 3) +180*pow(u, 2) -45*u) * sin(a);
- return z;
- }
- //Obliczenie wspolrzednej X wektora normalnego do powierzchni w punkcie
- float calcNormX(float u, float v) {
- float x, a = v*PI;
- float yu = 640*pow(u, 3) - 960*pow(u, 2) + 320*u;
- float yv = 0;
- float zu = (-450*pow(u, 4) + 900*pow(u, 3) - 810*pow(u, 2) + 360*u - 45)*sin(a);
- float zv = -PI*(90*pow(u, 5) - 225*pow(u, 4) + 270*pow(u, 3) - 180*pow(u, 2) + 45*u)*cos(a);
- x = (GLfloat)(yu*zv - zu*yv);
- return x;
- }
- //Obliczenie wspolrzednej Y wektora normalnego do powierzchni w punkcie
- float calcNormY(float u, float v) {
- float y, a = v*PI;
- float xu = (-450*pow(u, 4) + 900*pow(u, 3) - 810*pow(u, 2) + 360*u - 45)*cos(a);
- float xv = PI*(90*pow(u, 5) - 225*pow(u, 4) + 270*pow(u, 3) - 180*pow(u, 2) + 45*u)*sin(a);
- float zu = (-450*pow(u, 4) + 900*pow(u, 3) - 810*pow(u, 2) + 360*u - 45)*sin(a);
- float zv = -PI*(90*pow(u, 5) - 225*pow(u, 4) + 270*pow(u, 3) - 180*pow(u, 2) + 45*u)*cos(a);
- y = (GLfloat)(zu*xv - xu*zv);
- return y;
- }
- //Obliczenie wspolrzednej Z wektora normalnego do powierzchni w punkcie
- float calcNormZ(float u, float v) {
- float z, a = v*PI;
- float xu = (-450*pow(u, 4) + 900*pow(u, 3) - 810*pow(u, 2) + 360*u - 45)*cos(a);
- float xv = PI*(90*pow(u, 5) - 225*pow(u, 4) + 270*pow(u, 3) - 180*pow(u, 2) + 45*u)*sin(a);
- float yu = 640*pow(u, 3) - 960*pow(u, 2) + 320*u;
- float yv = 0;
- z = (GLfloat)(xu*yv - yu*xv);
- return z;
- }
- //Funkcja generujaca siatke puntow, najpierw w 2D, potem w 3D
- void genPointsMesh(){
- float stepXY = verLength/N;
- //Przypisanie punktom wspolrzednych
- for (int i=0; i<N+1; i++) {
- for (int j=0; j<N+1; j++) {
- pointsTab[i][j][0]= j*stepXY;
- pointsTab[i][j][1]= i*stepXY;
- }
- }
- //Przeksztalcenie wspolrzednych z dziedziny parametrycznej
- //w przestrzen 3D
- float u,v;
- for (int i=0; i<N+1; i++) {
- for (int j=0; j<N+1; j++) {
- v = pointsTab[i][j][0];
- u = pointsTab[i][j][1];
- pointsTab[i][j][0] = calc3Dx(u, v);
- pointsTab[i][j][1] = calc3Dy(u, v);
- pointsTab[i][j][2] = calc3Dz(u, v);
- //Wyliczenie wspolrzednych wektorow normalnych do powierzchni jajka
- float x = calcNormX(u, v);
- float y = calcNormY(u, v);
- float z = calcNormZ(u, v);
- //Normalizacja wektorow normalnych do powierzchni jajka
- //Wektory na bokach jajka
- if(i < N/2){
- pointsNorms[i][j][0] = x / (float)sqrt(pow(x, 2) + pow(y, 2) + pow(z, 2));
- pointsNorms[i][j][1] = y / (float)sqrt(pow(x, 2) + pow(y, 2) + pow(z, 2));
- pointsNorms[i][j][2] = z / (float)sqrt(pow(x, 2) + pow(y, 2) + pow(z, 2));
- }
- if(i > N/2){
- pointsNorms[i][j][0] = -1.0*x / (float)sqrt(pow(x, 2) + pow(y, 2) + pow(z, 2));
- pointsNorms[i][j][1] = -1.0*y / (float)sqrt(pow(x, 2) + pow(y, 2) + pow(z, 2));
- pointsNorms[i][j][2] = -1.0*z / (float)sqrt(pow(x, 2) + pow(y, 2) + pow(z, 2));
- }
- //Wektory na "szczycie" jajka
- if(i == N/2){
- pointsNorms[i][j][0]=0;
- pointsNorms[i][j][1]=1;
- pointsNorms[i][j][2]=0;
- }
- //Wektory na "dnie" jajka
- if (i==0 || i==N)
- {
- pointsNorms[i][j][0]=0;
- pointsNorms[i][j][1]=-1;
- pointsNorms[i][j][2]=0;
- }
- }
- }
- }
- //Funkcja renderujaca okreslony model jajka
- void Egg(void){
- //Wygenerowanie siatki 3D punktow
- genPointsMesh();
- //Parametry rysowania
- glColor3f(1.0, 1.0, 1.0);
- //Rysowanie jajka - trojkaty
- for(int i=0; i < N; i++){
- for(int j=0; j < N; j++){
- //W jedna strone
- glBegin(GL_TRIANGLES);
- glNormal3fv(pointsNorms[i][j+1]);
- glVertex3fv(pointsTab[i][j+1]);
- glNormal3fv(pointsNorms[i+1][j]);
- glVertex3fv(pointsTab[i+1][j]);
- glNormal3fv(pointsNorms[i+1][j+1]);
- glVertex3fv(pointsTab[i+1][j+1]);
- glEnd();
- //W druga strone
- glBegin(GL_TRIANGLES);
- glNormal3fv(pointsNorms[i][j]);
- glVertex3fv(pointsTab[i][j]);
- glNormal3fv(pointsNorms[i+1][j]);
- glVertex3fv(pointsTab[i+1][j]);
- glNormal3fv(pointsNorms[i][j+1]);
- glVertex3fv(pointsTab[i][j+1]);
- glEnd();
- }
- }
- }
- // Funkcja rysująca osie układu współrzędnych
- void Axes(void)
- {
- point3 x_min = {-2.0, 0.0, 0.0};
- point3 x_max = { 2.0, 0.0, 0.0};
- // początek i koniec obrazu osi x
- point3 y_min = {0.0, -2.0, 0.0};
- point3 y_max = {0.0, 2.0, 0.0};
- // początek i koniec obrazu osi y
- point3 z_min = {0.0, 0.0, -2.0};
- point3 z_max = {0.0, 0.0, 2.0};
- // początek i koniec obrazu osi y
- glColor3f(1.0f, 0.0f, 0.0f); // kolor rysowania osi - czerwony
- glBegin(GL_LINES); // rysowanie osi x
- glVertex3fv(x_min);
- glVertex3fv(x_max);
- glEnd();
- glColor3f(0.0f, 1.0f, 0.0f); // kolor rysowania - zielony
- glBegin(GL_LINES); // rysowanie osi y
- glVertex3fv(y_min);
- glVertex3fv(y_max);
- glEnd();
- glColor3f(0.0f, 0.0f, 1.0f); // kolor rysowania - niebieski
- glBegin(GL_LINES); // rysowanie osi z
- glVertex3fv(z_min);
- glVertex3fv(z_max);
- glEnd();
- }
- // Funkcja określająca co ma być rysowane (zawsze wywoływana gdy trzeba
- // przerysować scenę)
- void RenderScene(void)
- {
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- // Czyszczenie okna aktualnym kolorem czyszczącym
- glLoadIdentity();
- // Czyszczenie macierzy bieżącej
- if(status == 2) { // jeśli prawy klawisz myszy wciśnięty
- viewerR +=0.1* delta_y; // modyfikacja polozenia obserwatora(zoom)
- if(viewerR <= 6.0) // ograniczenie zblizenia
- viewerR = 6.0;
- if(viewerR >= 25.0) // ograniczenie oddalenia
- viewerR = 25.0;
- }
- //Wspolrzedne obserwatora - wzorki z ZSK
- viewer[0] = viewerR * cos(theta) * cos(fi);
- viewer[1] = viewerR * sin(fi);
- viewer[2] = viewerR * sin(theta) * cos(fi);
- gluLookAt(viewer[0],viewer[1],viewer[2], 0.0, 0.0, 0.0, 0.0, cos(fi), 0.0);
- // Zdefiniowanie położenia obserwatora
- Axes();
- // Narysowanie osi przy pomocy funkcji zdefiniowanej powyżej
- //Rotacje
- glRotatef(angle[0], 1.0, 0.0, 0.0);
- glRotatef(angle[1], 0.0, 1.0, 0.0);
- glRotatef(angle[2], 0.0, 0.0, 1.0);
- //Renderowanie jajka
- Egg();
- glFlush();
- // Przekazanie poleceń rysujących do wykonania
- glutSwapBuffers();
- }
- //Funkcja callback dla obrotu
- void spinEgg()
- {
- angle[0] -= 0.5;
- if( angle[0] > 360.0 ) angle[0] -= 360.0;
- angle[1] -= 0.5;
- if( angle[1] > 360.0 ) angle[1] -= 360.0;
- angle[2] -= 0.5;
- if( angle[2] > 360.0 ) angle[2] -= 360.0;
- glutPostRedisplay(); //odświeżenie zawartości aktualnego okna
- }
- // Funkcja ustalająca stan renderowania
- void MyInit(void)
- {
- glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
- // Kolor czyszcący (wypełnienia okna) ustawiono na czarny
- // Definicja materiału z jakiego zrobiony jest przedmiot
- //-------------------------------------------------------
- GLfloat mat_ambient[] = {1.0, 1.0, 1.0, 1.0};
- // współczynniki ka =[kar,kag,kab] dla światła otoczenia
- GLfloat mat_diffuse[] = {1.0, 1.0, 1.0, 1.0};
- // współczynniki kd =[kdr,kdg,kdb] światła rozproszonego
- GLfloat mat_specular[] = {1.0, 1.0, 1.0, 1.0};
- // współczynniki ks =[ksr,ksg,ksb] dla światła odbitego
- GLfloat mat_shininess = {100.0};
- // współczynnik n opisujący połysk powierzchni
- // Definicja źródła światła
- //-------------------------------------------------------
- GLfloat light_position[] = {5.0, 5.0, 10.0, 1.0};
- // położenie źródła
- GLfloat light_ambient[] = {0.1, 0.1, 0.1, 1.0};
- // składowe intensywności świecenia źródła światła otoczenia
- // Ia = [Iar,Iag,Iab]
- GLfloat light_diffuse[] = {1.0, 1.0, 0.0, 1.0};
- // składowe intensywności świecenia źródła światła powodującego
- // odbicie dyfuzyjne Id = [Idr,Idg,Idb]
- GLfloat light_specular[]= {1.0, 1.0, 1.0, 1.0};
- // składowe intensywności świecenia źródła światła powodującego
- // odbicie kierunkowe Is = [Isr,Isg,Isb]
- GLfloat att_constant = {1.0};
- // składowa stała ds dla modelu zmian oświetlenia w funkcji
- // odległości od źródła
- GLfloat att_linear = {0.05};
- // składowa liniowa dl dla modelu zmian oświetlenia w funkcji
- // odległości od źródła
- GLfloat att_quadratic = {0.001};
- // składowa kwadratowa dq dla modelu zmian oświetlenia w funkcji
- // odległości od źródła
- // Ustawienie patrametrów materiału
- //-------------------------------------------------------
- glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
- glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
- glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
- glMaterialf(GL_FRONT, GL_SHININESS, mat_shininess);
- // Ustawienie parametrów źródła światła
- //-------------------------------------------------------
- glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
- glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
- glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
- glLightfv(GL_LIGHT0, GL_POSITION, light_position);
- glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, att_constant);
- glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, att_linear);
- glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, att_quadratic);
- // Ustawienie opcji systemu oświetlania sceny
- //-------------------------------------------------------
- glShadeModel(GL_SMOOTH); // właczenie łagodnego cieniowania
- glEnable(GL_LIGHTING); // właczenie systemu oświetlenia sceny
- glEnable(GL_LIGHT0); // włączenie źródła o numerze 0
- glEnable(GL_DEPTH_TEST); // włączenie mechanizmu z-bufora
- }
- // Funkcja ma za zadanie utrzymanie stałych proporcji rysowanych
- // w przypadku zmiany rozmiarów okna.
- // Parametry vertical i horizontal (wysokość i szerokość okna) są
- // przekazywane do funkcji za każdym razem gdy zmieni się rozmiar okna.
- void ChangeSize(GLsizei horizontal, GLsizei vertical) {
- pix2angle_x = 360.0*0.1/(float)horizontal; // przeliczenie pikseli na stopnie
- pix2angle_y = 360.0*0.1/(float)vertical;
- glMatrixMode(GL_PROJECTION);
- // Przełączenie macierzy bieżącej na macierz projekcji
- glLoadIdentity();
- // Czyszcznie macierzy bieżącej
- gluPerspective(70.0, 1.0, 1.0, 30.0);
- // Ustawienie parametrów dla rzutu perspektywicznego
- if(horizontal <= vertical)
- glViewport(0, (vertical-horizontal)/2, horizontal, horizontal);
- else
- glViewport((horizontal-vertical)/2, 0, vertical, vertical);
- // Ustawienie wielkości okna okna widoku (viewport) w zależności
- // relacji pomiędzy wysokością i szerokością okna
- glMatrixMode(GL_MODELVIEW);
- // Przełączenie macierzy bieżącej na macierz widoku modelu
- glLoadIdentity();
- // Czyszczenie macierzy bieżącej
- }
- // Funkcja "bada" stan myszy i ustawia wartosci odpowiednich zmiennych globalnych
- void Mouse(int btn, int state, int x, int y) {
- if(btn == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) {
- y_pos_old = y; // przypisanie aktualnie odczytanej pozycji kursora
- // jako pozycji poprzedniej
- status = 2; //wciśnięty został prawy klawisz myszy
- }
- else
- status = 0; // nie został wciśnięty żaden klawisz
- }
- // Funkcja "monitoruje" polozenie kursora myszy i ustawia wartosci odpowiednich
- // zmiennych globalnych
- void Motion(GLsizei x, GLsizei y) {
- delta_x = x - x_pos_old; // obliczenie różnicy położenia kursora myszy
- x_pos_old = x; // podstawienie bieżacego położenia jako poprzednie
- delta_y = y - y_pos_old; // obliczenie różnicy położenia kursora myszy
- y_pos_old = y; // podstawienie bieżacego położenia jako poprzednie
- glutPostRedisplay(); // przerysowanie obrazu sceny
- }
- // Główny punkt wejścia programu. Program działa w trybie konsoli
- void main(void)
- {
- //Ziarno losowosci
- srand((unsigned) time(NULL));
- //Dynamiczna alokacja tablicy punktow
- pointsTab = new point3*[N+1];
- for (int i=0; i<N+1;i++){
- pointsTab[i] = new point3[N+1];
- }
- //Dynamiczna alokacja tablicy i wygenerowanie kolorow losowych dla punktow
- pointsNorms = new point3*[N+1];
- for(int i=0; i < N+1; i++){
- pointsNorms[i] = new point3[N+1];
- }
- glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
- glutInitWindowSize(800, 600);
- glutCreateWindow("Oswietlone, ruchome jajko");
- glutDisplayFunc(RenderScene);
- // Określenie, że funkcja RenderScene będzie funkcją zwrotną
- // (callback function). Bedzie ona wywoływana za każdym razem
- // gdy zajdzie potrzba przeryswania okna
- // Dla aktualnego okna ustala funkcję zwrotną odpowiedzialną
- // zazmiany rozmiaru okna
- glutReshapeFunc(ChangeSize);
- MyInit();
- // Funkcja MyInit() (zdefiniowana powyżej) wykonuje wszelkie
- // inicjalizacje konieczne przed przystąpieniem do renderowania
- // Włączenie mechanizmu usuwania powierzchni niewidocznych
- glutMouseFunc(Mouse);
- // Ustala funkcję zwrotną odpowiedzialną za badanie stanu myszy
- glutMotionFunc(Motion);
- // Ustala funkcję zwrotną odpowiedzialną za badanie ruchu myszy
- //Rejestracja funkcji zwrotnej (obrot)
- glutIdleFunc(spinEgg);
- glutMainLoop();
- // Funkcja uruchamia szkielet biblioteki GLUT
- //Zwolnienie pamięci
- for(int i=0; i < N+1; i++){
- delete[] pointsTab[i];
- delete[] pointsNorms[i];
- pointsTab[i] = 0;
- pointsNorms[i] = 0;
- }
- delete[] pointsTab;
- delete[] pointsNorms;
- pointsTab = 0;
- pointsNorms = 0;
- }
- ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
- /**
- * GRAFIKA KOMPUTEROWA I KOMUNIKACJA CZLOWIEK-KOMPUTER
- * Cwiczenie 5 - oświetlanie scen 3D (5.2 - oświetlone jajko, dwa źródła światła)
- *
- * Sterowanie:
- * LPM + ruch - swiatlo zolte
- * PPM + ruch - swiatlo niebieskie
- *
- * Autor: Michał Kaczara 181132
- * Data: 12/01/12
- **/
- //Zalaczenie plikow naglowkowych
- #include <windows.h>
- #include <gl/gl.h>
- #include <gl/glut.h>
- #include <math.h>
- #include <time.h>
- //Definicja typu point3 - punkt w przestrzeni 3D
- typedef float point3[3];
- //Stala PI
- const float PI = 3.14159265;
- //Tablica na punkty
- point3 **pointsTab;
- //Tablica na wektory normalne
- point3 **pointsNorms;
- static GLfloat fi[2] = {5.76, 1.05},// kąty obrotu, elewacja i azymut
- theta[2] = {4.68, 4.68};
- static GLfloat pix2angle_x = 0.0, // przelicznik pikseli na stopnie
- pix2angle_y = 0.0;
- static GLint status = 0; // stan klawiszy myszy
- // 0 - nie naciśnięto żadnego klawisza
- // 1 - naciśnięty został lewy klawisz, 2 - prawy
- static int x_pos_old = 0, // poprzednia pozycja kursora myszy
- y_pos_old = 0;
- static int delta_x = 0, // różnica pomiędzy pozycją bieżącą
- delta_y = 0; // i poprzednią kursora myszy
- //Parametry programu
- int N = 50; //Liczba punktow na jaka dzielimy kwadrat jednostkowy
- float verLength = 1.0; //Dlugosc boku kwadratu
- float lightsR = 10.0; //Promien sfery swiatel
- //Funkcja wyliczajaca wspolrzedna X punktu (u,v) w przestrzeni 3D
- float calc3Dx(float u, float v) {
- float x, a = v*PI;
- x = (-90*pow(u, 5) +225*pow(u, 4) -270*pow(u, 3) +180*pow(u, 2) -45*u) * cos(a);
- return x;
- }
- //Funkcja wyliczajaca wspolrzedna Y punktu (u,v) w przestrzeni 3D
- float calc3Dy(float u, float v) {
- float y;
- y = 160*pow(u, 4) -320*pow(u, 3) +160*pow(u, 2);
- return y - 5;
- }
- //Funkcja wyliczajaca wspolrzedna Z punktu (u,v) w przestrzeni 3D
- float calc3Dz(float u, float v) {
- float z, a = v*PI;
- z = (-90*pow(u, 5) +225*pow(u, 4) -270*pow(u, 3) +180*pow(u, 2) -45*u) * sin(a);
- return z;
- }
- //Obliczenie wspolrzednej X wektora normalnego do powierzchni w punkcie
- float calcNormX(float u, float v) {
- float x, a = v*PI;
- float yu = 640*pow(u, 3) - 960*pow(u, 2) + 320*u;
- float yv = 0;
- float zu = (-450*pow(u, 4) + 900*pow(u, 3) - 810*pow(u, 2) + 360*u - 45)*sin(a);
- float zv = -PI*(90*pow(u, 5) - 225*pow(u, 4) + 270*pow(u, 3) - 180*pow(u, 2) + 45*u)*cos(a);
- x = (GLfloat)(yu*zv - zu*yv);
- return x;
- }
- //Obliczenie wspolrzednej Y wektora normalnego do powierzchni w punkcie
- float calcNormY(float u, float v) {
- float y, a = v*PI;
- float xu = (-450*pow(u, 4) + 900*pow(u, 3) - 810*pow(u, 2) + 360*u - 45)*cos(a);
- float xv = PI*(90*pow(u, 5) - 225*pow(u, 4) + 270*pow(u, 3) - 180*pow(u, 2) + 45*u)*sin(a);
- float zu = (-450*pow(u, 4) + 900*pow(u, 3) - 810*pow(u, 2) + 360*u - 45)*sin(a);
- float zv = -PI*(90*pow(u, 5) - 225*pow(u, 4) + 270*pow(u, 3) - 180*pow(u, 2) + 45*u)*cos(a);
- y = (GLfloat)(zu*xv - xu*zv);
- return y;
- }
- //Obliczenie wspolrzednej Z wektora normalnego do powierzchni w punkcie
- float calcNormZ(float u, float v) {
- float z, a = v*PI;
- float xu = (-450*pow(u, 4) + 900*pow(u, 3) - 810*pow(u, 2) + 360*u - 45)*cos(a);
- float xv = PI*(90*pow(u, 5) - 225*pow(u, 4) + 270*pow(u, 3) - 180*pow(u, 2) + 45*u)*sin(a);
- float yu = 640*pow(u, 3) - 960*pow(u, 2) + 320*u;
- float yv = 0;
- z = (GLfloat)(xu*yv - yu*xv);
- return z;
- }
- //Funkcja generujaca siatke puntow, najpierw w 2D, potem w 3D
- void genPointsMesh(){
- float stepXY = verLength/N;
- //Przypisanie punktom wspolrzednych
- for (int i=0; i<N+1; i++) {
- for (int j=0; j<N+1; j++) {
- pointsTab[i][j][0]= j*stepXY;
- pointsTab[i][j][1]= i*stepXY;
- }
- }
- //Przeksztalcenie wspolrzednych z dziedziny parametrycznej
- //w przestrzen 3D
- float u,v;
- for (int i=0; i<N+1; i++) {
- for (int j=0; j<N+1; j++) {
- v = pointsTab[i][j][0];
- u = pointsTab[i][j][1];
- pointsTab[i][j][0] = calc3Dx(u, v);
- pointsTab[i][j][1] = calc3Dy(u, v);
- pointsTab[i][j][2] = calc3Dz(u, v);
- //Wyliczenie wspolrzednych wektorow normalnych do powierzchni jajka
- float x = calcNormX(u, v);
- float y = calcNormY(u, v);
- float z = calcNormZ(u, v);
- //Normalizacja wektorow normalnych do powierzchni jajka
- //Wektory na bokach jajka
- if(i < N/2){
- pointsNorms[i][j][0] = x / (float)sqrt(pow(x, 2) + pow(y, 2) + pow(z, 2));
- pointsNorms[i][j][1] = y / (float)sqrt(pow(x, 2) + pow(y, 2) + pow(z, 2));
- pointsNorms[i][j][2] = z / (float)sqrt(pow(x, 2) + pow(y, 2) + pow(z, 2));
- }
- if(i > N/2){
- pointsNorms[i][j][0] = -1.0*x / (float)sqrt(pow(x, 2) + pow(y, 2) + pow(z, 2));
- pointsNorms[i][j][1] = -1.0*y / (float)sqrt(pow(x, 2) + pow(y, 2) + pow(z, 2));
- pointsNorms[i][j][2] = -1.0*z / (float)sqrt(pow(x, 2) + pow(y, 2) + pow(z, 2));
- }
- //Wektory na "szczycie" jajka
- if(i == N/2){
- pointsNorms[i][j][0]=0;
- pointsNorms[i][j][1]=1;
- pointsNorms[i][j][2]=0;
- }
- //Wektory na "dnie" jajka
- if (i==0 || i==N)
- {
- pointsNorms[i][j][0]=0;
- pointsNorms[i][j][1]=-1;
- pointsNorms[i][j][2]=0;
- }
- }
- }
- }
- //Funkcja renderujaca okreslony model jajka
- void Egg(void){
- //Wygenerowanie siatki 3D punktow
- genPointsMesh();
- //Parametry rysowania
- glColor3f(1.0, 1.0, 1.0);
- //Rysowanie jajka - trojkaty
- for(int i=0; i < N; i++){
- for(int j=0; j < N; j++){
- //W jedna strone
- glBegin(GL_TRIANGLES);
- glNormal3fv(pointsNorms[i][j+1]);
- glVertex3fv(pointsTab[i][j+1]);
- glNormal3fv(pointsNorms[i+1][j]);
- glVertex3fv(pointsTab[i+1][j]);
- glNormal3fv(pointsNorms[i+1][j+1]);
- glVertex3fv(pointsTab[i+1][j+1]);
- glEnd();
- //W druga strone
- glBegin(GL_TRIANGLES);
- glNormal3fv(pointsNorms[i][j]);
- glVertex3fv(pointsTab[i][j]);
- glNormal3fv(pointsNorms[i+1][j]);
- glVertex3fv(pointsTab[i+1][j]);
- glNormal3fv(pointsNorms[i][j+1]);
- glVertex3fv(pointsTab[i][j+1]);
- glEnd();
- }
- }
- }
- // Funkcja rysująca osie układu współrzędnych
- void Axes(void)
- {
- point3 x_min = {-2.0, 0.0, 0.0};
- point3 x_max = { 2.0, 0.0, 0.0};
- // początek i koniec obrazu osi x
- point3 y_min = {0.0, -2.0, 0.0};
- point3 y_max = {0.0, 2.0, 0.0};
- // początek i koniec obrazu osi y
- point3 z_min = {0.0, 0.0, -2.0};
- point3 z_max = {0.0, 0.0, 2.0};
- // początek i koniec obrazu osi y
- glColor3f(1.0f, 0.0f, 0.0f); // kolor rysowania osi - czerwony
- glBegin(GL_LINES); // rysowanie osi x
- glVertex3fv(x_min);
- glVertex3fv(x_max);
- glEnd();
- glColor3f(0.0f, 1.0f, 0.0f); // kolor rysowania - zielony
- glBegin(GL_LINES); // rysowanie osi y
- glVertex3fv(y_min);
- glVertex3fv(y_max);
- glEnd();
- glColor3f(0.0f, 0.0f, 1.0f); // kolor rysowania - niebieski
- glBegin(GL_LINES); // rysowanie osi z
- glVertex3fv(z_min);
- glVertex3fv(z_max);
- glEnd();
- }
- // Funkcja określająca co ma być rysowane (zawsze wywoływana gdy trzeba
- // przerysować scenę)
- void RenderScene(void)
- {
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- // Czyszczenie okna aktualnym kolorem czyszczącym
- glLoadIdentity();
- // Czyszczenie macierzy bieżącej
- if(status == 1){ // jeśli lewy klawisz myszy wciśnięty
- theta[0] -= delta_x*pix2angle_x;
- //Ograniczenie dla azymutu
- if(theta[0] <= 0)
- theta[0] += 2*PI;
- if(theta[0] >= 2*PI)
- theta[0] -= 2*PI;
- fi[0] -= delta_y*pix2angle_y;
- //Ograniczenie dla elewacji
- if(fi[0] <= 0)
- fi[0] += 2*PI;
- if(fi[0] >= 2*PI)
- fi[0] -= 2*PI;
- }
- else if(status == 2){ // jeśli prawy klawisz myszy wciśnięty
- theta[1] -= delta_x*pix2angle_x;
- //Ograniczenie dla azymutu
- if(theta[1] <= 0)
- theta[1] += 2*PI;
- if(theta[1] >= 2*PI)
- theta[1] -= 2*PI;
- fi[1] -= delta_y*pix2angle_y;
- //Ograniczenie dla elewacji
- if(fi[1] <= 0)
- fi[1] += 2*PI;
- if(fi[1] >= 2*PI)
- fi[1] -= 2*PI;
- }
- gluLookAt(0.0, 0.0, -10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
- // Zdefiniowanie położenia obserwatora
- GLfloat lights_positions[4] = {0};
- lights_positions[0] = lightsR * cos(theta[0]) * cos(fi[0]);
- lights_positions[1] = lightsR * sin(fi[0]);
- lights_positions[2] = lightsR * sin(theta[0]) * cos(fi[0]);
- lights_positions[3] = 1.0;
- glLightfv(GL_LIGHT0, GL_POSITION, lights_positions);
- //Aktualizacja pozycji swiatla 0
- lights_positions[0] = lightsR * cos(theta[1]) * cos(fi[1]);
- lights_positions[1] = lightsR * sin(fi[1]);
- lights_positions[2] = lightsR * sin(theta[1]) * cos(fi[1]);
- lights_positions[3] = 1.0;
- glLightfv(GL_LIGHT1, GL_POSITION, lights_positions);
- //Aktualizacja pozycji swiatla 1
- Axes();
- // Narysowanie osi przy pomocy funkcji zdefiniowanej powyżej
- //Renderowanie jajka
- Egg();
- glFlush();
- // Przekazanie poleceń rysujących do wykonania
- glutSwapBuffers();
- }
- // Funkcja ustalająca stan renderowania
- void MyInit(void)
- {
- glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
- // Kolor czyszcący (wypełnienia okna) ustawiono na czarny
- // Definicja materiału z jakiego zrobiony jest przedmiot
- //-------------------------------------------------------
- GLfloat mat_ambient[] = {0.3, 0.3, 0.3, 1.0};
- // współczynniki ka =[kar,kag,kab] dla światła otoczenia
- GLfloat mat_diffuse[] = {1.0, 1.0, 1.0, 1.0};
- // współczynniki kd =[kdr,kdg,kdb] światła rozproszonego
- GLfloat mat_specular[] = {1.0, 1.0, 1.0, 1.0};
- // współczynniki ks =[ksr,ksg,ksb] dla światła odbitego
- GLfloat mat_shininess = {100.0};
- // współczynnik n opisujący połysk powierzchni
- // Definicja źródła światła
- //-------------------------------------------------------
- GLfloat light_position[2][4] = {{-10.0, -10.0, -10.0, 1.0}, {-10.0, -10.0, -10.0, 1.0}};
- // położenie źródła
- GLfloat light_ambient[] = {0.2, 0.2, 0.2, 1.0};
- // składowe intensywności świecenia źródła światła otoczenia
- // Ia = [Iar,Iag,Iab]
- GLfloat light_diffuse[2][4] = {{1.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 1.0}};
- // składowe intensywności świecenia źródła światła powodującego
- // odbicie dyfuzyjne Id = [Idr,Idg,Idb]
- GLfloat light_specular[2][4] = {{1.0, 1.0, 0.0, 1.0}, {0.7, 0.7, 1.0, 1.0}};
- // składowe intensywności świecenia źródła światła powodującego
- // odbicie kierunkowe Is = [Isr,Isg,Isb]
- GLfloat att_constant = {1.0};
- // składowa stała ds dla modelu zmian oświetlenia w funkcji
- // odległości od źródła
- GLfloat att_linear = {0.001};
- // składowa liniowa dl dla modelu zmian oświetlenia w funkcji
- // odległości od źródła
- GLfloat att_quadratic = {0.001};
- // składowa kwadratowa dq dla modelu zmian oświetlenia w funkcji
- // odległości od źródła
- // Ustawienie patrametrów materiału
- //-------------------------------------------------------
- glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
- glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
- glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
- glMaterialf(GL_FRONT, GL_SHININESS, mat_shininess);
- // Ustawienie parametrów źródła światła
- //-------------------------------------------------------
- glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
- glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse[0]);
- glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular[0]);
- glLightfv(GL_LIGHT0, GL_POSITION, light_position[0]);
- glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, att_constant);
- glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, att_linear);
- glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, att_quadratic);
- glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient);
- glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse[1]);
- glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular[1]);
- glLightfv(GL_LIGHT1, GL_POSITION, light_position[1]);
- glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, att_constant);
- glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, att_linear);
- glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, att_quadratic);
- // Ustawienie opcji systemu oświetlania sceny
- //-------------------------------------------------------
- glShadeModel(GL_SMOOTH); // właczenie łagodnego cieniowania
- glEnable(GL_LIGHTING); // właczenie systemu oświetlenia sceny
- glEnable(GL_LIGHT0); // włączenie źródła o numerze 0
- glEnable(GL_LIGHT1); // włączenie źródła o numerze 1
- glEnable(GL_DEPTH_TEST); // włączenie mechanizmu z-bufora
- }
- // Funkcja ma za zadanie utrzymanie stałych proporcji rysowanych
- // w przypadku zmiany rozmiarów okna.
- // Parametry vertical i horizontal (wysokość i szerokość okna) są
- // przekazywane do funkcji za każdym razem gdy zmieni się rozmiar okna.
- void ChangeSize(GLsizei horizontal, GLsizei vertical) {
- pix2angle_x = 360.0*0.0125/(float)horizontal; // przeliczenie pikseli na stopnie
- pix2angle_y = 360.0*0.0125/(float)vertical;
- glMatrixMode(GL_PROJECTION);
- // Przełączenie macierzy bieżącej na macierz projekcji
- glLoadIdentity();
- // Czyszcznie macierzy bieżącej
- gluPerspective(70.0, 1.0, 1.0, 30.0);
- // Ustawienie parametrów dla rzutu perspektywicznego
- if(horizontal <= vertical)
- glViewport(0, (vertical-horizontal)/2, horizontal, horizontal);
- else
- glViewport((horizontal-vertical)/2, 0, vertical, vertical);
- // Ustawienie wielkości okna okna widoku (viewport) w zależności
- // relacji pomiędzy wysokością i szerokością okna
- glMatrixMode(GL_MODELVIEW);
- // Przełączenie macierzy bieżącej na macierz widoku modelu
- glLoadIdentity();
- // Czyszczenie macierzy bieżącej
- }
- // Funkcja "bada" stan myszy i ustawia wartosci odpowiednich zmiennych globalnych
- void Mouse(int btn, int state, int x, int y) {
- if(btn == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
- x_pos_old = x; // przypisanie aktualnie odczytanej pozycji kursora
- y_pos_old = y; // jako pozycji poprzedniej
- status = 1; // wciśnięty został lewy klawisz myszy
- }
- else if(btn == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) {
- x_pos_old = x; // przypisanie aktualnie odczytanej pozycji kursora
- y_pos_old = y; // jako pozycji poprzedniej
- status = 2; //wciśnięty został prawy klawisz myszy
- }
- else
- status = 0; // nie został wciśnięty żaden klawisz
- }
- // Funkcja "monitoruje" polozenie kursora myszy i ustawia wartosci odpowiednich
- // zmiennych globalnych
- void Motion(GLsizei x, GLsizei y) {
- delta_x = x - x_pos_old; // obliczenie różnicy położenia kursora myszy
- x_pos_old = x; // podstawienie bieżacego położenia jako poprzednie
- delta_y = y - y_pos_old; // obliczenie różnicy położenia kursora myszy
- y_pos_old = y; // podstawienie bieżacego położenia jako poprzednie
- glutPostRedisplay(); // przerysowanie obrazu sceny
- }
- // Główny punkt wejścia programu. Program działa w trybie konsoli
- void main(void)
- {
- //Ziarno losowosci
- srand((unsigned) time(NULL));
- //Dynamiczna alokacja tablicy punktow
- pointsTab = new point3*[N+1];
- for (int i=0; i<N+1;i++){
- pointsTab[i] = new point3[N+1];
- }
- //Dynamiczna alokacja tablicy wspolrzednych wektorow normalnych
- pointsNorms = new point3*[N+1];
- for(int i=0; i < N+1; i++){
- pointsNorms[i] = new point3[N+1];
- }
- glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
- glutInitWindowSize(800, 600);
- glutCreateWindow("Oswietlone jajko, dwa zrodla swiatla");
- glutDisplayFunc(RenderScene);
- // Określenie, że funkcja RenderScene będzie funkcją zwrotną
- // (callback function). Bedzie ona wywoływana za każdym razem
- // gdy zajdzie potrzba przeryswania okna
- // Dla aktualnego okna ustala funkcję zwrotną odpowiedzialną
- // zazmiany rozmiaru okna
- glutReshapeFunc(ChangeSize);
- MyInit();
- // Funkcja MyInit() (zdefiniowana powyżej) wykonuje wszelkie
- // inicjalizacje konieczne przed przystąpieniem do renderowania
- // Włączenie mechanizmu usuwania powierzchni niewidocznych
- glutMouseFunc(Mouse);
- // Ustala funkcję zwrotną odpowiedzialną za badanie stanu myszy
- glutMotionFunc(Motion);
- // Ustala funkcję zwrotną odpowiedzialną za badanie ruchu myszy
- glEnable(GL_DEPTH_TEST);
- glutMainLoop();
- // Funkcja uruchamia szkielet biblioteki GLUT
- //Zwolnienie pamięci
- for(int i=0; i < N+1; i++){
- delete[] pointsTab[i];
- delete[] pointsNorms[i];
- pointsTab[i] = 0;
- pointsNorms[i] = 0;
- }
- delete[] pointsTab;
- delete[] pointsNorms;
- pointsTab = 0;
- pointsNorms = 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement