Advertisement
Guest User

lab3 zad2

a guest
Nov 22nd, 2017
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.08 KB | None | 0 0
  1. #include <windows.h>
  2. #include <gl/gl.h>
  3. #include <gl/glut.h>
  4. #include <math.h>
  5. #include <iostream>
  6.  
  7. #define PI 3.14159265
  8.  
  9. static int model = 1;   // wybór modelu wyświetlanego jajka
  10. static GLfloat azymut = 0.0;    // kąt azymutu (kierunek patrzenia na obiekt)
  11. static GLfloat elewacja = 0.0;  // kąt elewacji (wysokość położenia obserwatora)
  12. static GLfloat R = 10.0;
  13. // wartość promienia R sfery o środku w środku układu współrzędnych,
  14. // po której porusza się obserwator
  15.  
  16. static GLfloat pix2angle;     // przelicznik pikseli na stopnie
  17. static GLint status = 0;
  18. // stan klawiszy myszy:
  19. // 0 - nie naciśnięto żadnego klawisza
  20. // 1 - naciśnięty został lewy klawisz
  21. // 2 - naciśnięty został prawy klawisz
  22.  
  23. static int x_pos_old = 0;   // poprzednia pozycja kursora myszy
  24. static int delta_x = 0;
  25. // różnica pomiędzy pozycją bieżącą i poprzednią kursora myszy
  26. static int y_pos_old = 0;
  27. static int delta_y = 0;
  28. // jw. ale dla parametru y
  29. static int R_pos_old = 0;
  30. static int delta_R = 0;
  31. // jw. ale dla parametru zoom
  32.  
  33. typedef float point3[3];
  34. // typ danych przechowujący 3 współrzędne float (do tworzenia osi)
  35. static GLfloat viewer[] = { 0.0, 0.0, 10.0 };
  36. // współrzędne obserwatora (kamery) w układzie współrzędnych
  37.  
  38. // funkcja odpowiedzialna za tworzenie trójwymiarowego jajka z wcześniejszych zajęć
  39. void Egg() {
  40.     int N = 50;
  41.     // ilość stref, na które dzielimy bok kwadratu jednostkowego dziedziny parametrycznej
  42.     float u, v;
  43.     // wspolrzędne u, v dla dziedziny parametrycznej (kwadrat jednostkowy)
  44.     point3 **tab = new point3*[N];
  45.     // tablica do zapisywania punktów w przestrzeni 3-D (x, y, z)
  46.     point3 **tabRGB = new point3*[N];
  47.     // tablica kolorów (R, G, B)
  48.  
  49.     for (int i = 0; i < N; i++) {   // dynamiczne tworzenie tablicy dwuwymiarowej
  50.         tab[i] = new point3[N];     // (trójwymiarowej uwzględniając typ danych point3 będący tablicą)
  51.         tabRGB[i] = new point3[N];
  52.     }
  53.  
  54.     // poniżej wypełnianie tablicy RGB losowymi kolorami dla modelu 3 - jajka stworzonego z kolorowych trójkątów
  55.     for (int i = 0; i < N; i++) {
  56.         for (int j = 0; j < N; j++) {
  57.             tabRGB[i][j][0] = ((rand() % 101)*0.01);
  58.             tabRGB[i][j][1] = ((rand() % 101)*0.01);
  59.             tabRGB[i][j][2] = ((rand() % 101)*0.01);
  60.         }
  61.     }
  62.  
  63.     // poniżej wypełnianie tablicy obliczonymi wartościami dla punktów x, y, z w przestrzeni 3-D z odpowiednich wzorów
  64.     for (int i = 0; i < N; i++) {
  65.         for (int j = 0; j < N; j++) {
  66.             u = (float)i / (N - 1);
  67.             v = (float)j / (N - 1);
  68.  
  69.             tab[i][j][0] = (-90 * pow(u, 5) + 225 * pow(u, 4) - 270 * pow(u, 3) + 180 * pow(u, 2) - 45 * u) * cos(PI*v);    // x
  70.             tab[i][j][1] = 160 * pow(u, 4) - 320 * pow(u, 3) + 160 * pow(u, 2) - 5.0;                               // y z lekka translacja
  71.             tab[i][j][2] = (-90 * pow(u, 5) + 225 * pow(u, 4) - 270 * pow(u, 3) + 180 * pow(u, 2) - 45 * u) * sin(PI*v);    // z
  72.         }
  73.     }
  74.  
  75.     // ponizej rysowanie odpowiedniego modelu jajka
  76.     glColor3f(1.0f, 1.0f, 1.0f);
  77.  
  78.     if (model == 1) {   // punkty
  79.         glBegin(GL_POINTS);
  80.         for (int i = 0; i<N; i++) {
  81.             for (int j = 0; j<N; j++) {
  82.                 glVertex3fv(tab[i][j]);
  83.             }
  84.         }
  85.         glEnd();
  86.     }
  87.     else if (model == 2) {  // siatka
  88.  
  89.         glBegin(GL_LINES);
  90.         for (int i = 0; i<N - 1; i++) {
  91.             for (int j = 0; j<N - 1; j++) {
  92.  
  93.                 glVertex3fv(tab[i][j]);
  94.                 glVertex3fv(tab[i + 1][j]);
  95.                 // rysowanie siatki "pionowej"
  96.  
  97.                 glVertex3fv(tab[i][j]);
  98.                 glVertex3fv(tab[i][j + 1]);
  99.                 // rysowanie siatki "poziomej"
  100.  
  101.                 glVertex3fv(tab[i + 1][j]);
  102.                 glVertex3fv(tab[i][j + 1]);
  103.                 // rysowanie siatki "pochyłej"
  104.             }
  105.         }
  106.         glEnd();
  107.  
  108.     }
  109.     else if (model == 3) {  // kolorowe trójkąty
  110.  
  111.         glBegin(GL_TRIANGLES);
  112.         for (int i = 0; i<N - 1; i++) {
  113.             for (int j = 0; j<N - 1; j++) {
  114.  
  115.                 glColor3fv(tabRGB[i][j]);       // Pierwszy trójkąt
  116.                 glVertex3fv(tab[i][j]);
  117.                
  118.                 glColor3fv(tabRGB[i + 1][j]);
  119.                 glVertex3fv(tab[i + 1][j]);
  120.  
  121.                 glColor3fv(tabRGB[i][j + 1]);
  122.                 glVertex3fv(tab[i][j + 1]);
  123.                
  124.                 /*************************************************************************************/
  125.                
  126.                 glColor3fv(tabRGB[i + 1][j + 1]);   // Drugi, 'uzupełniający' trójkąt
  127.                 glVertex3fv(tab[i + 1][j + 1]);
  128.  
  129.                 glColor3fv(tabRGB[i + 1][j]);
  130.                 glVertex3fv(tab[i + 1][j]);
  131.  
  132.                 glColor3fv(tabRGB[i][j + 1]);
  133.                 glVertex3fv(tab[i][j + 1]);
  134.  
  135.                 // Jeśli nie stworzymy trójkątów tak, by sklejały się w prostokąty (uzupełniały na całej powierzchni),
  136.                 // pozostawimy pustą przestrzeń na płaszczyźnie jajka.
  137.             }
  138.         }
  139.         glEnd();
  140.     }
  141.  
  142.     // zwolnienie zaalokowanej wcześniej pamięci
  143.     for (int i = 0; i < N; i++) {
  144.         delete[] tab[i];
  145.         delete[] tabRGB[i];
  146.     }
  147.     delete[]tab;
  148.     delete[]tabRGB;
  149. }
  150.  
  151. // Funkcja "bada" stan myszy i ustawia wartości odpowiednich zmiennych globalnych
  152. void Mouse(int btn, int state, int x, int y)
  153. {
  154.     if (btn == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
  155.     {
  156.         x_pos_old = x;      // przypisanie aktualnie odczytanej pozycji kursora
  157.         y_pos_old = y;      // jako pozycji poprzedniej
  158.         status = 1;         // wciśnięty został lewy klawisz myszy
  159.  
  160.     }
  161.     else if (btn == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) {
  162.         R_pos_old = y;      // jw. - wersja dla R
  163.                             // tylko ruch pionowy myszki
  164.         status = 2;         // wciśnięty został prawy przycisk myszy
  165.     }
  166.     else status = 0;        // nie został wciśnięty żaden klawisz
  167. }
  168.  
  169. // Funkcja "monitoruje" położenie kursora myszy i ustawia wartości odpowiednich
  170. // zmiennych globalnych
  171. void Motion(GLsizei x, GLsizei y)
  172. {
  173.     delta_x = x - x_pos_old;        // obliczenie różnicy położenia kursora myszy
  174.     delta_y = y - y_pos_old;        // dla współrzędnych x, y (zoom wyliczany jak y)
  175.     delta_R = y - R_pos_old;
  176.  
  177.     x_pos_old = x;          // podstawienie bieżącego położenia jako poprzednie
  178.     y_pos_old = y;          // dla wszystkich zmiennych dot. sterowania myszą
  179.     R_pos_old = y;
  180.  
  181.     glutPostRedisplay();     // przerysowanie obrazu sceny
  182. }
  183.  
  184. // Funkcja rysująca osie układu wspó?rz?dnych
  185. void Axes(void)
  186. {
  187.     point3  x_min = { -5.0, 0.0, 0.0 };
  188.     point3  x_max = { 5.0, 0.0, 0.0 };
  189.     // początek i koniec obrazu osi x
  190.  
  191.     point3  y_min = { 0.0, -5.0, 0.0 };
  192.     point3  y_max = { 0.0,  5.0, 0.0 };
  193.     // początek i koniec obrazu osi y
  194.  
  195.     point3  z_min = { 0.0, 0.0, -5.0 };
  196.     point3  z_max = { 0.0, 0.0,  5.0 };
  197.     //  początek i koniec obrazu osi z
  198.  
  199.     glColor3f(1.0f, 0.0f, 0.0f);  // kolor rysowania osi - czerwony
  200.     glBegin(GL_LINES); // rysowanie osi x
  201.     glVertex3fv(x_min);
  202.     glVertex3fv(x_max);
  203.     glEnd();
  204.  
  205.     glColor3f(0.0f, 1.0f, 0.0f);  // kolor rysowania - zielony
  206.     glBegin(GL_LINES);  // rysowanie osi y
  207.     glVertex3fv(y_min);
  208.     glVertex3fv(y_max);
  209.     glEnd();
  210.  
  211.     glColor3f(0.0f, 0.0f, 1.0f);  // kolor rysowania - niebieski
  212.     glBegin(GL_LINES); // rysowanie osi z
  213.     glVertex3fv(z_min);
  214.     glVertex3fv(z_max);
  215.     glEnd();
  216. }
  217.  
  218. // Funkcja określająca co ma być rysowane (zawsze wywoływana, gdy trzeba
  219. // przerysować scenę)
  220. void RenderScene(void)
  221. {
  222.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  223.     // Czyszczenie okna aktualnym kolorem czyszczącym
  224.     glLoadIdentity();
  225.     // Czyszczenie macierzy bieżącej
  226.     gluLookAt(viewer[0], viewer[1], viewer[2], 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
  227.     // Zdefiniowanie położenia obserwatora
  228.     Axes();
  229.     // Narysowanie osi przy pomocy funkcji zdefiniowanej powyżej
  230.  
  231.     if (status == 1)    // jeśli został wciśnięty lewy przycisk myszy
  232.     {
  233.         azymut += (delta_x*pix2angle)/50;   // modyfikacja kąta obrotu o kąt proporcjonalny
  234.         elewacja += (delta_y*pix2angle)/50; // do różnicy położeń kursora myszy
  235.         // odpowiednio przeskalowane dane dla wygodniejszego sterowania
  236.     }
  237.     else if (status == 2) {     // jeśli został wciśnięty prawy przycisk myszy
  238.         R += (delta_R*pix2angle)/50;
  239.         // odpowiednio przeskalowany promień dla wygodniejszego sterowania
  240.     }
  241.  
  242.     glColor3f(1.0f, 1.0f, 1.0f);
  243.     // Ustawienie koloru rysowania na biały
  244.  
  245.     viewer[0] = R*cos(azymut)*cos(elewacja);
  246.     viewer[1] = R*sin(elewacja);
  247.     viewer[2] = R*sin(azymut)*cos(elewacja);
  248.     // Zmiana położenia obserwatora w zależności od ruchu myszy
  249.  
  250.     Egg();  // rysowanie jajka
  251.     glFlush();
  252.     // Przekazanie poleceń rysujących do wykonania
  253.     glutSwapBuffers();
  254. }
  255.  
  256. // funkcja zmieniająca model w zależności od wciśniętego klawisza
  257. void keys(unsigned char key, int x, int y)
  258. {
  259.     if (key == 'p') model = 1;
  260.     if (key == 'w') model = 2;
  261.     if (key == 's') model = 3;
  262.     // zmiana modelu za pomocą klawiszy p, w, s
  263.  
  264.     RenderScene(); // przerysowanie obrazu sceny
  265. }
  266.  
  267. // Funkcja ustalająca stan renderowania
  268. void MyInit(void)
  269. {
  270.     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
  271.     // Kolor czyszczący (wypełnienia okna) ustawiono na czarny
  272. }
  273.  
  274. // Funkcja ma za zadanie utrzymanie stałych proporcji rysowanych
  275. // w przypadku zmiany rozmiarów okna.
  276. // Parametry vertical i horizontal (wysokość i szerokość okna) są
  277. // przekazywane do funkcji za każdym razem gdy zmieni się rozmiar okna.
  278. void ChangeSize(GLsizei horizontal, GLsizei vertical)
  279. {
  280.     pix2angle = 360.0 / (float)horizontal;  // przeliczenie pikseli na stopnie
  281.     glMatrixMode(GL_PROJECTION);
  282.     // Przełączenie macierzy bieżącej na macierz projekcji
  283.     glLoadIdentity();
  284.     // Czyszcznie macierzy bieżącej
  285.     gluPerspective(70, 1.0, 1.0, 30.0);
  286.     // Ustawienie parametrów dla rzutu perspektywicznego
  287.  
  288.     if (horizontal <= vertical)
  289.         glViewport(0, (vertical - horizontal) / 2, horizontal, horizontal);
  290.     else
  291.         glViewport((horizontal - vertical) / 2, 0, vertical, vertical);
  292.     // Ustawienie wielkości okna okna widoku (viewport) w zależności
  293.     // relacji pomiędzy wysokością i szerokością okna
  294.  
  295.     glMatrixMode(GL_MODELVIEW);
  296.     // Przełączenie macierzy bieżącej na macierz widoku modelu  
  297.     glLoadIdentity();
  298.     // Czyszczenie macierzy bieżącej
  299. }
  300.  
  301. // Główny punkt wejścia programu. Program działa w trybie konsoli
  302. void main(void)
  303. {
  304.     glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  305.     glutInitWindowSize(1000, 1000);
  306.     glutCreateWindow("Zad2 - jajko i zmiana położenia obserwatora");
  307.     glutKeyboardFunc(keys);
  308.     // Funkcja określająca, że funkcja keys będzie funkcją zwrotną
  309.     // wywoływaną do obsługi klawiatury
  310.  
  311.     if (model == 1 || model == 2 || model == 3) {
  312.         glutDisplayFunc(RenderScene);
  313.         // Określenie, że funkcja RenderScene będzie funkcją zwrotną
  314.         // (callback function).  Będzie ona wywoływana za każdym razem
  315.         // gdy zajdzie potrzeba przerysowania okna
  316.         glutReshapeFunc(ChangeSize);
  317.         // Dla aktualnego okna ustala funkcję zwrotną odpowiedzialną
  318.         // za zmiany rozmiaru okna  
  319.         glutMouseFunc(Mouse);
  320.         // Ustala funkcję zwrotną odpowiedzialną za badanie stanu myszy
  321.         glutMotionFunc(Motion);
  322.         // Ustala funkcję zwrotną odpowiedzialną za badanie ruchu myszy
  323.         MyInit();
  324.         // Funkcja MyInit() (zdefiniowana powyżej) wykonuje wszelkie
  325.         // inicjalizacje konieczne  przed przystąpieniem do renderowania
  326.         glEnable(GL_DEPTH_TEST);
  327.         // Włączenie mechanizmu usuwania niewidocznych elementów sceny
  328.         glutMainLoop();
  329.         // Funkcja uruchamia szkielet biblioteki GLUT
  330.     }
  331.     // w przypadku nieprawidłowej danej model na wejściu programu
  332.     // zostanie on zamknięty po 5 sekundach
  333.     else {
  334.         std::cout << "Podano nieprawidlowe dane dla parametru model! Dostepne opcje: 1 - punkty, 2 - siatka, 3 - trojkaty.";
  335.         Sleep(5000);
  336.     }
  337. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement