Guest User

Untitled

a guest
Jan 9th, 2018
140
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.57 KB | None | 0 0
  1. /*************************************************************************************/
  2. // Szkielet programu do tworzenia modelu sceny 3-D z wizualizacją osi
  3. // układu współrzędnych dla rzutowania perspektywicznego
  4. /*************************************************************************************/
  5. #include <windows.h>
  6. #include <gl/gl.h>
  7. #include <gl/glut.h>
  8. #include <math.h>
  9.  
  10. typedef float point3[3];
  11.  
  12. float pi = 3.14159265359;
  13. float bokKwadrat = 1.0; // długość boku kwadratu jednostkowego
  14. int n = 30; // do podziału kwadratu jednostkowego
  15. point3 **wspTab; // tablica współrzędnych
  16. point3 **kolorTab; // tablica kolorów
  17. int model = 3;
  18.  
  19. static GLfloat viewer[] = { 0.0, 0.0, 10.0 }; // inicjalizacja położenia obserwatora
  20.  
  21. static GLfloat theta = 0.0; // kąt azymutu (kierunek patrzenia na obiekt)
  22. static GLfloat phi = 0.0; // kat elewacji (wysokosc polozenia obserwatora nad horyzontem)
  23. static GLfloat pix2angle_x; // przelicznik pikseli na stopnie
  24. static GLfloat pix2angle_y;
  25. static GLfloat R = 10.0;
  26.  
  27. static GLint status = 0; // stan klawiszy myszy
  28. // 0 - nie naciśnięto żadnego klawisza
  29. // 1 - naciśnięty zostać lewy klawisz
  30. // 2 - nacisniety zostal prawy klawisz
  31.  
  32. static int x_pos_old = 0; // poprzednia pozycja kursora myszy
  33. static int y_pos_old = 0;
  34.  
  35. static int delta_x = 0; // różnica pomiędzy pozycją bieżącą
  36. // i poprzednią kursora myszy
  37. static int delta_y = 0;
  38.  
  39.  
  40. // Obliczanie współrzędnych punktów
  41. float obliczX(float u, float v) {
  42. return (-90 * pow(u, 5) + 225 * pow(u, 4) - 270 * pow(u, 3) + 180 * pow(u, 2) - 45 * u) * cos(v * pi);
  43. }
  44.  
  45. float obliczY(float u, float v) {
  46. return (160 * pow(u, 4) - 320 * pow(u, 3) + 160 * pow(u, 2));
  47. }
  48.  
  49. float obliczZ(float u, float v) {
  50. return (-90 * pow(u, 5) + 225 * pow(u, 4) - 270 * pow(u, 3) + 180 * pow(u, 2) - 45 * u) * sin(v * pi);
  51. }
  52.  
  53. void colors() {
  54. // Tablica kolorów
  55. kolorTab = new point3*[n + 1];
  56. for (int i = 0; i < n + 1; i++)
  57. kolorTab[i] = new point3[n + 1];
  58. for (int i = 0; i < n + 1; i++)
  59. for (int j = 0; j < n + 1; j++) {
  60. kolorTab[i][j][0] = ((float)((rand() % 100)*0.01));
  61. kolorTab[i][j][1] = ((float)((rand() % 100)*0.01));
  62. kolorTab[i][j][2] = ((float)((rand() % 100)*0.01));
  63. }
  64. }
  65.  
  66. // Generowanie siatki punktów
  67. void siatkaPkt() {
  68. wspTab = new point3*[n + 1];
  69. for (int i = 0; i < n + 1; i++)
  70. wspTab[i] = new point3[n + 1];
  71.  
  72. float u, v;
  73.  
  74. for (int i = 0; i<n + 1; i++)
  75. for (int j = 0; j<n + 1; j++) {
  76. u = j * (bokKwadrat / n);
  77. v = i * (bokKwadrat / n);
  78. wspTab[i][j][0] = obliczX(u, v);
  79. wspTab[i][j][1] = obliczY(u, v) - 5;
  80. wspTab[i][j][2] = obliczZ(u, v);
  81. }
  82. }
  83.  
  84.  
  85. void Egg() {
  86. siatkaPkt();
  87.  
  88. // Ustawienie koloru jaja (siatki, punktów)
  89. glColor3f(0.0, 0.5, 0.75);
  90.  
  91. // Wybór trybu/modelu
  92. switch (model) {
  93. case 1: { // punkty
  94. glBegin(GL_POINTS);
  95. for (int i = 0; i<n; i++)
  96. for (int j = 0; j<n; j++)
  97. // wierzchołki odpowiadające punktom z tablicy współrzędnych punktów
  98. glVertex3fv(wspTab[i][j]);
  99. glEnd();
  100. }
  101. break;
  102. case 2: { // siatka
  103. for (int i = 0; i < n; i++)
  104. for (int j = 0; j < n; j++) {
  105. glBegin(GL_LINES);
  106. // pionowe
  107. glVertex3fv(wspTab[i][j]);
  108. glVertex3fv(wspTab[i][j + 1]);
  109. // poziome
  110. glVertex3fv(wspTab[i][j]);
  111. glVertex3fv(wspTab[i + 1][j]);
  112. // przekątne
  113. glVertex3fv(wspTab[i][j]);
  114. glVertex3fv(wspTab[i + 1][j + 1]);
  115. glEnd();
  116. }
  117. }
  118. break;
  119. case 3: { // trójkąty
  120. for (int i = 0; i < n; i++)
  121. for (int j = 0; j < n; j++) {
  122. glBegin(GL_TRIANGLES);
  123. // prawe trójkąty
  124. glColor3fv(kolorTab[i][j + 1]);
  125. glVertex3fv(wspTab[i][j + 1]);
  126. glColor3fv(kolorTab[i + 1][j]);
  127. glVertex3fv(wspTab[i + 1][j]);
  128. glColor3fv(kolorTab[i + 1][j + 1]);
  129. glVertex3fv(wspTab[i + 1][j + 1]);
  130. // lewe trójkąty
  131. glColor3fv(kolorTab[i][j]);
  132. glVertex3fv(wspTab[i][j]);
  133. glColor3fv(kolorTab[i + 1][j]);
  134. glVertex3fv(wspTab[i + 1][j]);
  135. glColor3fv(kolorTab[i][j + 1]);
  136. glVertex3fv(wspTab[i][j + 1]);
  137. glEnd();
  138. }
  139. }
  140. break;
  141. }
  142. }
  143.  
  144. /*************************************************************************************/
  145. // Funkcja rysująca osie układu współrzędnych
  146. void Axes(void)
  147. {
  148. point3 x_min = { -5.0, 0.0, 0.0 };
  149. point3 x_max = { 5.0, 0.0, 0.0 };
  150. // początek i koniec obrazu osi x
  151.  
  152. point3 y_min = { 0.0, -5.0, 0.0 };
  153. point3 y_max = { 0.0, 5.0, 0.0 };
  154. // początek i koniec obrazu osi y
  155.  
  156. point3 z_min = { 0.0, 0.0, -5.0 };
  157. point3 z_max = { 0.0, 0.0, 5.0 };
  158. // początek i koniec obrazu osi y
  159.  
  160. glColor3f(1.0f, 0.0f, 0.0f); // kolor rysowania osi - czerwony
  161. glBegin(GL_LINES); // rysowanie osi x
  162. glVertex3fv(x_min);
  163. glVertex3fv(x_max);
  164. glEnd();
  165.  
  166. glColor3f(0.0f, 1.0f, 0.0f); // kolor rysowania - zielony
  167. glBegin(GL_LINES); // rysowanie osi y
  168. glVertex3fv(y_min);
  169. glVertex3fv(y_max);
  170. glEnd();
  171.  
  172. glColor3f(0.0f, 0.0f, 1.0f); // kolor rysowania - niebieski
  173. glBegin(GL_LINES); // rysowanie osi z
  174. glVertex3fv(z_min);
  175. glVertex3fv(z_max);
  176. glEnd();
  177. }
  178.  
  179. /*************************************************************************************/
  180. // Funkcja określająca co ma być rysowane (zawsze wywoływana, gdy trzeba
  181. // przerysować scenę)
  182. void RenderScene(void)
  183. {
  184. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  185. // Czyszczenie okna aktualnym kolorem czyszczącym
  186.  
  187. glLoadIdentity();
  188. // Czyszczenie macierzy bieżącej
  189.  
  190.  
  191.  
  192.  
  193. if (status == 1) // jeśli lewy klawisz myszy wcięnięty
  194. {
  195. theta += delta_x*pix2angle_x/180;
  196. phi += delta_y*pix2angle_y/180;
  197. }
  198. else if (status == 2) // jeśli prawy klawisz myszy wciśnięty
  199. {
  200. R += 0.1 * delta_y; // skala przyblizania
  201. if (R <= 10.0) R = 10.0; // ograniczenie przyblizenia (im mniejsze, tym wieksze przybl)
  202. if (R >= 50.0) R = 50.0; // ograniczenie oddalenia (im wieksze, tym mniejsze oddalenie)
  203. }
  204.  
  205. viewer[0] = R * cos(theta) * cos(phi);
  206. viewer[1] = R * sin(phi);
  207. viewer[2] = R * sin(theta) * cos(phi);
  208.  
  209.  
  210. gluLookAt(viewer[0], viewer[1], viewer[2], 0.0, 0.0, 0.0, 0.0, cos(phi), 0.0);
  211. // Zdefiniowanie położenia obserwatora
  212. // pierwsze trzy - wspolrzedne obserwatora,
  213. // kolejne trzy - definiuja punkt na ktory obserwator patrzy
  214. // ostatnie trzy - wektor pozwalajacy na podanie skrócenia trzymanej przez obserwatora kamery
  215.  
  216. Axes();
  217. // Narysowanie osi przy pomocy funkcji zdefiniowanej powyżej
  218. glColor3f(1.0f, 1.0f, 1.0f);
  219. // Ustawienie koloru rysowania na biały
  220.  
  221. Egg();
  222. // Narysowanie jajka
  223.  
  224. glFlush();
  225. // Przekazanie poleceń rysujących do wykonania
  226. glutSwapBuffers();
  227. }
  228.  
  229. /*************************************************************************************/
  230. // Funkcja ustalająca stan renderowania
  231. void MyInit(void)
  232. {
  233. glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
  234. // Kolor czyszczący (wypełnienia okna) ustawiono na czarny
  235. }
  236.  
  237. /*************************************************************************************/
  238. // Funkcja ma za zadanie utrzymanie stałych proporcji rysowanych
  239. // w przypadku zmiany rozmiarów okna.
  240. // Parametry vertical i horizontal (wysokość i szerokość okna) są
  241. // przekazywane do funkcji za każdym razem gdy zmieni się rozmiar okna.
  242. void ChangeSize(GLsizei horizontal, GLsizei vertical)
  243. {
  244. pix2angle_x = 360.0 / (float)horizontal; // przeliczenie pikseli na stopnie
  245. pix2angle_y = 360.0 / (float)vertical; // przeliczenie pikseli na stopnie
  246.  
  247. GLdouble aspect; // proporcja w/h okresla proporcje wymiarow okna
  248.  
  249. glViewport(0, 0, horizontal, vertical);
  250.  
  251. glMatrixMode(GL_PROJECTION);
  252. // Przełączenie macierzy bieżącej na macierz projekcji
  253.  
  254. glLoadIdentity();
  255. // Czyszcznie macierzy bieżącej
  256.  
  257. aspect = (GLfloat)horizontal / (GLfloat)vertical;
  258.  
  259. gluPerspective(70, aspect, 1.0, 90.0); // Ustawienie parametrów dla rzutu perspektywicznego
  260. // (fovy, aspect, zNear, zFar)
  261. // (kąt, stosunek szerokości do wysokości, odległość od okna, odległość od rzutni)
  262.  
  263. if (horizontal <= vertical)
  264. glViewport(0, 0, horizontal, vertical);
  265.  
  266. else
  267. glViewport(0, 0, horizontal, vertical);
  268. // Ustawienie wielkości okna okna widoku (viewport) w zależności
  269. // relacji pomiędzy wysokością i szerokością okna
  270.  
  271. glMatrixMode(GL_MODELVIEW);
  272. // Przełączenie macierzy bieżącej na macierz widoku modelu
  273.  
  274. glLoadIdentity();
  275. // Czyszczenie macierzy bieżącej
  276. }
  277.  
  278. /*************************************************************************************/
  279. // Funkcja "bada" stan myszy i ustawia wartości odpowiednich zmiennych globalnych
  280. void Mouse(int btn, int state, int x, int y)
  281. {
  282. if (btn == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
  283. {
  284. x_pos_old = x; // przypisanie aktualnie odczytanej pozycji kursora
  285. // jako pozycji poprzedniej
  286. y_pos_old = y;
  287.  
  288. status = 1; // wcięnięty został lewy klawisz myszy
  289. }
  290. else if (btn == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) {
  291. y_pos_old = y; // przypisanie aktualnie odczytanej pozycji kursora
  292. status = 2; // wcięnięty został prawy klawisz myszy
  293. }
  294. else
  295.  
  296. status = 0; // nie został wcięnięty żaden klawisz
  297. }
  298.  
  299. /*************************************************************************************/
  300. // Funkcja "monitoruje" położenie kursora myszy i ustawia wartości odpowiednich
  301. // zmiennych globalnych
  302. void Motion(GLsizei x, GLsizei y)
  303. {
  304. delta_x = x - x_pos_old; // obliczenie różnicy położenia kursora myszy
  305.  
  306. x_pos_old = x; // podstawienie bieżącego położenia jako poprzednie
  307.  
  308. delta_y = y - y_pos_old;
  309.  
  310. y_pos_old = y;
  311.  
  312. glutPostRedisplay(); // przerysowanie obrazu sceny
  313. }
  314.  
  315. /*************************************************************************************/
  316.  
  317. /*************************************************************************************/
  318. // Funkcja zwrotna dla klawiszy
  319. void Keys(unsigned char key, int x, int y) {
  320. // zmiana modelu wyświetlania
  321. if (key == 'p' || key == '1') model = 1;
  322. if (key == 's' || key == '2') model = 2;
  323. if (key == 't' || key == '3') model = 3;
  324.  
  325. RenderScene();
  326. }
  327.  
  328. /*************************************************************************************/
  329. // Główny punkt wejścia programu. Program działa w trybie konsoli
  330. void main(void){
  331. FreeConsole();
  332.  
  333. glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  334.  
  335. glutInitWindowSize(600, 600);
  336.  
  337. glutCreateWindow("Rzutowanie perspektywiczne");
  338.  
  339. glutMouseFunc(Mouse);
  340. // Ustala funkcję zwrotną odpowiedzialną za badanie stanu myszy
  341.  
  342. glutMotionFunc(Motion);
  343. // Ustala funkcję zwrotną odpowiedzialną za badanie ruchu myszy
  344.  
  345. colors();
  346. glutDisplayFunc(RenderScene);
  347. // Określenie, że funkcja RenderScene będzie funkcją zwrotną
  348. // (callback function). Będzie ona wywoływana za każdym razem
  349. // gdy zajdzie potrzeba przerysowania okna
  350.  
  351. glutReshapeFunc(ChangeSize);
  352. // Dla aktualnego okna ustala funkcję zwrotną odpowiedzialną
  353. // za zmiany rozmiaru okna
  354.  
  355. MyInit();
  356. // Funkcja MyInit() (zdefiniowana powyżej) wykonuje wszelkie
  357. // inicjalizacje konieczne przed przystąpieniem do renderowania
  358. glEnable(GL_DEPTH_TEST);
  359. // Włączenie mechanizmu usuwania niewidocznych elementów sceny
  360.  
  361. glutKeyboardFunc(Keys);
  362. // Funkcja ta rejestruje funkcje zwrotną
  363.  
  364. glutMainLoop();
  365. // Funkcja uruchamia szkielet biblioteki GLUT
  366. }
  367. /*************************************************************************************/
Advertisement
Add Comment
Please, Sign In to add comment