Advertisement
Guest User

slon

a guest
Dec 11th, 2019
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.08 KB | None | 0 0
  1. #include <GL/glut.h>
  2. #include <GL/gl.h>
  3. #include <GL/glu.h>//////////////////////////////////////////////////////////////////////////////////////////
  4. // Program demonstruje skladanie transformacji przy modelowaniu zlozonych obiektow
  5. // skladajacych sie z wielu elementow ruchomych (ramie robota).
  6.  
  7. #include <GL/glut.h>
  8.  
  9.  
  10. // Wskazniki do wykorzystywanych kwadryk
  11. GLUquadricObj *podstawaSciany;
  12. GLUquadricObj *podstawaDyskG;
  13. GLUquadricObj *przegubSciany;
  14. GLUquadricObj *przegubDyskG;
  15. GLUquadricObj *przegubDyskD;
  16. GLUquadricObj *glowicaSciany;
  17. GLUquadricObj *glowicaDyskG;
  18. GLUquadricObj *glowicaDyskD;
  19.  
  20. GLfloat rotObsY = 40.0;
  21. GLfloat rotObsX = 40.0;
  22. GLfloat rotObsZ = 0.0;
  23. GLfloat rotPodstawy = 0.0;
  24. GLfloat rotRamienia1= 40.0;
  25. GLfloat rotRamienia2= -40.0;
  26. GLfloat rotGlowicy = 20.0;
  27. GLfloat rozUchwytow = 0.5;
  28.  
  29. GLfloat rotacjaPlanety = 0.0;
  30. GLfloat rotacjaKsiezyca = 0.0;
  31. GLfloat spinPlanety = 0.0;
  32.  
  33. GLfloat odlMin = -80;
  34. GLfloat Odl = -50;
  35. GLfloat odlMax = -10;
  36. GLfloat zoomSpeed = 0.5;
  37. GLUquadricObj* orbitaPlanety;
  38. GLUquadricObj* orbitaKsiezyca;
  39. GLUquadricObj* cylinder;
  40. GLUquadricObj* prostokat;
  41. GLUquadricObj* orbita;
  42. GLUquadricObj* orbitaKsiezyc;
  43.  
  44.  
  45. float alp=0, spin=0,moon=0;
  46. //////////////////////////////////////////////////////////////////////////////////////////
  47. // Funkcja inicjujaca elementy skladowe ramienia robota zamodelowane jako kwadryki
  48. //
  49. void InicjujRamieRobota(void)
  50. {
  51. // Zainicjowanie scian bocznych walca bedacego podstawa ramienia
  52. podstawaSciany = gluNewQuadric();
  53. gluQuadricDrawStyle(podstawaSciany, GLU_LINE);
  54.  
  55. // Zainicjowanie gornej podstawy walca
  56. podstawaDyskG = gluNewQuadric();
  57. gluQuadricDrawStyle(podstawaDyskG, GLU_LINE);
  58.  
  59. // Zainicjowanie scian bocznych cylindrycznego przegubu ramienia
  60. przegubSciany = gluNewQuadric();
  61. gluQuadricDrawStyle(przegubSciany, GLU_LINE);
  62.  
  63. // Zainicjowanie gornej podstawy walca
  64. przegubDyskG = gluNewQuadric();
  65. gluQuadricDrawStyle(przegubDyskG, GLU_LINE);
  66.  
  67. // Zainicjowanie dolnej podstawy walca
  68. przegubDyskD = gluNewQuadric();
  69. gluQuadricDrawStyle(przegubDyskD, GLU_LINE);
  70.  
  71. // Zainicjowanie scian bocznych cylindra glowicy
  72. glowicaSciany = gluNewQuadric();
  73. gluQuadricDrawStyle(glowicaSciany, GLU_LINE);
  74.  
  75. // Zainicjowanie gornej podstawy walca
  76. glowicaDyskG = gluNewQuadric();
  77. gluQuadricDrawStyle(glowicaDyskG, GLU_LINE);
  78.  
  79. // Zainicjowanie dolnej podstawy walca
  80. glowicaDyskD = gluNewQuadric();
  81. gluQuadricDrawStyle(glowicaDyskD, GLU_LINE);
  82.  
  83. cylinder = gluNewQuadric();
  84. gluQuadricDrawStyle(cylinder, GLU_FILL);
  85.  
  86. prostokat = gluNewQuadric();
  87. gluQuadricDrawStyle(prostokat, GLU_FILL);
  88.  
  89. orbita = gluNewQuadric();
  90. gluQuadricDrawStyle(orbita, GLU_LINE);
  91.  
  92. orbitaKsiezyc = gluNewQuadric();
  93. gluQuadricDrawStyle(orbitaKsiezyc, GLU_LINE);
  94.  
  95. }
  96.  
  97. GLfloat zmienna = 0;
  98. GLfloat spinukladu = 0.0;
  99. GLUquadricObj* slonce;
  100. GLUquadricObj* planeta;
  101. GLUquadricObj* kk;
  102. int i=0;
  103. float obrot=0;
  104. float poruszaj = 0;
  105. float poruszajKsiezyc = 0;
  106. int flag=0;
  107. float obrotPlanety = 0;
  108. GLfloat spinPlaneta = 0;
  109. float obrotKsiezyca = 0;
  110. //////////////////////////////////////////////////////////////////////////////////////////
  111. // Funkcja rysujaca obraz sceny widzianej z biezacej pozycji obserwatora
  112. // Zalozenie: Funkcja glutWireSpehere moze ryswac tylko sfere o promieniu 1
  113. void RysujRamieRobota(GLfloat obrotPodstawy, GLfloat obrotRamienia1,
  114. GLfloat obrotRamienia2, GLfloat obrotGlowicy,
  115. GLfloat rozstawUchwytow)
  116. {
  117. // Pocztaek tworzenia ukladu wspolrzednych
  118. glBegin(GL_LINES);
  119.  
  120. // Os X Red
  121. glColor3f(1.0, 0.0, 0.0);
  122. glVertex3f(-40.0, 0.0, 0.0);
  123. glVertex3f(40.0, 0.0, 0.0);
  124.  
  125. // Os Y Green
  126. glColor3f(0.0,1.0,0.0);
  127. glVertex3f(0.0, -40.0, 0.0);
  128. glVertex3f(0.0, 20.0, 0.0);
  129.  
  130. // Os Z Blue
  131. glColor3f(0.0,0.0,1.0);
  132. glVertex3f(0.0, 0.0, -20.0);
  133. glVertex3f(0.0, 0.0, 20.0);
  134.  
  135. // Koniec tworzenia ukladu wspolrzednych
  136. glEnd();
  137.  
  138. poruszaj += 0.25;
  139. zmienna += 1;
  140. poruszajKsiezyc += 0.5;
  141. //slonce
  142. glColor3f(1,1,0);
  143. glPushMatrix();
  144. glTranslatef(0,0,0);
  145. glRotatef(-90.0,1,0,0);
  146.  
  147. glutWireSphere(2.5,20,20);
  148. glPopMatrix();
  149.  
  150. //elipsa
  151. glColor3f(0, 1, 0.4);
  152. glPushMatrix();
  153. glRotatef(90,1,0,0);
  154. glTranslatef(0, 0, 0);
  155. gluDisk(orbita, 20, 20, 50, 1);
  156. glPopMatrix();
  157.  
  158. //ziemia
  159. glColor3f(0, 0, 1);
  160. glPushMatrix();
  161.  
  162. glRotatef(poruszaj, 0, 1, 0);
  163. glTranslatef(0, 0, 20);
  164. glRotatef(zmienna, 1, 0, 0);
  165. glutWireSphere(1, 20, 20);
  166. glPopMatrix();
  167.  
  168. //orbitaksiezyca
  169. glColor3f(1, 0, 1);
  170. glPushMatrix();
  171. glRotatef(poruszaj, 0, 1, 0);
  172. glTranslatef(0,0,20);
  173. glRotatef(90.0, 1, 0, 0);
  174. gluDisk(orbitaKsiezyc,2.5,2.5,50,1);
  175.  
  176. glPopMatrix();
  177.  
  178.  
  179. //ksiezyc
  180. glColor3f(0.75, 0.75, 0.75);
  181. glPushMatrix();
  182.  
  183.  
  184. glRotatef(-poruszaj, 0, 1, 0);
  185. glRotatef(poruszajKsiezyc, 0, 1, 0);
  186. glTranslatef(0, 0, 20);
  187. glRotatef(poruszajKsiezyc, 0, 1, 0);
  188. glTranslatef(0, 0, 2.5);
  189.  
  190. glutWireSphere(0.25, 20, 20);
  191. glPopMatrix();
  192.  
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200.  
  201. /*
  202.  
  203. glColor3f(1.0, 1.0, 1.0);
  204.  
  205.  
  206.  
  207.  
  208. // Przygotowanie stosu macierzy modelowania
  209. glPushMatrix();
  210.  
  211. // Rysowanie podstawy ramienia (cylinder bez dolnej podstawy)
  212. //
  213.  
  214. //glowa
  215. glTranslatef(0.0, 0.0, 0.0);
  216. glRotatef(0, 1, 0, 0);
  217. glRotatef(obrotGlowicy, 0, 1, 0);
  218.  
  219. glPushMatrix();
  220. glTranslatef(0.0, 4.5, 0.0);
  221. glutWireSphere(0.75, 20, 20);
  222. glPopMatrix();
  223.  
  224.  
  225.  
  226. //OBROT DZIAŁA W PIONIE
  227. // Wyznaczenie osi obrotu ramienia w plaszczyznie pionowej
  228. glTranslatef(0.0, 4.0, 0.0);
  229.  
  230. // Obrot ramienia w plaszczyznie pionowej
  231. glRotatef(obrotRamienia1, 0, 0, 1);
  232.  
  233.  
  234.  
  235. // - deska
  236. glPushMatrix();
  237. glRotatef(-90.0, 1, 0, 0);
  238. glTranslatef(0.0, 0.0, 0.3);
  239. glScalef(1.25, 4.0, 0.5);
  240. glutWireCube(1.0);
  241. glTranslatef(0.0, 0.0, 1.0);
  242. glPopMatrix();
  243.  
  244.  
  245. // Modelowanie ramienia nr 2
  246. glPushMatrix();
  247. glScalef(4.0, 1.0, 1.0);
  248. glTranslatef(2.0 / 4.0, 1.5, 2.0);
  249. glPopMatrix();
  250.  
  251.  
  252. //dzialo lewe
  253. glPushMatrix();
  254. glRotatef(90.0, 0, 1, 0);
  255. glTranslatef(2.0, -0.5, -1.5);
  256. gluCylinder(podstawaSciany, 0.5, 0.5, 6.0, 20, 4);
  257. glTranslatef(0.0, 0.0, 0);
  258. gluDisk(podstawaDyskG, 0.0, 0.5, 20, 4);
  259. glPopMatrix();
  260. //dzialo prawe
  261. glPushMatrix();
  262. glRotatef(90.0, 0, 1, 0);
  263. glTranslatef(-2.0, -0.5, -1.5);
  264. gluCylinder(podstawaSciany, 0.5, 0.5, 6.0, 20, 4);
  265. glTranslatef(0.0, 0.0, 0.0);
  266. gluDisk(podstawaDyskG, 0.0, 0.5, 20, 4);
  267. glPopMatrix();
  268.  
  269.  
  270. // Wyznaczenie osi obrotu glowicy
  271.  
  272. glPopMatrix();
  273.  
  274.  
  275.  
  276.  
  277. //podstawa
  278. glPushMatrix();
  279. // - sciany boczne
  280. glRotatef(-90.0, 1, 0, 0);
  281. gluCylinder(podstawaSciany, 2.5, 2.5, 1.0, 20, 4);
  282.  
  283. // - gorna podstawa
  284. glTranslatef(0.0, 0.0, 1.0);
  285. gluDisk(podstawaDyskG, 0.0, 2.5, 20, 4);
  286.  
  287. // - dolna podstawa
  288. glTranslatef(0.0, 0.0, -1.0);
  289. gluDisk(podstawaDyskG, 0.0, 2.5, 20, 4);
  290. glPopMatrix();
  291.  
  292.  
  293. //walec pionowy
  294. glPushMatrix();
  295. // - sciany boczne
  296. glTranslatef(0.0, 1.0, 0.0);
  297. glRotatef(-90.0, 1, 0, 0);
  298. gluCylinder(podstawaSciany, 0.625, 0.625, 3.0, 20, 4);
  299. glPopMatrix();
  300.  
  301.  
  302.  
  303. // Posprzatanie na stosie macierzy modelowania
  304.  
  305.  
  306.  
  307.  
  308. */
  309.  
  310.  
  311.  
  312.  
  313.  
  314.  
  315.  
  316.  
  317.  
  318.  
  319.  
  320.  
  321.  
  322.  
  323.  
  324.  
  325.  
  326.  
  327.  
  328.  
  329.  
  330.  
  331. /*
  332. //push matrix i pop,. w ich "ciele" musi być jakiś tam obiekt graficzny, ale chyba MAX jeden.
  333. glColor3f(1, 0, 0);
  334. glPushMatrix();
  335. glTranslatef(0, 5, 0);
  336. glRotatef(45.0, 0, 1, 0); // obracasz sześcian o kąt 45st według osi Y.
  337. glScalef(6,10,6); // skalujesz - niżej opisałem.
  338. glutSolidCube(1);
  339. glPopMatrix();
  340.  
  341. glColor3f(0, 1, 0);//kolorek tej nadbudówki
  342. glPushMatrix();
  343. glTranslatef(0,11.5,0); // przesuwasz o 10+1,5 nadbudówke od początku układu w góre żeby byo widać
  344. glScalef(8, 3, 8); //rozciągasz sześcian sobie na takie wartości.
  345. glutSolidCube(1); // i myk rysujesz sześcian 1x1x1 ale on sie przeskaluje przez glScalef
  346. glPopMatrix();
  347.  
  348. glColor3f(0,0,1); // Kolorek tych takich wieżyczek
  349. glPushMatrix();
  350. glTranslatef(3,13.5,3); // przesuwasz sobie obiekt w takie koordy
  351. glutSolidCube(2); // tworzysz w tym miejscu sześcian 2x2x2
  352. glPopMatrix();
  353. //analogicznie
  354. glPushMatrix();
  355. glTranslatef(-3, 13.5, 3);
  356. glutSolidCube(2);
  357. glPopMatrix();
  358. glPushMatrix();
  359. glTranslatef(-3, 13.5, -3);
  360. glutSolidCube(2);
  361. glPopMatrix();
  362.  
  363. glPushMatrix();
  364. glTranslatef(3, 13.5, -3);
  365. glutSolidCube(2);
  366. glPopMatrix();
  367. */
  368. /*
  369. gluCylinder(cylinder,2,2,5,10,10);
  370.  
  371. glColor3f(0.5, 0.5, 0.5);
  372.  
  373. gluCylinder(cylinder,4,3,1,10,10);
  374. glTranslatef(0, 0, 3);
  375.  
  376. gluCylinder(cylinder,6,6,2,10,10);
  377.  
  378. glTranslatef(0,0,2);
  379. gluCylinder(cylinder,2,2,3,10,10);
  380. gluCylinder(cylinder,1,1,4,10,10);
  381. glTranslatef(0,0,4);
  382.  
  383. glColor3f(0.3, 0.5, 0.3);
  384. for(i=0; i<5; i++){
  385. glPushMatrix();
  386. glRotatef(i*(360/5)+obrot,0,0,1);
  387. obrot+=flag*0.5;
  388. glTranslatef(0,5,0);
  389. glPushMatrix();
  390. glScalef(2,8,0.1);
  391. glutSolidCube(1);
  392. glPushMatrix();
  393. glPopMatrix();
  394. glPopMatrix();
  395. }
  396.  
  397. // Posprzatanie na stosie macierzy modelowania
  398. glPopMatrix();
  399. */
  400. }
  401.  
  402. //////////////////////////////////////////////////////////////////////////////////////////
  403. // Funkcja generujaca pojedyncza klatke animacji
  404. void WyswietlObraz(void)
  405. {
  406. // Wyczyszczenie bufora ramki i bufora glebokosci
  407. glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  408.  
  409. // Powielenie macierzy na wierzcholku stosu
  410. glPushMatrix();
  411.  
  412. // Wyznaczenie polozenia obserwatora (przeksztalcenie uladu wspolrzednych
  413. // sceny do ukladu wspolrzednych obserwatora).
  414. glTranslatef(0, 0, Odl);
  415. glRotatef(rotObsX, 1, 0, 0);
  416. glRotatef(rotObsY,0,1,0);
  417. glRotatef(rotObsZ, 0, 0, 1);
  418.  
  419.  
  420. // Generacja obrazu sceny w niewidocznym buforze ramki
  421. RysujRamieRobota(rotPodstawy, rotRamienia1, rotRamienia2, rotGlowicy, rozUchwytow);
  422.  
  423. // Usuniecie macierzy lezacej na wierzcholku stosu (powrot do stanu
  424. // sprzed wywolania funkcji)
  425. glPopMatrix();
  426.  
  427. // Przelaczenie buforow ramki
  428. glutSwapBuffers();
  429.  
  430.  
  431. }
  432.  
  433. //////////////////////////////////////////////////////////////////////////////////////////
  434. // Funkcja ustawiajaca parametry rzutu perspektywicznego i rozmiary viewportu
  435. void UstawParametryWidoku(int szerokosc, int wysokosc)
  436. {
  437. // Ustawienie parametrow viewportu
  438. glViewport(0, 0, szerokosc, wysokosc);
  439.  
  440. // Przejscie w tryb modyfikacji macierzy rzutowania
  441. glMatrixMode(GL_PROJECTION);
  442. glLoadIdentity();
  443. gluPerspective(40.0, (float)szerokosc/(float)wysokosc, 1.0, 1000.0);
  444.  
  445. // Przejscie w tryb modyfikacji macierzy przeksztalcen geometrycznych
  446. glMatrixMode(GL_MODELVIEW);
  447.  
  448. // Zmiana macierzy znajdujacej sie na wierzcholku stosu na macierz jednostkowa
  449. glLoadIdentity();
  450. }
  451.  
  452. //////////////////////////////////////////////////////////////////////////////////////////
  453. // Funkcja klawiszy specjalnych
  454. void ObslugaKlawiszySpecjalnych(int klawisz, int x, int y)
  455. {
  456. switch(klawisz)
  457. {
  458. case GLUT_KEY_UP:
  459. rotObsX = rotObsX + 1.0;
  460. break;
  461.  
  462. case GLUT_KEY_DOWN:
  463. rotObsX = rotObsX - 1.0;
  464. break;
  465.  
  466. case GLUT_KEY_LEFT:
  467. rotObsY = rotObsY - 1.0;
  468. break;
  469.  
  470. case GLUT_KEY_RIGHT:
  471. rotObsY = rotObsY + 1.0;
  472. break;
  473. }
  474. }
  475. //////////////////////////////////////////////////////////////////////////////////////////
  476. // Funkcja obslugi klawiatury
  477. void ObslugaKlawiatury(unsigned char klawisz, int x, int y)
  478. {
  479.  
  480. switch(klawisz)
  481. {
  482. case '2':
  483. rotRamienia1 = (rotRamienia1 < 90.0) ? rotRamienia1 + 1.0 : rotRamienia1;
  484. break;
  485.  
  486. case '@':
  487. rotRamienia1 = (rotRamienia1 > 0.0) ? rotRamienia1 - 1.0 : rotRamienia1;
  488. break;
  489.  
  490. case '3':
  491. rotRamienia2 = (rotRamienia2 < 0.0) ? rotRamienia2 + 1.0 : rotRamienia2;
  492. break;
  493.  
  494. case '#':
  495. rotRamienia2 = (rotRamienia2 > -90.0) ? rotRamienia2 - 1.0 : rotRamienia2;
  496. break;
  497.  
  498. case '4':
  499. rotGlowicy = (rotGlowicy < 360.0) ? rotGlowicy + 1.0 : rotGlowicy;
  500. break;
  501.  
  502. case '$':
  503. rotGlowicy = (rotGlowicy > 0.0) ? rotGlowicy - 1.0 : rotGlowicy;
  504. break;
  505.  
  506. case '5':
  507. rozUchwytow = (rozUchwytow < 1.5) ? rozUchwytow + 0.1 : rozUchwytow;
  508. break;
  509.  
  510. case '%':
  511. rozUchwytow = (rozUchwytow > 0.5) ? rozUchwytow - 0.1 : rozUchwytow;
  512. break;
  513.  
  514. case 'o':
  515. if (Odl > odlMin)
  516. Odl--;
  517. break;
  518.  
  519. case 'i':
  520. if (Odl < odlMax)
  521. Odl++;
  522. break;
  523.  
  524. case 'y':
  525. rotObsZ++;
  526. break;
  527.  
  528. case 'u':
  529. rotObsZ--;
  530. break;
  531. case 'n':
  532. flag = (flag > -4) ? flag - 1:flag ;
  533. break;
  534.  
  535. case 'm':
  536. flag = (flag < 4) ? flag + 1:flag ;
  537. break;
  538. case 'x':
  539. //obrotPlanety = (obrotPlanety > -360) ? obrotPlanety - 10.25f : obrotPlanety;
  540. obrotPlanety = (int)(obrotPlanety + 1) % 360;
  541. //spinPlaneta = (int)(spinPlaneta + 1) % 360;
  542.  
  543. break;
  544. case 'c':
  545. //obrotPlanety = (obrotPlanety < 360) ? obrotPlanety + 10.25f : obrotPlanety;
  546. obrotPlanety = (int)(obrotPlanety - 1) % 360;
  547. //spinPlaneta = (int)(spinPlaneta + 1) % 360;
  548. break;
  549. case 'v':
  550. //obrotPlanety = (obrotPlanety < 360) ? obrotPlanety + 10.25f : obrotPlanety;
  551. obrotKsiezyca = (int)(obrotKsiezyca - 1) % 360;
  552. //spinPlaneta = (int)(spinPlaneta + 1) % 360;
  553. break;
  554. }
  555. if(klawisz == 27)
  556. exit(0);
  557. }
  558.  
  559. //////////////////////////////////////////////////////////////////////////////////////////
  560. // Glowna funkcja programu
  561. int main(int argc, char **argv)
  562. {
  563. // Zainicjowanie biblioteki GLUT
  564. glutInit(&argc, argv);
  565.  
  566. // Ustawienie trybu wyswietlania
  567. glutInitDisplayMode (GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);
  568.  
  569. // Ustawienie polozenia dolenego lewego rogu okna
  570. glutInitWindowPosition(100, 100);
  571.  
  572. // Ustawienie rozmiarow okna
  573. glutInitWindowSize(400, 400);
  574.  
  575. // Utworzenie okna
  576. glutCreateWindow("Robot");
  577.  
  578. // Odblokowanie bufora glebokosci
  579. glEnable(GL_DEPTH_TEST);
  580.  
  581. // Ustawienie funkcji wykonywanej na danych w buforze glebokosci
  582. glDepthFunc(GL_LEQUAL);
  583.  
  584. // Ustawienie wartosci czyszczacej zawartosc bufora glebokosci
  585. glClearDepth(1000.0);
  586.  
  587. // Ustawienie koloru czyszczenia bufora ramki
  588. glClearColor (0.3, 0.3, 0.3, 0.0);
  589.  
  590. // Zarejestrowanie funkcji (callback) wyswietlajacej
  591. glutDisplayFunc(WyswietlObraz);
  592.  
  593. // Zarejestrowanie funkcji (callback) wywolywanej za kazdym razem kiedy
  594. // zmieniane sa rozmiary okna
  595. glutReshapeFunc(UstawParametryWidoku);
  596.  
  597. // Zarejestrowanie funkcji wykonywanej gdy okno nie obsluguje
  598. // zadnych zadan
  599. glutIdleFunc(WyswietlObraz);
  600.  
  601. // Zarejestrowanie funkcji obslugi klawiatury
  602. glutKeyboardFunc(ObslugaKlawiatury);
  603.  
  604. // Zarejestrowanie funkcji obslugi klawiszy specjalnych
  605. glutSpecialFunc(ObslugaKlawiszySpecjalnych);
  606.  
  607.  
  608. // Zainicjowanie kwadryk tworzacych ramie robota
  609. InicjujRamieRobota();
  610.  
  611. // Obsluga glownej petli programu (wywolywanie zarejestrowanych callbackow
  612. // w odpowiedzi na odbierane zdarzenia lub obsluga stanu bezczynnosci)
  613. glutMainLoop();
  614.  
  615. return 0;
  616. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement