Advertisement
Guest User

Untitled

a guest
Jan 25th, 2020
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.50 KB | None | 0 0
  1. #pragma warning(disable : 4996)
  2.  
  3. #include <math.h>
  4. #include <GL/glut.h>
  5. #include <string.h>
  6. #include <stdio.h>
  7. #include "materials.h"
  8.  
  9. // Definicja stalych
  10. #define OBSERWATOR_FOV_Y 10.0
  11. #define odlmin 10.0
  12. #define odlmax 300.0
  13.  
  14. #define M_PI 3.14159
  15. #define DEG2RAD(x) ((float)(x)*M_PI/180.0)
  16.  
  17. // Zmienne globalne
  18. int szerokoscOkna = 800;
  19. int wysokoscOkna = 600;
  20.  
  21. GLfloat odl = 200.0;
  22. GLfloat rotObsX = 40.0;
  23. GLfloat rotObsY = 40.0;
  24. GLfloat rotObsZ = 0.0;
  25.  
  26. int iloscpodzialowpoziomych = 12;
  27. int zrodlo1 = 1;
  28. int zrodlo2 = 1;
  29. int obecnymaterial = 0;
  30. int normalne = 1;
  31. int smooth = 1;
  32. int fill = 1;
  33. float length;
  34.  
  35. float lPionowych = 10; // Liczba podzialow pionowych
  36. float lPoziomych = 10; // Liczba podzialow poziomych
  37. float promien = 3.0; // Promien walca
  38. float wysokosc = 3.0; // Wysokosc walca
  39. int zmienna = 5;
  40. int zmienna2 = 5;
  41.  
  42. int a = 3;
  43. double h = 5;
  44. int R = 6;
  45. int r = 8;
  46. int n = 40;
  47. int nMin = 4;
  48. int nMax = 64;
  49. double dAlfa;
  50. int i = 0, j;
  51. int N1 = 20;
  52. int N2 = 10;
  53. int rW = 15;
  54. int rZ;
  55. int srA;
  56.  
  57. float r_reflektor = 30;
  58. float predkosc_reflektor = 0.1;
  59. float nachylenie_reflektor = 0;
  60. float kat_reflektor = 0;
  61.  
  62. float material1[5][4] = {
  63. {0, 0, 1, 1.0},// [0] wspolczynnik odbicia swiatla otoczenia
  64. {0, 0, 1, 1.0},// [1] wspolczynnik odbicia swiatla rozproszonego
  65. {0, 0, 1, 1.0},// [2] wspolczynnik odbicia swiatla lustrzanego
  66. {6,0,0,0}, // [3] polysk
  67. {0,0,0.0,1.0} // [4] kolor swiatla emitowanego
  68. };
  69. // Tablica parametrow materialu nr 2
  70. float material2[5][4] = {
  71. {1, 1,0, 1}, // [0] wspolczynnik odbicia swiatla otoczenia
  72. {1, 1,0, 1.0}, // [1] wspolczynnik odbicia swiatla rozproszonego
  73. {0.1, 0.1,0, 1.0}, // [2] wspolczynnik odbicia swiatla lustrzanego
  74. {10, 0.0, 0.0, 0.0}, // [3] polysk
  75. {0.0, 0.0, 0.0, 1.0} // [4] kolor swiatla emitowanego
  76. };
  77.  
  78. //reflektor
  79. GLfloat param_swiatla1[5][4] = {
  80. {1,1,1,1}, // [0] światło otoczenia
  81. {1,1,1,1}, // [1] światło rozproszone
  82. {1,1,1,1}, // [2] światło zwierciadlane
  83. {0,0,0,1}, // [3] położenie
  84. {-1,0,0} // [4] kierunek świecenia
  85. };
  86.  
  87. //kierunkowe
  88. GLfloat param_swiatla2[5][4] = {
  89. {0,0.7,0,1}, // [0] światło otoczenia
  90. {0,0.7,0,1}, // [1] światło rozproszone
  91. {0,0.7,0,1}, // [2] światło zwierciadlane
  92. {10,10,10,0}, // [3] położenie
  93. {0,0,0,0} // [4] kierunek świecenia
  94. };
  95.  
  96.  
  97. // Prototypy funkcji
  98. void UstawParametryWidoku(int szer, int wys);
  99. void WyswietlObraz(void);
  100. void ObslugaKlawiatury(unsigned char klawisz, int x, int y);
  101. void RysujTekstRastrowy(void* font, char* tekst);
  102. void RysujNakladke(void);
  103.  
  104. void UstawSwiatlaIMaterialy()
  105. {
  106. glEnable(GL_LIGHTING);
  107. // Odblokowanie zrodla swiatla nr 1
  108.  
  109.  
  110. if (zrodlo1 == 1)
  111. {
  112. glDisable(GL_LIGHTING);
  113. glPushMatrix();
  114.  
  115. glRotatef(nachylenie_reflektor, 1, 0, 0);
  116. glBegin(GL_LINE_STRIP);
  117. glColor3f(0, 0, 0);
  118. for (int i = 0; i <= 360; i = i + 2)
  119. {
  120. glVertex3f(r_reflektor * cos(DEG2RAD(i)), 0, r_reflektor * sin(DEG2RAD(i)));
  121. }
  122. glEnd();
  123. glPopMatrix();
  124.  
  125. glPushMatrix();
  126.  
  127. glRotatef(nachylenie_reflektor, 1, 0, 0);
  128. glRotatef(kat_reflektor, 0, 1, 0);
  129. glTranslatef(r_reflektor, 0, 0);
  130.  
  131.  
  132. glColor3f(1, 1, 0);
  133. glutSolidSphere(0.3, 5, 5);
  134. glEnable(GL_LIGHTING);
  135.  
  136. glEnable(GL_LIGHT0);
  137.  
  138. // Inicjowanie zrodla swiatla
  139. glLightfv(GL_LIGHT0, GL_DIFFUSE, param_swiatla1[1]);
  140. glLightfv(GL_LIGHT0, GL_SPECULAR, param_swiatla1[2]);
  141. glLightfv(GL_LIGHT0, GL_POSITION, param_swiatla1[3]);
  142. glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 30);
  143. glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, param_swiatla1[4]);
  144.  
  145. glPopMatrix();
  146. }
  147. else {
  148. glDisable(GL_LIGHT0);
  149. }
  150.  
  151. if (zrodlo2 == 1)
  152. {
  153. glEnable(GL_LIGHT1);
  154.  
  155. // Inicjowanie zrodla swiatla
  156. glLightfv(GL_LIGHT1, GL_DIFFUSE, param_swiatla2[1]);
  157. glLightfv(GL_LIGHT1, GL_SPECULAR, param_swiatla2[2]);
  158. glLightfv(GL_LIGHT1, GL_POSITION, param_swiatla2[3]);
  159. glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, param_swiatla2[4]);
  160. }
  161. else {
  162. glDisable(GL_LIGHT1);
  163. }
  164.  
  165. switch (obecnymaterial)
  166. {
  167. case 0:
  168. glMaterialfv(GL_FRONT, GL_AMBIENT, material1[0]);
  169. glMaterialfv(GL_FRONT, GL_DIFFUSE, material1[1]);
  170. glMaterialfv(GL_FRONT, GL_SPECULAR, material1[2]);
  171. glMaterialfv(GL_FRONT, GL_SHININESS, material1[3]);
  172. glMaterialfv(GL_FRONT, GL_EMISSION, material1[4]);
  173. break;
  174. case 1:
  175. glMaterialfv(GL_FRONT, GL_AMBIENT, material2[0]);
  176. glMaterialfv(GL_FRONT, GL_DIFFUSE, material2[1]);
  177. glMaterialfv(GL_FRONT, GL_SPECULAR, material2[2]);
  178. glMaterialfv(GL_FRONT, GL_SHININESS, material2[3]);
  179. glMaterialfv(GL_FRONT, GL_EMISSION, material2[4]);
  180. break;
  181. case 2:
  182. glMaterialfv(GL_FRONT, GL_AMBIENT, PolishedSilverAmbient);
  183. glMaterialfv(GL_FRONT, GL_DIFFUSE, PolishedSilverDiffuse);
  184. glMaterialfv(GL_FRONT, GL_SPECULAR, PolishedSilverSpecular);
  185. glMaterialfv(GL_FRONT, GL_SHININESS, &PolishedSilverShininess);
  186. glMaterialfv(GL_FRONT, GL_EMISSION, material2[4]);
  187. break;
  188. default:
  189. break;
  190. }
  191. }
  192.  
  193. void SyncSmoothIFill()
  194. {
  195. if (smooth)
  196. glShadeModel(GL_SMOOTH);
  197. else
  198. glShadeModel(GL_FLAT);
  199.  
  200. if (fill)
  201. glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  202. else
  203. glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  204. }
  205.  
  206. void wektory(float R, float h, int n, int m)
  207. {
  208.  
  209. glDisable(GL_LIGHTING);
  210.  
  211. glBegin(GL_LINES);
  212. glColor3f(1, 0, 0);
  213.  
  214. float alfa;
  215. int i;
  216. float x;
  217. float z;
  218. float dR, dr, dh, y, tmp1, tmp2;
  219. dh = h / m;
  220.  
  221.  
  222. for (i = 0; i < m; i++)
  223. {
  224. y = dh * i;
  225. tmp1 = y / h;
  226. tmp2 = (y + dh) / h;
  227.  
  228. alfa = 360.0 / n;
  229. for (j = 0; j <= n; j++)
  230. {
  231. x = cos(0.0174532925f * j * alfa);
  232. z = sin(0.0174532925f * j * alfa);
  233.  
  234. glVertex3f(x * R, y, z * R);
  235. glVertex3f((x) * (R+1), y, (z) * (R + 1));
  236. }
  237. }
  238.  
  239.  
  240. alfa = 360.0 / n;
  241. glVertex3f(0, h, 0);
  242. glVertex3f(0, h+1, 0);
  243. for (i = 0; i <= n; i++)
  244. {
  245. x = cos(0.0174532925f * i * alfa);
  246. z = sin(0.0174532925f * i * alfa);
  247.  
  248. glVertex3f(x * R, h, z * R);
  249. glVertex3f((x) * R, h + 1, (z) * R);
  250. }
  251.  
  252. glVertex3f(0, 0, 0);
  253. glVertex3f(0, -1, 0);
  254. for (i = 0; i <= n; i++)
  255. {
  256. x = cos(0.0174532925f * i * alfa);
  257. z = sin(0.0174532925f * i * alfa);
  258.  
  259. glVertex3f(x * R, 0, z * R);
  260. glVertex3f((x)*R, -1, (z)*R);
  261. }
  262.  
  263. glEnd();
  264. glEnable(GL_LIGHTING);
  265. }
  266.  
  267. void powBocznaWalca(float R, float y, float h, int n)
  268. {
  269. float alfa;
  270. int i;
  271. float x;
  272. float z;
  273. glColor3f(0, 1, 1);
  274. glBegin(GL_QUAD_STRIP);
  275.  
  276. alfa = 360.0 / n;
  277. for (i = 0; i <= n; i++)
  278. {
  279. x = cos(0.0174532925f * i * alfa);
  280. z = sin(0.0174532925f * i * alfa);
  281. glNormal3f(x, 0, z);
  282. glVertex3f(x * R, y + 0, z * R);
  283. glVertex3f(x * R, y + h, z * R);
  284. }
  285.  
  286. glEnd();
  287. }
  288.  
  289. void RysujKolo(float R, float y, int n)
  290. {
  291. float alfa;
  292. int i;
  293. float x;
  294. float z;
  295.  
  296. glBegin(GL_TRIANGLE_FAN);
  297. glVertex3f(0, y, 0);
  298.  
  299. alfa = 360.0f / n;
  300. for (i = 0; i <= n; i++)
  301. {
  302. x = cos(0.0174532925f * i * alfa);
  303. z = sin(0.0174532925f * i * alfa);
  304.  
  305. glVertex3f(x * R, y + 0, z * R);
  306. }
  307.  
  308.  
  309. x = cos(0.0);
  310. z = sin(0.0);
  311.  
  312. //glVertex3f(x * R, y + 0, z * R);
  313.  
  314. glEnd();
  315. }
  316.  
  317.  
  318. void rysowanieWalca(float R, float h, int n, int m) {
  319. int i;
  320. float dR, dr, dh, y, tmp1, tmp2;
  321. dh = h / m;
  322. for (i = 0; i < m; i++)
  323. {
  324. y = dh * i;
  325. tmp1 = y / h;
  326. tmp2 = (y + dh) / h;
  327. powBocznaWalca(R, y, dh, n);
  328. }
  329.  
  330. glNormal3f(0, -1, 0);
  331. RysujKolo(R, 0, n);
  332. glNormal3f(0, 1, 0);
  333. RysujKolo(R, h, n);
  334.  
  335. }
  336.  
  337. //////////////////////////////////////////////////////////////////////////////////////////
  338. // Funkcja ustawiajaca parametry rzutu perspektywicznego i rozmiary viewportu. Powinna
  339. // bya wywolywana kazdorazowo po zmianie rozmiarow okna programu.
  340. void UstawParametryWidoku(int szer, int wys)
  341. {
  342. // Zapamietanie wielkosci widoku
  343. szerokoscOkna = szer;
  344. wysokoscOkna = wys;
  345.  
  346. // Ustawienie parametrow viewportu
  347. glViewport(0, 0, szerokoscOkna, wysokoscOkna);
  348.  
  349. // Przejscie w tryb modyfikacji macierzy rzutowania
  350. glMatrixMode(GL_PROJECTION);
  351. glLoadIdentity();
  352. gluPerspective(OBSERWATOR_FOV_Y, (float)szerokoscOkna / (float)wysokoscOkna, 1.0, 1000.0);
  353. }
  354.  
  355.  
  356. //////////////////////////////////////////////////////////////////////////////////////////
  357. // Funkcja wyswietlajaca pojedyncza klatke animacji
  358. void WyswietlObraz(void)
  359. {
  360. // Wyczyszczenie bufora koloru i bufora glebokosci
  361. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  362.  
  363. // Przejscie w tryb modyfikacji macierzy przeksztalcen geometrycznych
  364. glMatrixMode(GL_MODELVIEW);
  365.  
  366. // Zastapienie aktywnej macierzy macierza jednostkowa
  367. glLoadIdentity();
  368.  
  369. // Ustalenie polozenia obserwatora
  370. glTranslatef(0, 0, -odl);
  371. glRotatef(rotObsX, 1, 0, 0);
  372. glRotatef(rotObsY, 0, 1, 0);
  373. glRotatef(rotObsZ, 0, 0, 1);
  374.  
  375.  
  376. UstawSwiatlaIMaterialy();
  377. //RysujUklad();
  378. //glColor3f(1.0, 1.0, 1.0);
  379. //RysujPierscien(10, 4, iloscpodzialowpoziomych);
  380. kat_reflektor = kat_reflektor + predkosc_reflektor;
  381. rysowanieWalca(promien, wysokosc, N1, N2);
  382. RysujNakladke();
  383. if (normalne)
  384. wektory(promien, wysokosc, N1, N2);
  385.  
  386.  
  387. // Przelaczenie buforow ramki
  388. glutSwapBuffers();
  389. }
  390.  
  391. void RysujTekstRastrowy(void* font, char* tekst)
  392. {
  393. int i;
  394.  
  395. for (i = 0; i < (int)strlen(tekst); i++)
  396. glutBitmapCharacter(font, tekst[i]);
  397. }
  398.  
  399. void RysujNakladke(void)
  400. {
  401. char buf[255];
  402.  
  403. // Zmiana typu rzutu z perspektywicznego na ortogonalny
  404. glMatrixMode(GL_PROJECTION);
  405. glPushMatrix();
  406. glLoadIdentity();
  407. glOrtho(0.0, szerokoscOkna, 0.0, wysokoscOkna, -100.0, 100.0);
  408.  
  409. // Modelowanie sceny 2D (zawartosci nakladki)
  410. glMatrixMode(GL_MODELVIEW);
  411. glPushMatrix();
  412. glLoadIdentity();
  413.  
  414. // Zablokowanie oswietlenia (mialoby ono wplyw na kolor tekstu)
  415. glDisable(GL_LIGHTING);
  416.  
  417. // Okreslenie koloru tekstu
  418. glColor3f(1.0, 1.0, 1.0);
  419.  
  420. // RYSOWANIE MENU PARAMETROW ZRODLA SWIATLA
  421.  
  422. sprintf(buf, "Swiatlo: Klawisze 3, 4");
  423. glRasterPos2i(30, 150);
  424. RysujTekstRastrowy(GLUT_BITMAP_8_BY_13, buf);
  425.  
  426. sprintf(buf, "Zobrazowanie geometryczne: Klawisz 7");
  427. glRasterPos2i(30, 140);
  428. RysujTekstRastrowy(GLUT_BITMAP_8_BY_13, buf);
  429.  
  430. sprintf(buf, "Material: Klawisz 5");
  431. glRasterPos2i(30, 130);
  432. RysujTekstRastrowy(GLUT_BITMAP_8_BY_13, buf);
  433.  
  434. sprintf(buf, "Podzialy poziome: 1+,!- pionowe: 2+,@-");
  435. glRasterPos2i(30, 120);
  436. RysujTekstRastrowy(GLUT_BITMAP_8_BY_13, buf);
  437.  
  438. sprintf(buf, "Odleglosc z+ x-");
  439. glRasterPos2i(30, 110);
  440. RysujTekstRastrowy(GLUT_BITMAP_8_BY_13, buf);
  441.  
  442. sprintf(buf, "Wygladzanie 6");
  443. glRasterPos2i(30, 100);
  444. RysujTekstRastrowy(GLUT_BITMAP_8_BY_13, buf);
  445.  
  446. sprintf(buf, "polygon mode 7");
  447. glRasterPos2i(30, 90);
  448. RysujTekstRastrowy(GLUT_BITMAP_8_BY_13, buf);
  449.  
  450. sprintf(buf, "wektory normalne 8");
  451. glRasterPos2i(30, 80);
  452. RysujTekstRastrowy(GLUT_BITMAP_8_BY_13, buf);
  453.  
  454. sprintf(buf, "promien reflektora i+/j-");
  455. glRasterPos2i(30, 70);
  456. RysujTekstRastrowy(GLUT_BITMAP_8_BY_13, buf);
  457.  
  458. sprintf(buf, "predkosc reflektora o+/k-");
  459. glRasterPos2i(30, 60);
  460. RysujTekstRastrowy(GLUT_BITMAP_8_BY_13, buf);
  461.  
  462. sprintf(buf, "kat reflektora p+/l-");
  463. glRasterPos2i(30, 50);
  464. RysujTekstRastrowy(GLUT_BITMAP_8_BY_13, buf);
  465.  
  466. // Przywrocenie macierzy sprzed wywolania funkcji
  467. glMatrixMode(GL_PROJECTION);
  468. glPopMatrix();
  469. glMatrixMode(GL_MODELVIEW);
  470. glPopMatrix();
  471.  
  472. // Odblokowanie oswietlenia
  473. glEnable(GL_LIGHTING);
  474. }
  475.  
  476. //////////////////////////////////////////////////////////////////////////////////////////
  477. // Funkcja obslugi klawiatury
  478. void ObslugaKlawiatury(unsigned char klawisz, int x, int y)
  479. {
  480. switch (klawisz)
  481. {
  482. //Odległość obserwatora
  483. case 'z':
  484. odl = odl > odlmin ? odl - 3.0 : odl;
  485. break;
  486. case 'x':
  487. odl = odl < odlmax ? odl + 3.0 : odl;
  488. break;
  489. //
  490.  
  491. //Podziały pierścienia
  492. case '1':
  493. if (N1 < nMax) N1++;
  494. break;
  495. case '!':
  496. if (N1 > nMin) N1--;
  497. break;
  498. case '2':
  499. if (N2 < nMax) N2++;
  500. break;
  501. case '@':
  502. if (N2 > nMin) N2--;
  503. break;
  504.  
  505. //Źródła światła
  506. case '3':
  507. zrodlo1 = !zrodlo1;
  508. break;
  509. case '4':
  510. zrodlo2 = !zrodlo2;
  511. break;
  512.  
  513. //Zmiana materiału bryły
  514. case '5':
  515. obecnymaterial++;
  516. if (obecnymaterial > 2) obecnymaterial = 0;
  517. break;
  518. //
  519.  
  520. //Cieniowanie
  521. case '6':
  522. smooth = !smooth;
  523. SyncSmoothIFill();
  524. break;
  525.  
  526. case '7':
  527. fill = !fill;
  528. SyncSmoothIFill();
  529. break;
  530. //
  531.  
  532. case '8':
  533. normalne = !normalne;
  534. break;
  535.  
  536. //Poruszanie się obserwatora
  537. case 'q':
  538. case 'Q':
  539. rotObsZ = rotObsZ + 1.0;
  540. break;
  541. case 'e':
  542. case 'E':
  543. rotObsZ = rotObsZ - 1.0;
  544. break;
  545. case 'w':
  546. case 'W':
  547. rotObsX = rotObsX + 1.0;
  548. break;
  549. case 's':
  550. case 'S':
  551. rotObsX = rotObsX - 1.0;
  552. break;
  553. case 'a':
  554. case 'A':
  555. rotObsY = rotObsY - 1.0;
  556. break;
  557. case 'd':
  558. case 'D':
  559. rotObsY = rotObsY + 1.0;
  560. break;
  561. //
  562.  
  563.  
  564. case 'i':
  565. r_reflektor++;
  566. break;
  567. case 'j':
  568. r_reflektor--;
  569. break;
  570. case 'o':
  571. predkosc_reflektor = predkosc_reflektor + 0.1;
  572. break;
  573. case 'k':
  574. predkosc_reflektor = predkosc_reflektor - 0.1;
  575. break;
  576. case 'p':
  577. nachylenie_reflektor = nachylenie_reflektor + 1;
  578. break;
  579. case 'l':
  580. nachylenie_reflektor = nachylenie_reflektor - 1;
  581. break;
  582.  
  583. case 27:
  584. exit(0);
  585. break;
  586. default:
  587. break;
  588. }
  589. }
  590.  
  591.  
  592. //////////////////////////////////////////////////////////////////////////////////////////
  593. // Glowna funkcja programu
  594. int main(int argc, char** argv)
  595. {
  596. // Zainicjowanie biblioteki GLUT
  597. glutInit(&argc, argv);
  598.  
  599. // Ustawienie trybu wyswietlania
  600. glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  601.  
  602. // Ustawienie polozenia dolenego lewego rogu okna
  603. glutInitWindowPosition(100, 100);
  604.  
  605. // Ustawienie rozmiarow okna
  606. glutInitWindowSize(szerokoscOkna, wysokoscOkna);
  607.  
  608. // Utworzenie okna
  609. glutCreateWindow("Szescian");
  610.  
  611. // Odblokowanie bufora glebokosci
  612. glEnable(GL_DEPTH_TEST);
  613.  
  614. // Ustawienie wartosci czyszczacej zawartosc bufora glebokosci
  615. glClearDepth(1000.0);
  616.  
  617. // Ustawienie koloru czyszczenia bufora ramki
  618. glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
  619.  
  620. // Wlaczenie wyswietlania wielokatow w postaci obrysow (przydatne w celach diagnostycznych).
  621. glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  622.  
  623. // Zarejestrowanie funkcji (callback) odpowiedzialnej za
  624. glutDisplayFunc(WyswietlObraz);
  625.  
  626. // Zarejestrowanie funkcji (callback) wywolywanej za kazdym razem kiedy
  627. // zmieniane sa rozmiary okna
  628. glutReshapeFunc(UstawParametryWidoku);
  629.  
  630. // Zarejestrowanie funkcji wykonywanej gdy okno nie obsluguje
  631. // zadnych zadan
  632. glutIdleFunc(WyswietlObraz);
  633.  
  634. // Zarejestrowanie funkcji obslugi klawiatury
  635. glutKeyboardFunc(ObslugaKlawiatury);
  636.  
  637. // Obsluga glownej petli programu (wywolywanie zarejestrowanych callbackow
  638. // w odpowiedzi na odbierane zdarzenia lub obsluga stanu bezczynnosci)
  639. glutMainLoop();
  640.  
  641. return 0;
  642. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement