Advertisement
Guest User

Untitled

a guest
Dec 16th, 2019
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 15.32 KB | None | 0 0
  1. #include <windows.h>
  2. #include <math.h>
  3. #define M_PI 3.14159265358979323846
  4. #include <time.h>
  5. #include <iostream>
  6. #include <gl/gl.h>
  7. #include <gl/glut.h>
  8. #include <cstdlib>
  9.  
  10. //Definicja typu point3 - punkt w przestrzeni 3D
  11. typedef float point3[3];
  12. const float PI = 3.14159265;
  13. static GLfloat viewer[] = { 0.0, 0.0, 10.0 };
  14. // inicjalizacja położenia obserwatora
  15. static GLfloat fi = 0.0, // kąty obrotu, elewacja i azymut
  16. theta = 0.0;
  17. static GLfloat pix2angle_x, // przelicznik pikseli na stopnie
  18. pix2angle_y;
  19. static GLint status = 0; // stan klawiszy myszy
  20.                          // 0 - nie naciśnięto żadnego klawisza
  21.                          // 1 - naciśnięty został lewy klawisz, 2 - prawy
  22. static int x_pos_old = 0, // poprzednia pozycja kursora myszy
  23. y_pos_old = 0;
  24. static int delta_x = 0, // różnica pomiędzy pozycjami
  25. delta_y = 0; // i poprzednią kursora myszy
  26.              //Przelacznik renderowania scian
  27. bool sciany[5] = { true, true, true, true, true };
  28. //Parametry programu
  29. float verLength = 2.0; //Dlugosc boku kwadratu
  30. float viewerR = 5.0; //Promien sfery obserwatora
  31.                      /*Funkcja wczytuje dane obrazu zapisanego w formacie TGA w pliku, alokuje
  32.                      pamięć i zwraca wskaźnik (pBits) do bufora w którym umieszczone są dane.
  33.                      Ponadto udostępnia (ImWidth), (ImHeight) obrazu tekstury oraz dane
  34.                      opisujące format obrazu według specyfikacji OpenGL (ImComponents) i
  35.                      (ImFormat).*/
  36. GLbyte* LoadTGAImage(const char* FileName, GLint* ImWidth, GLint
  37.     * ImHeight, GLint* ImComponents, GLenum* ImFormat)
  38. {
  39.     // Struktura dla nagłówka pliku TGA
  40. #pragma pack(1)
  41.     typedef struct
  42.     {
  43.         GLbyte idlength;
  44.         GLbyte colormaptype;
  45.         GLbyte datatypecode;
  46.         unsigned short colormapstart;
  47.         unsigned short colormaplength;
  48.         unsigned char colormapdepth;
  49.         unsigned short x_orgin;
  50.         unsigned short y_orgin;
  51.         unsigned short width;
  52.         unsigned short height;
  53.         GLbyte bitsperpixel;
  54.         GLbyte descriptor;
  55.     }TGAHEADER;
  56. #pragma pack(8)
  57.     FILE* pFile;
  58.     TGAHEADER tgaHeader;
  59.     unsigned long lImageSize;
  60.     short sDepth;
  61.     GLbyte* pbitsperpixel = NULL;
  62.     // Wartości domyślne zwracane w przypadku błędu
  63.     *ImWidth = 0;
  64.     *ImHeight = 0;
  65.     *ImFormat = GL_BGR_EXT;
  66.     *ImComponents = GL_RGB8;
  67.     fopen_s(&pFile, FileName, "rb");
  68.     if (pFile == NULL)
  69.         return NULL;
  70.     // Przeczytanie nagłówka pliku
  71.     fread(&tgaHeader, sizeof(TGAHEADER), 1, pFile);
  72.     // Odczytanie szerokości, wysokości i głębi obrazu
  73.     *ImWidth = tgaHeader.width;
  74.     *ImHeight = tgaHeader.height;
  75.     sDepth = tgaHeader.bitsperpixel / 8;
  76.     // Sprawdzenie, czy głębia spełnia założone warunki (8, 24, lub 32 bity)
  77.     if (tgaHeader.bitsperpixel != 8 && tgaHeader.bitsperpixel != 24 &&
  78.         tgaHeader.bitsperpixel != 32)
  79.         return NULL;
  80.     // Obliczenie rozmiaru bufora w pamięci
  81.     lImageSize = tgaHeader.width * tgaHeader.height * sDepth;
  82.     // Alokacja pamięci dla danych obrazu
  83.     pbitsperpixel = (GLbyte*)malloc(lImageSize * sizeof(GLbyte));
  84.     if (pbitsperpixel == NULL)
  85.         return NULL;
  86.     if (fread(pbitsperpixel, lImageSize, 1, pFile) != 1)
  87.     {
  88.         free(pbitsperpixel);
  89.         return NULL;
  90.     }
  91.     // Ustawienie formatu OpenGL
  92.     switch (sDepth)
  93.     {
  94.     case 3:
  95.         *ImFormat = GL_BGR_EXT;
  96.         *ImComponents = GL_RGB8;
  97.         break;
  98.     case 4:
  99.         *ImFormat = GL_BGRA_EXT;
  100.         *ImComponents = GL_RGBA8;
  101.         break;
  102.     case 1:
  103.         *ImFormat = GL_LUMINANCE;
  104.         *ImComponents = GL_LUMINANCE8;
  105.         break;
  106.     };
  107.     fclose(pFile);
  108.     return pbitsperpixel;
  109. }
  110. //------------------------------------------------------------------------
  111. //Funkcja rysujaca ostroslup
  112. void Pyramid(float sX, float sY, float sZ) {
  113.     //Ustawienie koloru
  114.     glColor3f(1.0, 1.0, 1.0);
  115.     //Rysowanie scian, poczawszy od podstawy i tylko jesli przelacznik dla  sciany == true
  116.         //Podstawa
  117.     if (sciany[0]) {
  118.         glBegin(GL_QUADS);
  119.         glNormal3f(0.0, -1.0, 0.0);
  120.         glTexCoord2f(0.0, 0.0);
  121.         glVertex3f(sX, sY, sZ);
  122.         glNormal3f(0.0, -1.0, 0.0);
  123.         glTexCoord2f(1.0, 0.0);
  124.         glVertex3f(sX + verLength, sY, sZ);
  125.         glNormal3f(0.0, -1.0, 0.0);
  126.         glTexCoord2f(1.0, 1.0);
  127.         glVertex3f(sX + verLength, sY, sZ + verLength);
  128.         glNormal3f(0.0, -1.0, 0.0);
  129.         glTexCoord2f(0.0, 1.0);
  130.         glVertex3f(sX, sY, sZ + verLength);
  131.         glEnd();
  132.     }
  133.     //Sciana 1.
  134.     if (sciany[1]) {
  135.         glBegin(GL_TRIANGLES);
  136.         glNormal3f(0.0, 0.0, -1.0);
  137.         glTexCoord2f(0.0, 0.0);
  138.         glVertex3f(sX, sY, sZ);
  139.         glNormal3f(0.0, 0.0, -1.0);
  140.         glTexCoord2f(1.0, 0.0);
  141.         glVertex3f(sX + verLength / 2, sY + 2.0, sZ + verLength / 2);
  142.         glNormal3f(0.0, 0.0, -1.0);
  143.         glTexCoord2f(0.5, 0.5);
  144.         glVertex3f(sX + verLength, sY, sZ);
  145.         glEnd();
  146.     }
  147.     //Sciana 2.
  148.     if (sciany[2]) {
  149.         glBegin(GL_TRIANGLES);
  150.         glNormal3f(1.0, 0.0, 0.0);
  151.         glTexCoord2f(0.0, 0.0);
  152.         glVertex3f(sX + verLength, sY, sZ);
  153.         glNormal3f(1.0, 0.0, 0.0);
  154.         glTexCoord2f(1.0, 0.0);
  155.         glVertex3f(sX + verLength / 2, sY + 2.0, sZ + verLength / 2);
  156.         glNormal3f(1.0, 0.0, 0.0);
  157.         glTexCoord2f(0.5, 5.0);
  158.         glVertex3f(sX + verLength, sY, sZ + verLength);
  159.         glEnd();
  160.     }
  161.     //Sciana 3.
  162.     if (sciany[3]) {
  163.         glBegin(GL_TRIANGLES);
  164.         glNormal3f(0.0, 0.0, 1.0);
  165.         glTexCoord2f(0.0, 0.0);
  166.         glVertex3f(sX + verLength, sY, sZ + verLength);
  167.         glNormal3f(0.0, 0.0, 1.0);
  168.         glTexCoord2f(1.0, 0.0);
  169.         glVertex3f(sX + verLength / 2, sY + 2.0, sZ + verLength / 2);
  170.         glNormal3f(0.0, 0.0, 1.0);
  171.         glTexCoord2f(0.5, 0.5);
  172.         glVertex3f(sX, sY, sZ + verLength);
  173.         glEnd();
  174.     }
  175.     //Sciana 4.
  176.     if (sciany[4]) {
  177.         glBegin(GL_TRIANGLES);
  178.         glNormal3f(-1.0, 0.0, 0.0);
  179.         glTexCoord2f(0.0, 0.0);
  180.         glVertex3f(sX, sY, sZ + verLength);
  181.         glNormal3f(-1.0, 0.0, 0.0);
  182.         glTexCoord2f(1.0, 0.0);
  183.         glVertex3f(sX + verLength / 2, sY + 2.0, sZ + verLength / 2);
  184.         glNormal3f(-1.0, 0.0, 0.0);
  185.         glTexCoord2f(0.5, 0.5);
  186.         glVertex3f(sX, sY, sZ);
  187.         glEnd();
  188.     }
  189. }
  190. // Funkcja rysująca osie układu współrzędnych
  191. void Axes(void)
  192. {
  193.     point3 x_min = { -2.0, 0.0, 0.0 };
  194.     point3 x_max = { 2.0, 0.0, 0.0 };
  195.     // początek i koniec obrazu osi x
  196.     point3 y_min = { 0.0, -2.0, 0.0 };
  197.     point3 y_max = { 0.0, 2.0, 0.0 };
  198.     // początek i koniec obrazu osi y
  199.     point3 z_min = { 0.0, 0.0, -2.0 };
  200.     point3 z_max = { 0.0, 0.0, 2.0 };
  201.     // początek i koniec obrazu osi y
  202.     glColor3f(1.0f, 0.0f, 0.0f); // kolor rysowania osi - czerwony
  203.     glBegin(GL_LINES); // rysowanie osi x
  204.     glVertex3fv(x_min);
  205.     glVertex3fv(x_max);
  206.     glEnd();
  207.     glColor3f(0.0f, 1.0f, 0.0f); // kolor rysowania - zielony
  208.     glBegin(GL_LINES); // rysowanie osi y
  209.     glVertex3fv(y_min);
  210.     glVertex3fv(y_max);
  211.     glEnd();
  212.     glColor3f(0.0f, 0.0f, 1.0f); // kolor rysowania - niebieski
  213.     glBegin(GL_LINES); // rysowanie osi z
  214.     glVertex3fv(z_min);
  215.     glVertex3fv(z_max);
  216.     glEnd();
  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.     if (status == 1) { // jeśli lewy klawisz myszy wciśnięty
  227.         theta += delta_x * pix2angle_x; // modyfikacja kąta obrotu o   kąt proporcjonalny
  228.         fi += delta_y * pix2angle_y; // do różnicy położeń kursora myszy
  229.         if (theta >= 360.0)
  230.             theta = 0.0;
  231.         if (fi >= 360.0)
  232.             fi = 0.0;
  233.     }
  234.     else if (status == 2) { // jeśli prawy klawisz myszy wciśnięty
  235.         viewerR += 0.1 * delta_y; // modyfikacja polozenia  obserwatora(zoom)
  236.         if (viewerR <= 3.0) // ograniczenie zblizenia
  237.             viewerR = 3.0;
  238.         if (viewerR >= 10.0) // ograniczenie oddalenia
  239.             viewerR = 10.0;
  240.     }
  241.     //Wspolrzedne obserwatora - wzorki z ZSK
  242.     viewer[0] = viewerR * cos(theta) * cos(fi);
  243.     viewer[1] = viewerR * sin(fi);
  244.     viewer[2] = viewerR * sin(theta) * cos(fi);
  245.     gluLookAt(viewer[0], viewer[1], viewer[2], 0.0, 0.0, 0.0, 0.0, cos(fi),
  246.         0.0);
  247.     // Zdefiniowanie położenia obserwatora
  248.     Axes();
  249.     // Narysowanie osi przy pomocy funkcji zdefiniowanej powyżej
  250.     //Renderowanie trojkata
  251.     Pyramid(-1.0, 0.0, -1.0);
  252.  
  253.     glutSwapBuffers();
  254.  
  255.     glFlush();
  256.     // Przekazanie poleceń rysujących do wykonania
  257. }
  258. //Funkcja - callback dla klawiszy
  259. void Keys(unsigned char key, int x, int y)
  260. {
  261.     //Zmiana rodzaju modelu w zaleznosci od klawisza
  262.     if (key == '1') sciany[0] = !sciany[0];
  263.     if (key == '2') sciany[1] = !sciany[1];
  264.     if (key == '3') sciany[2] = !sciany[2];
  265.     if (key == '4') sciany[3] = !sciany[3];
  266.     if (key == '5') sciany[4] = !sciany[4];
  267.  
  268.     RenderScene();
  269. }
  270. // Funkcja ustalająca stan renderowania
  271. void MyInit(void)
  272. {
  273.     glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
  274.     // Kolor czyszcący (wypełnienia okna) ustawiono na czarny
  275.     // Zmienne dla obrazu tekstury
  276.     GLbyte* pBytes;
  277.     GLint ImWidth, ImHeight, ImComponents;
  278.     GLenum ImFormat;
  279.     // Definicja materiału z jakiego zrobiony jest przedmiot
  280.     //-------------------------------------------------------
  281.     GLfloat mat_ambient[] = { 1.0, 1.0, 1.0, 1.0 };
  282.     // współczynniki ka =[kar,kag,kab] dla światła otoczenia
  283.     GLfloat mat_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
  284.     // współczynniki kd =[kdr,kdg,kdb] światła rozproszonego
  285.     GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
  286.     // współczynniki ks =[ksr,ksg,ksb] dla światła odbitego
  287.     GLfloat mat_shininess = { 100.0 };
  288.     // współczynnik n opisujący połysk powierzchni
  289.     // Definicja źródła światła
  290.     //-------------------------------------------------------
  291.     GLfloat light_position[] = { 0.0, 0.0, 10.0, 1.0 };
  292.     // położenie źródła
  293.     GLfloat light_ambient[] = { 0.1f, 0.1f, 0.1f, 1.0f };
  294.     // składowe intensywności świecenia źródła światła otoczenia
  295.     // Ia = [Iar,Iag,Iab]
  296.     GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
  297.     // składowe intensywności świecenia źródła światła powodującego
  298.     // odbicie dyfuzyjne Id = [Idr,Idg,Idb]
  299.     GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
  300.     // składowe intensywności świecenia źródła światła powodującego
  301.     // odbicie kierunkowe Is = [Isr,Isg,Isb]
  302.     GLfloat att_constant = { 1.0 };
  303.     // składowa stała ds dla modelu zmian oświetlenia w funkcji
  304.     // odległości od źródła
  305.     GLfloat att_linear = { 0.05f };
  306.     // składowa liniowa dl dla modelu zmian oświetlenia w funkcji
  307.     // odległości od źródła
  308.     GLfloat att_quadratic = { 0.001f };
  309.     // składowa kwadratowa dq dla modelu zmian oświetlenia w funkcji
  310.     // odległości od źródła
  311.     // Ustawienie patrametrów materiału
  312.     //-------------------------------------------------------
  313.     glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
  314.     glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
  315.     glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
  316.     glMaterialf(GL_FRONT, GL_SHININESS, mat_shininess);
  317.     // Ustawienie parametrów źródła światła
  318.     //-------------------------------------------------------
  319.     glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
  320.     glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
  321.     glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
  322.     glLightfv(GL_LIGHT0, GL_POSITION, light_position);
  323.     glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, att_constant);
  324.     glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, att_linear);
  325.     glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, att_quadratic);
  326.     // Ustawienie opcji systemu oświetlania sceny
  327.     //-------------------------------------------------------
  328.     glShadeModel(GL_SMOOTH); // właczenie łagodnego cieniowania
  329.     glEnable(GL_LIGHTING); // właczenie systemu oświetlenia sceny
  330.     glEnable(GL_LIGHT0); // włączenie źródła o numerze 0
  331.     glEnable(GL_DEPTH_TEST); // włączenie mechanizmu z-bufora
  332.                              // Teksturowanie będzie prowadzone tyko po jednej stronie ściany
  333.     glEnable(GL_CULL_FACE);
  334.     // Przeczytanie obrazu tekstury z pliku o nazwie tekstura.tga
  335.     pBytes = LoadTGAImage("tekstura.tga", &ImWidth, &ImHeight, &ImComponents, &ImFormat);
  336.     if (pBytes == NULL)
  337.         std::cout << "error";
  338.     // Zdefiniowanie tekstury 2-D
  339.     glTexImage2D(GL_TEXTURE_2D, 0, ImComponents, ImWidth, ImHeight, 0,
  340.         ImFormat, GL_UNSIGNED_BYTE, pBytes);
  341.     // Zwolnienie pamięci
  342.     free(pBytes);
  343.     // Włączenie mechanizmu teksturowania
  344.     glEnable(GL_TEXTURE_2D);
  345.     // Ustalenie trybu teksturowania
  346.     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  347.     // Określenie sposobu nakładania tekstur
  348.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  349.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  350. }
  351. // Funkcja ma za zadanie utrzymanie stałych proporcji rysowanych
  352. // w przypadku zmiany rozmiarów okna.
  353. // Parametry vertical i horizontal (wysokość i szerokość okna) są
  354. // przekazywane do funkcji za każdym razem gdy zmieni się rozmiar okna.
  355. void ChangeSize(GLsizei horizontal, GLsizei vertical) {
  356.     pix2angle_x = 360.0 * 0.1 / (float)horizontal; // przeliczenie pikseli na   stopnie
  357.     pix2angle_y = 360.0 * 0.1 / (float)vertical;
  358.     glMatrixMode(GL_PROJECTION);
  359.     // Przełączenie macierzy bieżącej na macierz projekcji
  360.     glLoadIdentity();
  361.     // Czyszcznie macierzy bieżącej
  362.     gluPerspective(70.0, 1.0, 1.0, 30.0);
  363.     // Ustawienie parametrów dla rzutu perspektywicznego
  364.     if (horizontal <= vertical)
  365.         glViewport(0, (vertical - horizontal) / 2, horizontal, horizontal);
  366.     else
  367.         glViewport((horizontal - vertical) / 2, 0, vertical, vertical);
  368.     // Ustawienie wielkości okna okna widoku (viewport) w zależności
  369.     // relacji pomiędzy wysokością i szerokością okna
  370.     glMatrixMode(GL_MODELVIEW);
  371.     // Przełączenie macierzy bieżącej na macierz widoku modelu
  372.     glLoadIdentity();
  373.     // Czyszczenie macierzy bieżącej
  374. }
  375. // Funkcja "bada" stan myszy i ustawia wartosci odpowiednich zmiennych globalnych
  376. void Mouse(int btn, int state, int x, int y) {
  377.     if (btn == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
  378.         x_pos_old = x; // przypisanie aktualnie odczytanej pozycji  kursora
  379.         y_pos_old = y; // jako pozycji poprzedniej
  380.         status = 1; // wciśnięty został lewy klawisz myszy
  381.     }
  382.     else if (btn == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) {
  383.         y_pos_old = y; // przypisanie aktualnie odczytanej pozycji  kursora
  384.             // jako pozycji poprzedniej
  385.         status = 2; //wciśnięty został prawy klawisz myszy
  386.     }
  387.     else
  388.         status = 0; // nie został wciśnięty żaden klawisz
  389. }
  390. // Funkcja "monitoruje" polozenie kursora myszy i ustawia wartosci odpowiednich
  391. // zmiennych globalnych
  392. void Motion(GLsizei x, GLsizei y) {
  393.     delta_x = x - x_pos_old; // obliczenie różnicy położenia kursora myszy
  394.     x_pos_old = x; // podstawienie bieżacego położenia jako poprzednie
  395.     delta_y = y - y_pos_old; // obliczenie różnicy położenia kursora myszy
  396.     y_pos_old = y; // podstawienie bieżacego położenia jako poprzednie
  397.     glutPostRedisplay(); // przerysowanie obrazu sceny
  398. }
  399. // Główny punkt wejścia programu. Program działa w trybie konsoli
  400. int main(int argc, char* argv[])
  401. {
  402.     //Ziarno losowosci
  403.     srand((unsigned)time(NULL));
  404.     glutInit(&argc, argv);
  405.     glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  406.     glutInitWindowSize(1200, 800);
  407.     glutCreateWindow("Teksturowanie");
  408.     glutDisplayFunc(RenderScene);
  409.     // Określenie, że funkcja RenderScene będzie funkcją zwrotną
  410.     // (callback function). Bedzie ona wywoływana za każdym razem
  411.     // gdy zajdzie potrzba przeryswania okna
  412.     // Dla aktualnego okna ustala funkcję zwrotną odpowiedzialną
  413.     // zazmiany rozmiaru okna
  414.     glutReshapeFunc(ChangeSize);
  415.     MyInit();
  416.     // Funkcja MyInit() (zdefiniowana powyżej) wykonuje wszelkie
  417.     // inicjalizacje konieczne przed przystąpieniem do renderowania
  418.     glutMouseFunc(Mouse);
  419.     // Ustala funkcję zwrotną odpowiedzialną za badanie stanu myszy
  420.     glutMotionFunc(Motion);
  421.     // Ustala funkcję zwrotną odpowiedzialną za badanie ruchu myszy
  422.     //Rejestracja funkcji zwrotnej dla klawiatury
  423.     glutKeyboardFunc(Keys);
  424.     glutMainLoop();
  425.     // Funkcja uruchamia szkielet biblioteki GLUT
  426. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement