Advertisement
pierdziadek

grafika lab5

Dec 15th, 2024
59
0
99 days
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 14.48 KB | None | 0 0
  1. #include <iostream>
  2.  
  3. #define GL3_PROTOTYPES 1
  4. #include <glew.h>
  5. #include <SDL.h>
  6.  
  7. #include <glm.hpp>
  8. #include <gtc/matrix_transform.hpp>
  9. #include <gtc/type_ptr.hpp>
  10.  
  11. #define WIDTH 800
  12. #define HEIGHT 600
  13.  
  14. //------------------------------------------------------------------------------------------------------------------------------
  15. //Globalne zmienne
  16.  
  17. // kod zrodlowy shadera wierzcholkow
  18. const GLchar* vertexSource =
  19. "#version 150 core\n"
  20. "in vec3 position;"
  21. "in vec3 color;"
  22. "in vec2 texcoord;"
  23. "out vec3 Color;"
  24. "out vec2 Texcoord;"
  25. "uniform mat4 transformMatrix;"
  26. "void main()"
  27. "{"
  28. "    gl_Position =  transformMatrix * vec4(position, 1.0);"
  29. "    Color = color;"
  30. "    Texcoord = texcoord;"
  31. "}";
  32.  
  33. // kod zrodlowy shadera fragmentow
  34. const GLchar* fragmentSource =
  35. "#version 150 core\n"
  36. "in vec3 Color;"
  37. "in vec2 Texcoord;"
  38. "out vec4 outColor;"
  39. "uniform sampler2D tex;"
  40. "void main()"
  41. "{"
  42. "    outColor = texture(tex, Texcoord) * vec4(Color, 1.0);"
  43. "}";
  44.  
  45.  
  46. //------------------------------------------------------------------------------------------------------------------------------
  47.  
  48. GLint posAttrib, colAttrib, texAttrib;                  //wskazniki atrybutow wierzcholkow
  49. GLuint vertexShader, fragmentShader, shaderProgram;     //shadery
  50.  
  51.  
  52. const int NUM_WALLS = 4;
  53. GLuint vao[3], vbo[8], ebo[ 2 ], tex[NUM_WALLS];    // identyfikatory poszczegolnych obiektow (obiekty tablic wierzcholkow, buforow wierzcholkow, elementow, tekstury)
  54.  
  55. float obrot = 0;
  56. float pozycjaX = 0;
  57. float pozycjaY = 0;
  58.  
  59. //------------------------------------------------------------------------------------------------------------------------------
  60.  
  61. float collisionRadius = 0.3f;
  62. struct Wall2D {
  63.     glm::vec2 p1;
  64.     glm::vec2 p2;
  65. };
  66.  
  67. // ze wzoru na odleglosc punktu od plaszczyzny
  68. bool checkCollision2D( const glm::vec3& position, const Wall2D& wall, float radius ) {
  69.     glm::vec2 p = glm::vec2( position.x, position.z );
  70.     glm::vec2 v1 = wall.p1;
  71.     glm::vec2 v2 = wall.p2;
  72.  
  73.     glm::vec2 wallVec = v2 - v1;
  74.  
  75.     glm::vec2 pointVec = p - v1;
  76.  
  77.     float wallLengthSq = glm::dot( wallVec, wallVec );
  78.  
  79.     float t = glm::dot( pointVec, wallVec ) / wallLengthSq;
  80.  
  81.     t = glm::clamp( t, 0.0f, 1.0f );
  82.  
  83.     glm::vec2 closestPoint = v1 + t * wallVec;
  84.  
  85.     float distanceSq = glm::dot( p - closestPoint, p - closestPoint );
  86.  
  87.     return distanceSq <= radius * radius;
  88. }
  89.  
  90.  
  91. GLfloat ver_floor[] = { //wspolrzedne wierzcholkow podlogi
  92.     -5.0f,  0.0f, -5.0f,
  93.     5.0f,  0.0f, -5.0f,
  94.     5.0f,  0.0f,  5.0f,
  95.     -5.0f,  0.0f,  5.0f,
  96. };
  97.  
  98. GLfloat col_floor[] = { //kolory wierzcholkow podlogi
  99.     1.0f, 1.0f, 1.0f,
  100.     1.0f, 1.0f, 1.0f,
  101.     1.0f, 1.0f, 1.0f,
  102.     1.0f, 1.0f, 1.0f,
  103. };
  104.  
  105. GLfloat tex_floor[] = { //wspolrzedne tekstury dla podlogi,
  106.                         //jesli wykraczaja poza przedzial <0,1> nastapi nakladanie zalezne od parametrow ustawionych za pomoca funkcji glTexParameteri, np. GL_REPEAT
  107.     0.0f, 0.0f, // lewy dolny rog tekstury
  108.     5.0f, 0.0f,
  109.     5.0f, 5.0f,
  110.     0.0f, 5.0f, // prawy gorny rog tekstury
  111. };
  112.  
  113. GLuint elements[] = { // pogrupowanie wierzcholkow w trojkaty, wykorzystane zarowno dla sciany jaki dla podlogi
  114.     0,1,2,
  115.     2,3,0,
  116. };
  117.  
  118. float pixels_floor[] = { //tekstura o wymiarach 2x2; dla kazdego punktu okreslone skladowe RGB koloru
  119.     1.0f, 1.0f, 1.0f,   0.1f, 0.1f, 0.1f,
  120.     0.1f, 0.1f, 0.1f,   1.0f, 1.0f, 1.0f,
  121. };
  122.  
  123. GLfloat ver_triangle[] = { //wspolrzedne wierzcholkow trojkata okreslajacego polozenie obserwatora (kamery)
  124.     -0.2f,  0.0f, 0.0f,
  125.      0.2f,  0.0f, 0.0f,
  126.      0.0f,  0.0f, -1.0f,
  127. };
  128.  
  129. GLfloat col_triangle[] = { //kolory wierzcholkow trojkata okreslajacego polozenie obserwatora (kamery)
  130.     0.0f, 0.0f, 1.0f,
  131.     0.0f, 0.0f, 1.0f,
  132.     0.0f, 0.0f, 1.0f,
  133. };
  134.  
  135. GLfloat wierzcholki_labiryntu [ ] = {
  136.     -4.0f, 0.0f, -4.0f,
  137.     4.0f, 0.0f, -4.0f,
  138.     4.0f, 1.0f, -4.0f,
  139.     -4.0f, 1.0f, -4.0f,
  140.  
  141.     -4.0f, 0.0f, 4.0f,
  142.     -4.0f, 1.0f, 4.0f,
  143.  
  144.     4.0f, 0.0f, 4.0f,
  145.     4.0f, 1.0f, 4.0f,
  146.  
  147. };
  148. GLuint trojkaty_labiryntu [ ] = {
  149.     0,1,3,
  150.     1,2,3,
  151.  
  152.     1,4,5,
  153.     1,2,5,
  154.  
  155.     4,6,7,
  156.     4,5,7,
  157. };
  158.  
  159.  
  160.  
  161.  
  162. //------------------------------------------------------------------------------------------------------------------------------
  163.  
  164. int init_shaders()
  165. {
  166.     // tworzenie i kompilacja shadera wierzcholkow
  167.     vertexShader = glCreateShader(GL_VERTEX_SHADER);
  168.     glShaderSource(vertexShader, 1, &vertexSource, NULL);
  169.     glCompileShader(vertexShader);
  170.     GLint status;
  171.     glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &status);
  172.     if (status != GL_TRUE)
  173.     {
  174.         std::cout << "Kompilacja shadera wierzcholkow NIE powiodla sie!\n";
  175.         return 0;
  176.     }
  177.  
  178.     // tworzenie i kompilacja shadera fragmentow
  179.     fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
  180.     glShaderSource(fragmentShader, 1, &fragmentSource, NULL);
  181.     glCompileShader(fragmentShader);
  182.     glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &status);
  183.     if (status != GL_TRUE)
  184.     {
  185.         std::cout << "Kompilacja shadera fragmentow NIE powiodla sie!\n";
  186.         return 0;
  187.     }
  188.  
  189.     // dolaczenie programow przetwarzajacych wierzcholki i fragmenty do programu cieniujacego
  190.     shaderProgram = glCreateProgram();
  191.     glAttachShader(shaderProgram, vertexShader);
  192.     glAttachShader(shaderProgram, fragmentShader);
  193.     glBindFragDataLocation(shaderProgram, 0, "outColor");
  194.     glLinkProgram(shaderProgram);
  195.     glUseProgram(shaderProgram);
  196.  
  197.     // wskazniki atrybutow wierzcholkow
  198.     posAttrib = glGetAttribLocation(shaderProgram, "position");
  199.     glEnableVertexAttribArray(posAttrib);
  200.     colAttrib = glGetAttribLocation(shaderProgram, "color");
  201.     glEnableVertexAttribArray(colAttrib);
  202.     texAttrib = glGetAttribLocation(shaderProgram, "texcoord");
  203.     glEnableVertexAttribArray(texAttrib);
  204.  
  205.     return 1;
  206.  
  207. }
  208.  
  209. //------------------------------------------------------------------------------------------------------------------------------
  210.  
  211. void create_objects()
  212. {
  213.     // generowanie obiektow
  214.     glGenVertexArrays(3, vao);  // obiekt tablicy wierzcholkow, dla kazdego obiektu (np. dla podlogi) mamy jedna tablice
  215.     glGenBuffers(8, vbo);       // obiekty buforow wierzcholkow, dla kazdego typu atrubutow kazdego obiektu mamy jeden bufor (np. bufor dla kolorow podlogi, bufor dla wspolrzednych podlogi itd.)
  216.     glGenBuffers(2, ebo);       // obiekt bufora elementow (ten sam bufor mozna wykorzystac zarowno dla podlogi jak i sciany)
  217.    
  218.     // podloga vao[0]
  219.  
  220.     glBindVertexArray(vao[0]);
  221.  
  222.     glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);  // bufor wspolrzednych wierzcholkow podlogi
  223.     glBufferData(GL_ARRAY_BUFFER, sizeof(ver_floor), ver_floor, GL_STATIC_DRAW);
  224.     glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0);
  225.     glEnableVertexAttribArray(posAttrib);
  226.  
  227.     glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);  // bufor kolorow wierzcholkow podlogi
  228.     glBufferData(GL_ARRAY_BUFFER, sizeof(col_floor), col_floor, GL_STATIC_DRAW);
  229.     glVertexAttribPointer(colAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0);
  230.     glEnableVertexAttribArray(colAttrib);
  231.  
  232.     glBindBuffer(GL_ARRAY_BUFFER, vbo[2]);  // bufor wspolrzednych tekstury podlogi
  233.     glBufferData(GL_ARRAY_BUFFER, sizeof(tex_floor), tex_floor, GL_STATIC_DRAW);
  234.     glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0);
  235.     glEnableVertexAttribArray(texAttrib);
  236.  
  237.     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo[0 ] );
  238.     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW);
  239.  
  240.     // trojkat vao[1]
  241.  
  242.     glBindVertexArray(vao[1]);
  243.  
  244.     glBindBuffer(GL_ARRAY_BUFFER, vbo[3]);  // bufor wspolrzednych wierzcholkow trojkata
  245.     glBufferData(GL_ARRAY_BUFFER, sizeof(ver_triangle), ver_triangle, GL_STATIC_DRAW);
  246.     glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0);
  247.     glEnableVertexAttribArray(posAttrib);
  248.  
  249.     glBindBuffer(GL_ARRAY_BUFFER, vbo[4]);  // bufor kolorow wierzcholkow trojkata
  250.     glBufferData(GL_ARRAY_BUFFER, sizeof(col_triangle), col_triangle, GL_STATIC_DRAW);
  251.     glVertexAttribPointer(colAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0);
  252.     glEnableVertexAttribArray(colAttrib);
  253.    
  254.     // labirynt vao[2]
  255.  
  256.     glBindVertexArray( vao[ 2 ] );
  257.  
  258.     glBindBuffer( GL_ARRAY_BUFFER, vbo[ 5 ] );  // bufor wspolrzednych wierzcholkow podlogi
  259.     glBufferData( GL_ARRAY_BUFFER, sizeof( wierzcholki_labiryntu ), wierzcholki_labiryntu, GL_STATIC_DRAW );
  260.     glVertexAttribPointer( posAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0 );
  261.     glEnableVertexAttribArray( posAttrib );
  262.  
  263.     glBindBuffer( GL_ARRAY_BUFFER, vbo[ 6 ] );  // bufor kolorow wierzcholkow podlogi
  264.     glBufferData( GL_ARRAY_BUFFER, sizeof( col_floor ), col_floor, GL_STATIC_DRAW );
  265.     glVertexAttribPointer( colAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0 );
  266.     glEnableVertexAttribArray( colAttrib );
  267.  
  268.     glBindBuffer( GL_ARRAY_BUFFER, vbo[ 7 ] );  // bufor wspolrzednych tekstury podlogi
  269.     glBufferData( GL_ARRAY_BUFFER, sizeof( tex_floor ), tex_floor, GL_STATIC_DRAW );
  270.     glVertexAttribPointer( texAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0 );
  271.     glEnableVertexAttribArray( texAttrib );
  272.  
  273.     glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, ebo[ 1 ] );
  274.     glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof( trojkaty_labiryntu ), trojkaty_labiryntu, GL_STATIC_DRAW );
  275.  
  276. }
  277.  
  278. //------------------------------------------------------------------------------------------------------------------------------
  279.  
  280. void configure_texture()
  281. {
  282.     glGenTextures(NUM_WALLS, tex);      // obiekt tekstury
  283.     for ( int i = 0; i < NUM_WALLS; ++i ) {
  284.         glBindTexture( GL_TEXTURE_2D, tex[ i ] );
  285.  
  286.         // Przykład różnych ustawień wrap
  287.         if ( i % 2 == 0 ) {
  288.             glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
  289.             glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
  290.         } else {
  291.             glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
  292.             glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
  293.         }
  294.  
  295.         // Przykład różnych ustawień filtrów
  296.         if ( i % 3 == 0 ) {
  297.             glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
  298.             glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
  299.         } else {
  300.             glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
  301.             glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
  302.         }
  303.  
  304.         // Załaduj teksturę (może być ta sama lub inna)
  305.         glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_FLOAT, pixels_floor );
  306.     }
  307. }
  308.  
  309. //------------------------------------------------------------------------------------------------------------------------------
  310.  
  311. int main(int argc, char ** argv)
  312. {
  313.     SDL_Init(SDL_INIT_VIDEO);
  314.     SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
  315.     SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
  316.     SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
  317.     SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
  318.     SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
  319.     SDL_Window* window = SDL_CreateWindow("OpenGL", 100, 100, 800, 600, SDL_WINDOW_OPENGL);
  320.     SDL_GLContext context = SDL_GL_CreateContext(window);
  321.     SDL_Event windowEvent;
  322.  
  323.     glewExperimental = GL_TRUE;
  324.     GLenum err = glewInit();
  325.     if (GLEW_OK != err)
  326.     {
  327.         std::cout << "ERROR" << std::endl;
  328.     }
  329.  
  330.     glEnable(GL_DEPTH_TEST);
  331.     glDepthFunc(GL_LEQUAL); // GL_ALWAYS)
  332.  
  333.     if(!init_shaders())
  334.         return 0;
  335.  
  336.     create_objects();
  337.  
  338.     configure_texture();
  339.  
  340.    
  341.     glm::mat4 projectionMatrix = glm::perspective(glm::radians(45.0f), 1.0f, 1.0f, 20.0f);       //macierz rzutowania perspektywicznego
  342.     glm::mat4 viewMatrix;  //macierz widoku
  343.     glm::mat4 transformMatrix; //macierz wynikowa
  344.  
  345.     GLint transformMatrixUniformLocation = glGetUniformLocation(shaderProgram, "transformMatrix");
  346.  
  347.     int top_view = false; //zmienna okreslajaca czy patrzymy na scene z gory
  348.  
  349.     glm::vec3 position = glm::vec3(0.0f, 1.0f, 0.0f); //poczatkowe polozenie kamery
  350.     glm::vec3 direction = glm::vec3(0.0f, 0.0f, -1.0f); //poczatkowy kierunek, w ktorym kamera jest skierowana
  351.  
  352.  
  353.     while (true)
  354.     {
  355.         if (SDL_PollEvent(&windowEvent))
  356.         {
  357.             if (windowEvent.type == SDL_KEYUP &&
  358.                 windowEvent.key.keysym.sym == SDLK_ESCAPE) break;
  359.             if (windowEvent.type == SDL_QUIT) break;
  360.  
  361.  
  362.             float collisionRadius = 0.1f; // tutaj ogarnac bo jak sie respisz w scanie to nie mozesz z niej wyjsc
  363.             Wall2D walls2D[ 3 ] = {
  364.                 {glm::vec2( -4.0f, -4.0f ), glm::vec2( 4.0f, -4.0f )},
  365.                 {glm::vec2( 4.0f, -4.0f ), glm::vec2( -4.0f, 4.0f )},
  366.                 {glm::vec2( 4.0f, 4.0f ), glm::vec2( -4.0f, 4.0f )},
  367.             };
  368.  
  369.             glm::vec3 newPosition = position;
  370.  
  371.             if ( windowEvent.type == SDL_KEYDOWN ) {
  372.                 switch ( windowEvent.key.keysym.sym ) {
  373.                     case SDLK_SPACE:
  374.                         top_view = !top_view;
  375.                         break;
  376.                     case SDLK_UP:
  377.                         newPosition += 0.3f * direction;
  378.                         break;
  379.  
  380.                     case SDLK_DOWN:
  381.                         newPosition -= 0.3f * direction;
  382.                         break;
  383.  
  384.                     case SDLK_LEFT:
  385.                         obrot += 0.03f;
  386.                         direction = glm::vec3( sinf( obrot ), 0.0f, cosf( obrot ) );
  387.                         break;
  388.  
  389.                     case SDLK_RIGHT:
  390.                         obrot -= 0.03f;
  391.                         direction = glm::vec3( sinf( obrot ), 0.0f, cosf( obrot ) );
  392.                         break;
  393.                 }
  394.             }
  395.  
  396.             bool collision = false;
  397.             for ( int i = 0; i < NUM_WALLS; ++i ) {
  398.                 if ( checkCollision2D( newPosition, walls2D[ i ], collisionRadius ) ) {
  399.                     collision = true;
  400.                     break;
  401.                 }
  402.             }
  403.  
  404.             if ( !collision ) {
  405.                 position = newPosition;
  406.             }
  407.  
  408.         }
  409.         direction = glm::vec3( sinf( obrot ), 0.0f, cosf( obrot ) );
  410.    
  411.         if (top_view) //patrzymy z gory
  412.             viewMatrix = glm::lookAt(glm::vec3(0.0f, 20.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f));
  413.    
  414.         else //patrzymy z miejsca, w ktorym jest obserwator
  415.             viewMatrix = glm::lookAt(position, position + direction, glm::vec3(0.0f, 1.0f, 0.0f));
  416.    
  417.            
  418.         transformMatrix = projectionMatrix * viewMatrix;                // wynikowa macierz transformacji
  419.         glUniformMatrix4fv(transformMatrixUniformLocation, 1, GL_FALSE, glm::value_ptr(transformMatrix));   // macierz jako wejściowa zmienna dla shadera wierzcholkow
  420.  
  421.        
  422.         glClearColor(0.5f, 0.5f, 0.5f, 1.0f);   // szare tlo
  423.         glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
  424.        
  425.         glBindVertexArray(vao[0]);
  426.         glBindTexture( GL_TEXTURE_2D, tex[ 0 ] );
  427.         glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);    //rysujemy podloge
  428.  
  429.         glBindVertexArray(vao[1]);
  430.         glDisable(GL_TEXTURE_2D);
  431.         glDrawArrays(GL_TRIANGLES, 0, 3);   //rysujemy trojkat przedstawiajacy polozenie kamery
  432.  
  433.         for ( int i = 1; i < NUM_WALLS; ++i ) {
  434.             glBindVertexArray( vao[ 2 ] ); // Zakładamy, że vao[2] to labirynt
  435.             glBindTexture( GL_TEXTURE_2D, tex[ i ] ); // Wybierz teksturę dla tej ściany
  436.  
  437.             // Rysuj ścianę i przesuń wskaźnik do kolejnych elementów w buforze
  438.             glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_INT, ( void* ) ( (i-1) * 6 * sizeof( GLuint ) ) );
  439.         }
  440.        
  441.         SDL_GL_SwapWindow(window);
  442.     }
  443.  
  444.     glDeleteProgram(shaderProgram);
  445.     glDeleteShader(fragmentShader);
  446.     glDeleteShader(vertexShader);
  447.  
  448.     glDeleteBuffers(5, vbo);
  449.     glDeleteBuffers(2, ebo);
  450.     glDeleteTextures(1, tex);
  451.     glDeleteVertexArrays(2, vao);
  452.  
  453.     SDL_GL_DeleteContext(context);
  454.     SDL_Quit();
  455.  
  456.     return 0;
  457. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement