Advertisement
czaffik

sdl opengl 2d rect

Feb 3rd, 2018
532
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 15.61 KB | None | 0 0
  1. /// main.cpp ==========================================================================================================================
  2. #include "scene.h"
  3.  
  4. int main(int argc, char* args[])
  5. {
  6.     Scene *s = new Scene(800, 600);
  7.  
  8.     s->init();
  9.     s->eventLoop();
  10.     delete s;
  11.  
  12.     return 0;
  13. }
  14.  
  15.  
  16.  
  17. /// scene.h ==========================================================================================================================
  18. #ifndef SCENE_H
  19. #define SCENE_H
  20.  
  21. #include "rectangle.h"
  22. #include <SDL2/SDL.h>
  23.  
  24. class Scene
  25. {
  26.     public:
  27.         Scene(int _width, int _height);
  28.         virtual ~Scene();
  29.  
  30.         void init();
  31.         void draw();
  32.         void eventLoop();
  33.  
  34.     protected:
  35.         void checkCollisions();
  36.         void createWindow();
  37.  
  38.         int width;
  39.         int height;
  40.  
  41.         std::shared_ptr<Program> program;
  42.         SDL_Window* window = nullptr;
  43.         SDL_GLContext glContext;
  44.         SDL_TimerID timerID;
  45.  
  46.         std::vector<std::shared_ptr<Rectangle> > rect;
  47. };
  48.  
  49. #endif // SCENE_H
  50.  
  51.  
  52.  
  53. // scene.cpp ==========================================================================================================================
  54. #include "scene.h"
  55. #include <glm/gtc/matrix_transform.hpp>
  56. #include <glm/gtc/type_ptr.hpp>
  57. #include <SDL2/SDL_image.h>
  58.  
  59. Scene::Scene(int _width, int _height)
  60.     : width(_width), height(_height)
  61. {
  62.  
  63. }
  64.  
  65. Scene::~Scene()
  66. {
  67.     SDL_GL_DeleteContext(glContext);
  68.     SDL_DestroyWindow(window);
  69.     IMG_Quit();
  70.     SDL_Quit();
  71. }
  72.  
  73. void Scene::init()
  74. {
  75.     createWindow();
  76.  
  77.     glewExperimental = GL_TRUE;
  78.     glewInit();
  79.  
  80.     program = std::make_shared<Program>("model.glvs", "model.glfs");
  81.  
  82.     rect.push_back(std::make_shared<Rectangle>());
  83.     rect[0]->init(program, "ludzik.png", glm::vec2(-50.0f, -50.0f), 20.0f);
  84.  
  85.     rect.push_back(std::make_shared<Rectangle>());
  86.     rect[1]->init(program, "kwadrat.png", glm::vec2(0.0f, 0.0f), 20.0f);
  87.  
  88.     rect.push_back(std::make_shared<Rectangle>());
  89.     rect[2]->init(program, "kwadrat.png", glm::vec2(50.0f, -50.0f), 20.0f);
  90.  
  91.     rect.push_back(std::make_shared<Rectangle>());
  92.     rect[3]->init(program, "kwadrat.png", glm::vec2(-50.0f, 50.0f), 20.0f);
  93.  
  94.     glUseProgram(program->getID());
  95.         glm::mat4 proj = glm::ortho(-static_cast<float>(width)/2.0f,
  96.                                     static_cast<float>(width)/2.0f,
  97.                                     -static_cast<float>(height)/2.0f,
  98.                                     static_cast<float>(height)/2.0f,
  99.                                     -1.0f, 1.0f);
  100.         glUniformMatrix4fv(program->getUniform("proj"), 1, GL_FALSE, glm::value_ptr(proj));
  101.     glUseProgram(0);
  102. }
  103.  
  104. void Scene::draw()
  105. {
  106.     glClearColor(0.0f, 1.0f, 1.0f, 1.0f);
  107.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  108.  
  109.     for(const auto &r : rect) r->draw();
  110.  
  111.     SDL_GL_SwapWindow(window);
  112. }
  113.  
  114. void Scene::eventLoop()
  115. {
  116.     bool quit = false;
  117.     SDL_Event event;
  118.  
  119.     while (!quit)
  120.     {
  121.         while (SDL_PollEvent(&event) != 0)
  122.         {
  123.             if (event.type == SDL_QUIT)
  124.             {
  125.                 quit = true;
  126.             }
  127.             else if (event.type == SDL_KEYDOWN)
  128.             {
  129.                 switch(event.key.keysym.sym)
  130.                 {
  131.                     case SDLK_ESCAPE:
  132.                         quit = true;
  133.                         break;
  134.                 }
  135.             }
  136.  
  137.             const Uint8* currentKeyStates = SDL_GetKeyboardState(NULL);
  138.             if (currentKeyStates[SDL_SCANCODE_W] || currentKeyStates[SDL_SCANCODE_UP]) rect[0]->changePosition(glm::vec2(0.0f, 0.8f));
  139.             else if (currentKeyStates[SDL_SCANCODE_S] || currentKeyStates[SDL_SCANCODE_DOWN]) rect[0]->changePosition(glm::vec2(0.0f, -0.8f));
  140.             else if (currentKeyStates[SDL_SCANCODE_A] || currentKeyStates[SDL_SCANCODE_LEFT]) rect[0]->changePosition(glm::vec2(-0.8f, 0.0f));
  141.             else if (currentKeyStates[SDL_SCANCODE_D] || currentKeyStates[SDL_SCANCODE_RIGHT]) rect[0]->changePosition(glm::vec2(0.8f, 0.0f));
  142.             checkCollisions();
  143.         }
  144.  
  145.         draw();
  146.     }
  147. }
  148.  
  149. void Scene::checkCollisions()
  150. {
  151.     for (unsigned int i = 0; i < rect.size(); i++)
  152.     {
  153.         for (unsigned int j = 0; j < rect.size(); j++)
  154.         {
  155.             if (i == j) continue;
  156.  
  157.             if ((rect[i]->getPoint(0).x >= rect[j]->getPoint(0).x &&
  158.                  rect[i]->getPoint(0).x <= rect[j]->getPoint(1).x &&
  159.                  rect[i]->getPoint(0).y <= rect[j]->getPoint(0).y &&
  160.                  rect[i]->getPoint(0).y >= rect[j]->getPoint(3).y) ||
  161.  
  162.                 (rect[i]->getPoint(1).x >= rect[j]->getPoint(0).x &&
  163.                  rect[i]->getPoint(1).x <= rect[j]->getPoint(1).x &&
  164.                  rect[i]->getPoint(1).y <= rect[j]->getPoint(0).y &&
  165.                  rect[i]->getPoint(1).y >= rect[j]->getPoint(3).y) ||
  166.  
  167.                 (rect[i]->getPoint(2).x >= rect[j]->getPoint(0).x &&
  168.                  rect[i]->getPoint(2).x <= rect[j]->getPoint(1).x &&
  169.                  rect[i]->getPoint(2).y <= rect[j]->getPoint(0).y &&
  170.                  rect[i]->getPoint(2).y >= rect[j]->getPoint(3).y) ||
  171.  
  172.                 (rect[i]->getPoint(3).x >= rect[j]->getPoint(0).x &&
  173.                  rect[i]->getPoint(3).x <= rect[j]->getPoint(1).x &&
  174.                  rect[i]->getPoint(3).y <= rect[j]->getPoint(0).y &&
  175.                  rect[i]->getPoint(3).y >= rect[j]->getPoint(3).y))
  176.                 rect[0]->undo();
  177.         }
  178.     }
  179. }
  180.  
  181. void Scene::createWindow()
  182. {
  183.     SDL_Init( SDL_INIT_VIDEO );
  184.  
  185.     SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
  186.     SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
  187.     SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
  188.     SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
  189.     SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
  190.  
  191.     window = SDL_CreateWindow("OpenGL", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width,
  192.                               height, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);
  193.  
  194.     glContext = SDL_GL_CreateContext(window);
  195.     int imgFlags = IMG_INIT_PNG;
  196.     IMG_Init((imgFlags) & imgFlags);
  197.  
  198.     glEnable(GL_DEPTH_TEST);
  199.     glEnable(GL_CULL_FACE);
  200.     glCullFace(GL_FRONT);
  201.     glFrontFace(GL_CW);
  202. }
  203.  
  204.  
  205.  
  206. /// rectangle.h =======================================================================================================================
  207. #ifndef RECTANGLE_H
  208. #define RECTANGLE_H
  209.  
  210. #include "program.h"
  211. #include <memory>
  212. #include <glm/glm.hpp>
  213.  
  214. class Rectangle
  215. {
  216.     public:
  217.         Rectangle();
  218.         virtual ~Rectangle();
  219.  
  220.         void init(std::shared_ptr<Program> &_program, std::string textureName, glm::vec2 _position, float _scale);
  221.         void draw();
  222.  
  223.         virtual void setProgram(std::shared_ptr<Program> &_program) { program = _program; }
  224.  
  225.         void setPosition(glm::vec2 _position);
  226.         void changePosition(glm::vec2 _dp);
  227.         glm::vec2 getPosition() const { return position; }
  228.  
  229.         float getScale() const { return scale; }
  230.  
  231.         void setMatrix(glm::mat4 _matrix) { matrix = _matrix; }
  232.         void changeMatrix(glm::mat4 _matrix);
  233.         glm::mat4 getMatrix() const { return matrix; }
  234.  
  235.         glm::vec2 getPoint(unsigned int number) { return points[number]; }
  236.  
  237.         void undo() { position = prevPos; }
  238.  
  239.     protected:
  240.         glm::vec2 position = glm::vec2();
  241.         glm::vec2 prevPos;
  242.         float scale = 1.0f;
  243.  
  244.         glm::mat4 matrix;
  245.         std::vector<glm::vec2> points;
  246.  
  247.         std::shared_ptr<Program> program;
  248.         GLuint vao;
  249.         GLuint vbo;
  250.         GLuint ebo;
  251.         GLuint tex;
  252. };
  253.  
  254. #endif // RECTANGLE_H
  255.  
  256.  
  257.  
  258. /// rectangle.cpp =====================================================================================================================
  259. #include "rectangle.h"
  260. #include <SDL2/SDL_image.h>
  261. #include <glm/gtc/matrix_transform.hpp>
  262. #include <glm/gtc/type_ptr.hpp>
  263.  
  264. Rectangle::Rectangle()
  265. {
  266.     glGenVertexArrays(1, &vao);
  267.     glGenBuffers(1, &vbo);
  268.     glGenBuffers(1, &ebo);
  269.     glGenTextures(1, &tex);
  270. }
  271.  
  272. Rectangle::~Rectangle()
  273. {
  274.     glDeleteBuffers(1, &ebo);
  275.     glDeleteBuffers(1, &vbo);
  276.     glDeleteVertexArrays(1, &vao);
  277.     glDeleteTextures(1, &tex);
  278. }
  279.  
  280. void Rectangle::init(std::shared_ptr<Program> &_program, std::string textureName, glm::vec2 _position, float _scale)
  281. {
  282.     program = _program;
  283.     position = _position;
  284.     scale = _scale;
  285.  
  286.     glBindVertexArray(vao);
  287.  
  288.     points.push_back(position + scale*glm::vec2(-1.0f, 1.0f));
  289.     points.push_back(position + scale*glm::vec2(1.0f, 1.0f));
  290.     points.push_back(position + scale*glm::vec2(1.0f, -1.0f));
  291.     points.push_back(position + scale*glm::vec2(-1.0f, -1.0f));
  292.  
  293.     GLfloat vertices[] =
  294.     {
  295.          -1.0f,  1.0f, 0.0f, 1.0f,
  296.           1.0f,  1.0f, 1.0f, 1.0f,
  297.           1.0f, -1.0f, 1.0f, 0.0f,
  298.          -1.0f, -1.0f, 0.0f, 0.0f
  299.     };
  300.     glBindBuffer(GL_ARRAY_BUFFER, vbo);
  301.     glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
  302.  
  303.     GLuint elements[] =
  304.     {
  305.         1, 3, 2, 1, 0, 3
  306.     };
  307.  
  308.     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
  309.     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW);
  310.  
  311.     SDL_Surface *img;
  312.     std::string file;
  313.  
  314.     glActiveTexture(GL_TEXTURE0);
  315.     glBindTexture(GL_TEXTURE_2D, tex);
  316.     file = textureName;
  317.     img = IMG_Load(file.c_str());
  318.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img->w, img->h, 0, GL_RGB, GL_UNSIGNED_BYTE, img->pixels);
  319.     SDL_FreeSurface(img);
  320.  
  321.     glGenerateMipmap(GL_TEXTURE_2D);
  322.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
  323.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_NEAREST);
  324.  
  325.     glGenerateMipmap(GL_TEXTURE_2D);
  326.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
  327.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_NEAREST);
  328.  
  329.     glUseProgram(_program->getID());
  330.         glUniform1i(program->getUniform("tex0"), 0);
  331.     glUseProgram(0);
  332. }
  333.  
  334. void Rectangle::draw()
  335. {
  336.     glUseProgram(program->getID());
  337.         matrix = glm::translate(matrix, glm::vec3(position.x, position.y, 0.0f));
  338.         glUniform1f(program->getUniform("scale"), scale);
  339.         glUniformMatrix4fv(program->getUniform("model"), 1, GL_FALSE, glm::value_ptr(matrix));
  340.  
  341.         glBindVertexArray(vao);
  342.         glBindBuffer(GL_ARRAY_BUFFER, vbo);
  343.         glEnableVertexAttribArray(0);
  344.         glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), 0);
  345.         glEnableVertexAttribArray(1);
  346.         glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), (void*)(2*sizeof(GLfloat)));
  347.  
  348.         glBindVertexArray(vao);
  349.         glActiveTexture(GL_TEXTURE0);
  350.         glBindTexture(GL_TEXTURE_2D, tex);
  351.         glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
  352.  
  353.         matrix = glm::mat4();
  354.     glUseProgram(0);
  355. }
  356.  
  357. void Rectangle::setPosition(glm::vec2 _position)
  358. {
  359.     prevPos = position;
  360.     position = _position;
  361.     points[0] = glm::vec2(position + scale*glm::vec2(-1.0f, 1.0f));
  362.     points[1] = glm::vec2(position + scale*glm::vec2(1.0f, 1.0f));
  363.     points[2] = glm::vec2(position + scale*glm::vec2(1.0f, -1.0f));
  364.     points[3] = glm::vec2(position + scale*glm::vec2(-1.0f, -1.0f));
  365. }
  366.  
  367. void Rectangle::changePosition(glm::vec2 _dp)
  368. {
  369.     prevPos = position;
  370.     position += _dp;
  371.     points[0] = glm::vec2(position + scale*glm::vec2(-1.0f, 1.0f));
  372.     points[1] = glm::vec2(position + scale*glm::vec2(1.0f, 1.0f));
  373.     points[2] = glm::vec2(position + scale*glm::vec2(1.0f, -1.0f));
  374.     points[3] = glm::vec2(position + scale*glm::vec2(-1.0f, -1.0f));
  375. }
  376.  
  377. void Rectangle::changeMatrix(glm::mat4 _matrix)
  378. {
  379.     matrix = _matrix;
  380.     glUniformMatrix4fv(program->getUniform("model"), 1, GL_FALSE, glm::value_ptr(matrix));
  381. }
  382.  
  383.  
  384.  
  385. /// program.h =========================================================================================================================
  386. #ifndef PROGRAM_H
  387. #define PROGRAM_H
  388.  
  389. #include <gl/glew.h>
  390. #include <gl/gl.h>
  391. #include <string>
  392. #include <vector>
  393. #include <map>
  394.  
  395. class Program
  396. {
  397.     public:
  398.         Program(std::string _vertexName, std::string _fragmentName = "", std::string _geometryName = "");
  399.         virtual ~Program();
  400.  
  401.         GLuint getID() const { return id; }
  402.         GLint getUniform(std::string name);
  403.  
  404.     protected:
  405.         void createShader(GLenum type, std::string fileName);
  406.         std::string loadFile(std::string fileName);
  407.  
  408.         GLuint id;
  409.         std::vector<GLuint> shader;
  410.         std::map<std::string, GLint> uniform;
  411.  
  412.     private:
  413. };
  414.  
  415. #endif // PROGRAM_H
  416.  
  417.  
  418.  
  419. /// program.cpp =======================================================================================================================
  420. #include "program.h"
  421. #include <fstream>
  422. #include <iostream>
  423. #include <sstream>
  424.  
  425. Program::Program(std::string _vertexName, std::string _fragmentName, std::string _geometryName)
  426. {
  427.     id = glCreateProgram();
  428.     createShader(GL_VERTEX_SHADER, _vertexName);
  429.     if (!_fragmentName.empty()) createShader(GL_FRAGMENT_SHADER, _fragmentName);
  430.     if (!_geometryName.empty()) createShader(GL_GEOMETRY_SHADER, _geometryName);
  431.  
  432.     glLinkProgram(id);
  433.  
  434.     GLint programSuccess = GL_TRUE;
  435.     glGetProgramiv(id, GL_LINK_STATUS, &programSuccess);
  436.     if (programSuccess != GL_TRUE)
  437.         std::cout << "Nie mozna utworzyc programu: " << glGetError();
  438.  
  439.     glBindFragDataLocation(id, 0, "outColor");
  440. }
  441.  
  442. Program::~Program()
  443. {
  444.     for (const auto &s: shader) glDeleteShader(s);
  445.     glDeleteProgram(id);
  446. }
  447.  
  448. GLint Program::getUniform(std::string name)
  449. {
  450.     auto it = uniform.find(name);
  451.     if (it == uniform.end())
  452.     {
  453.         GLint value = glGetUniformLocation(id, name.c_str());
  454.         if (value != -1) uniform[name] = value;
  455.         else return -1;
  456.     }
  457.  
  458.     return uniform[name];
  459. }
  460.  
  461. void Program::createShader(GLenum type, std::string fileName)
  462. {
  463.     GLuint s;
  464.  
  465.     if      (type == GL_VERTEX_SHADER)   s = glCreateShader(GL_VERTEX_SHADER);
  466.     else if (type == GL_FRAGMENT_SHADER) s = glCreateShader(GL_FRAGMENT_SHADER);
  467.     else if (type == GL_GEOMETRY_SHADER) s = glCreateShader(GL_GEOMETRY_SHADER);
  468.  
  469.     const GLchar *source = loadFile(fileName).c_str();
  470.     glShaderSource(s, 1, &source, nullptr);
  471.     glCompileShader(s);
  472.  
  473.     GLint vShaderCompiled = GL_FALSE;
  474.     glGetShaderiv(s, GL_COMPILE_STATUS, &vShaderCompiled);
  475.     if (vShaderCompiled != GL_TRUE)
  476.         std::cout << "Nie mozna skompilowac shadera: " << fileName << ". Blad: " << glGetError();
  477.  
  478.     glAttachShader(id, s);
  479.     shader.push_back(s);
  480. }
  481.  
  482. std::string Program::loadFile(std::string fileName)
  483. {
  484.     std::fstream file;
  485.     file.open(fileName.c_str(), std::ios::in);
  486.  
  487.     std::stringstream buffer;
  488.     buffer << file.rdbuf();
  489.     std::string data(buffer.str());
  490.  
  491.     return data;
  492. }
  493.  
  494.  
  495.  
  496. // model.glvs =========================================================================================================================
  497. #version 330
  498.  
  499. layout (location = 0) in vec2 position;
  500. layout (location = 1) in vec2 texcoord;
  501.  
  502. out vec2 vTexcoord;
  503.  
  504. uniform mat4 model;
  505. uniform mat4 proj;
  506. uniform float scale;
  507.  
  508. void main()
  509. {
  510.     mat4 scaleMat = mat4(scale, 0.0, 0.0, 0.0, 0.0, scale, 0.0, 0.0, 0.0, 0.0, scale, 0.0, 0.0, 0.0, 0.0, 1.0);
  511.     vTexcoord = vec2(texcoord.x, 1.0 - texcoord.y);
  512.     gl_Position = proj*model*scaleMat*vec4(position.x, position.y, 0.0, 1.0);
  513. }
  514.  
  515.  
  516.  
  517. /// model.glfs ========================================================================================================================
  518. #version 330
  519.  
  520. out vec4 outColor;
  521. in vec2 vTexcoord;
  522. uniform sampler2D tex0;
  523.  
  524. void main()
  525. {
  526.     outColor = texture(tex0, vTexcoord);
  527. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement