Advertisement
czaffik

sdl kształty 3d

Jan 12th, 2018
522
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 46.15 KB | None | 0 0
  1. // main.cpp ==============================================================================================================
  2. #include "engine.h"
  3.  
  4. int main(int argc, char* args[])
  5. {
  6.     try
  7.     {
  8.         Engine* e = new Engine(800, 600, 1);
  9.  
  10.         e->init();
  11.         e->mainLoop();
  12.         e->close();
  13.         delete e;
  14.     }
  15.     catch(std::string &message)
  16.     {
  17.         std::cout << message << std::endl;
  18.         return -1;
  19.     }
  20.  
  21.     return 0;
  22. }
  23. // main.cpp ==============================================================================================================
  24.  
  25.  
  26. // engine.h ==============================================================================================================
  27. #ifndef ENGINE_H
  28. #define ENGINE_H
  29.  
  30. #include "scene.h"
  31.  
  32. class Engine
  33. {
  34.     public:
  35.         Engine(int _screenWidth, int _screenHeight, int _delay = 1);
  36.         virtual ~Engine();
  37.  
  38.         void init();
  39.         void mainLoop();
  40.         void close();
  41.  
  42.     protected:
  43.         void draw();
  44.         void animate(float dt);
  45.         void createWindow();
  46.         void setOpenGL();
  47.  
  48.         SDL_Window* window = nullptr;
  49.         SDL_GLContext glContext;
  50.         SDL_TimerID timerID;
  51.  
  52.         const int screenWidth;
  53.         const int screenHeight;
  54.         int delay;
  55.         float deltaTime = 0.0f;
  56.  
  57.         std::vector<std::unique_ptr<Scene> > scene;
  58.         unsigned int activeScene = 0;
  59.  
  60.     private:
  61. };
  62.  
  63. // engine.h ==============================================================================================================
  64.  
  65.  
  66. // engine.cpp ==============================================================================================================
  67. #include "engine.h"
  68. #include <sstream>
  69. #include <gl/gl.h>
  70. #include <SDL2/SDL_image.h>
  71. #include <SDL2/SDL_ttf.h>
  72.  
  73. Engine::Engine(int _screenWidth, int _screenHeight, int _delay)
  74.     : screenWidth(_screenWidth), screenHeight(_screenHeight), delay(_delay)
  75. {
  76.     deltaTime = static_cast<float>(delay)*0.001f;
  77. }
  78.  
  79. Engine::~Engine()
  80. {
  81.     //dtor
  82. }
  83.  
  84. void Engine::init()
  85. {
  86.     createWindow();
  87.     setOpenGL();
  88.  
  89.     glewExperimental = GL_TRUE;
  90.     glewInit();
  91.  
  92.     scene.push_back(std::make_unique<Scene>(screenWidth, screenHeight));
  93.     for (const auto & s : scene) s->init();
  94. }
  95.  
  96. void Engine::mainLoop()
  97. {
  98.     bool quit = false;
  99.     SDL_Event event;
  100.  
  101.     while (!quit)
  102.     {
  103.         while (SDL_PollEvent(&event) != 0)
  104.         {
  105.             if (event.type == SDL_QUIT)
  106.             {
  107.                 quit = true;
  108.             }
  109.             else if (event.type == SDL_USEREVENT)
  110.             {
  111.                 animate(deltaTime);
  112.             }
  113.             scene[activeScene]->eventLoop(event);
  114.         }
  115.  
  116.         draw();
  117.     }
  118. }
  119.  
  120. void Engine::close()
  121. {
  122.     SDL_GL_DeleteContext(glContext);
  123.     SDL_DestroyWindow(window);
  124.     window = nullptr;
  125.  
  126.     SDL_RemoveTimer(timerID);
  127.  
  128.     TTF_Quit();
  129.     IMG_Quit();
  130.     SDL_Quit();
  131. }
  132.  
  133. void Engine::draw()
  134. {
  135.     scene[activeScene]->draw();
  136.     SDL_GL_SwapWindow(window);
  137. }
  138.  
  139. void Engine::animate(float dt)
  140. {
  141.     scene[activeScene]->animate(dt);
  142. }
  143.  
  144. void Engine::createWindow()
  145. {
  146.     std::stringstream err;
  147.  
  148.     if( SDL_Init( SDL_INIT_EVERYTHING ) < 0 )
  149.     {
  150.         err << "Engine::init: Blad przy inicjalizacji SDL: " << SDL_GetError();
  151.         throw err.str();
  152.     }
  153.     if( !SDL_SetHint( SDL_HINT_RENDER_SCALE_QUALITY, "1" ) )
  154.     {
  155.         std::cout << "Engine::init: Filtrowanie liniowe nie zostalo wlaczone" << std::endl;
  156.     }
  157.  
  158.     SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
  159.     SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 5);
  160.     SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
  161.     SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
  162.     SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
  163.     SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
  164.     SDL_GL_SetAttribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, 1);
  165.  
  166.     window = SDL_CreateWindow("OpenGL", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, screenWidth,
  167.                               screenHeight, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);
  168.     if( window == NULL )
  169.     {
  170.         err << "Engine::init: Nie mozna utworzyc okna " << SDL_GetError();
  171.         throw err.str();
  172.     }
  173.  
  174.     glContext = SDL_GL_CreateContext(window);
  175.     timerID = SDL_AddTimer(delay, callback, (void*)"");
  176.  
  177.     int imgFlags = IMG_INIT_PNG;
  178.     if (!(IMG_Init(imgFlags) & imgFlags))
  179.     {
  180.         err << "Engine::init: SDL_image nie zostal zainicjowany: " << IMG_GetError();
  181.         throw err.str();
  182.     }
  183.  
  184.     if (TTF_Init() == -1)
  185.     {
  186.         err << "Engine::init: SDL_TTF nie zostal zainicjowany: " << TTF_GetError();
  187.         throw err.str();
  188.     }
  189. }
  190.  
  191. void Engine::setOpenGL()
  192. {
  193.     glEnable(GL_DEPTH_TEST);
  194.     glEnable(GL_FRAMEBUFFER_SRGB);
  195.     glEnable(GL_CULL_FACE);
  196.     glCullFace(GL_FRONT);
  197.     glFrontFace(GL_CW);
  198. }
  199.  
  200. Uint32 callback(Uint32 interval, void *param)
  201. {
  202.     SDL_Event event;
  203.     SDL_UserEvent userevent;
  204.  
  205.     userevent.type = SDL_USEREVENT;
  206.     userevent.code = 0;
  207.     userevent.data1 = NULL;
  208.     userevent.data2 = NULL;
  209.  
  210.     event.type = SDL_USEREVENT;
  211.     event.user = userevent;
  212.  
  213.     SDL_PushEvent(&event);
  214.     return(interval);
  215. }
  216. // engine.cpp ==============================================================================================================
  217.  
  218.  
  219. // scene.h ==============================================================================================================
  220. #ifndef SCENE_H
  221. #define SCENE_H
  222.  
  223. #include "program.h"
  224. #include "camera.h"
  225. #include "model.h"
  226. #include <memory>
  227. #include <vector>
  228. #include <iostream>
  229. #include <SDL2/SDL.h>
  230. #include "lightning.h"
  231.  
  232. class Scene
  233. {
  234.     public:
  235.         Scene(int _width, int _height);
  236.         virtual ~Scene();
  237.  
  238.         void init();
  239.         void draw();
  240.         void eventLoop(SDL_Event &event);
  241.         void animate(float dt);
  242.  
  243.     protected:
  244.         void loadSceneProgram(std::string vertName, std::string fragName, std::string geoName = "");
  245.         void loadModelProgram(std::string vertName, std::string fragName, std::string geoName = "");
  246.         void createFrameBuffer();
  247.         void createDrawSurface();
  248.         void drawSurface();
  249.  
  250.         int width;
  251.         int height;
  252.  
  253.         std::vector<std::shared_ptr<Program> > sceneProgram;
  254.         std::vector<std::shared_ptr<Program> > modelProgram;
  255.  
  256.         unsigned int activeSceneProgram = 0;
  257.         unsigned int activeModelProgram = 0;
  258.  
  259.         std::unique_ptr<Camera> camera;
  260.         std::vector<std::shared_ptr<Model> > model;
  261.         std::unique_ptr<Lightning> lightning;
  262.  
  263.         GLuint frameBuffer;
  264.         GLuint frameTex;
  265.         GLuint renderBuffer;
  266.  
  267.         GLuint surfaceVao;
  268.         GLuint surfaceVbo;
  269.         GLuint surfaceEbo;
  270.  
  271.         int x = 0, y = 0, old_x = 0, old_y = 0;
  272.         bool stop = false;
  273.  
  274.     private:
  275. };
  276.  
  277. #endif // SCENE_H
  278. // scene.h ==============================================================================================================
  279.  
  280.  
  281. // scene.cpp ==============================================================================================================
  282. #include "scene.h"
  283. #include <cmath>
  284. #include <glm/glm.hpp>
  285. #include <glm/gtc/matrix_transform.hpp>
  286. #include <glm/gtc/type_ptr.hpp>
  287.  
  288. Scene::Scene(int _width, int _height)
  289.     : width(_width), height(_height)
  290. {
  291.     //ctor
  292. }
  293.  
  294. Scene::~Scene()
  295. {
  296.     //dtor
  297. }
  298.  
  299. void Scene::init()
  300. {
  301.     loadSceneProgram("data/shaders/scene.glvs", "data/shaders/scene.glfs");
  302.     loadModelProgram("data/shaders/model.glvs", "data/shaders/model.glfs");
  303.  
  304.     activeModelProgram = 0;
  305.  
  306.     createFrameBuffer();
  307.     createDrawSurface();
  308.  
  309.     model.push_back(std::make_shared<Cube>());
  310.     //model.push_back(std::make_shared<Cone>());
  311.     model.push_back(std::make_shared<Mirror>());
  312.     model.push_back(std::make_shared<Mirror>());
  313.     model.push_back(std::make_shared<Mirror>());
  314.     model.push_back(std::make_shared<Mirror>());
  315.     model.push_back(std::make_shared<Mirror>());
  316.     model.push_back(std::make_shared<Mirror>());
  317.  
  318.     for (const auto &m: model) m->init(modelProgram[activeModelProgram]);
  319.  
  320.     camera = std::make_unique<Camera>(glm::vec3(0.0, 0.0, 10.0), glm::vec3(0.0, 0.0, 0.0), glm::vec3(0.0, 1.0, 0.0));
  321.     camera->setProgram(modelProgram[activeModelProgram]);
  322.  
  323.     lightning = std::make_unique<Lightning>(modelProgram[activeModelProgram]);
  324.     lightning->setAmbient(glm::vec3(0.0f, 0.0f, 0.0f));
  325.     lightning->addLight(glm::vec3(0.0f, 6.0f, 0.0f), glm::vec3(10.0f, 10.0f, 0.0f), 0.05f);
  326.     lightning->addLight(glm::vec3(0.0f, -6.0f, 0.0f), glm::vec3(10.0f, 10.0f, 0.0f), 0.05f);
  327.     lightning->addLight(glm::vec3(6.0f, 0.0f, 0.0f), glm::vec3(2.0f, 0.0f, 0.0f), 0.05f);
  328.     lightning->addLight(glm::vec3(-6.0f, 0.0f, 0.0f), glm::vec3(0.0f, 2.0f, 0.0f), 0.05f);
  329.     lightning->addLight(glm::vec3(0.0f, 0.0f, 6.0f), glm::vec3(0.0f, 0.0f, 2.0f), 0.05f);
  330.     lightning->addLight(glm::vec3(0.0f, 0.0f, -6.0f), glm::vec3(2.0f, 2.0f, 2.0f), 0.05f);
  331.  
  332.     glUseProgram(modelProgram[activeModelProgram]->getID());
  333.         glm::mat4 proj = glm::perspective(glm::radians(45.0f), 800.0f / 600.0f, 1.0f, 10000.0f);
  334.         glUniformMatrix4fv(modelProgram[activeModelProgram]->getUniform("proj"), 1, GL_FALSE, glm::value_ptr(proj));
  335.     glUseProgram(0);
  336.  
  337.     glUseProgram(sceneProgram[activeSceneProgram]->getID());
  338.         glUniform1f(sceneProgram[activeSceneProgram]->getUniform("gamma"), 0.95f);
  339.     glUseProgram(0);
  340.  
  341.     model[0]->setPosition(glm::vec3(0.0, 0.0, 0.0));
  342.     model[1]->setPosition(glm::vec3(0.0, 0.0, -4.0));
  343.     model[1]->setYaw(0.0f);
  344.     model[1]->setScale(4.0f);
  345.     model[2]->setPosition(glm::vec3(4.0, 0.0, 0.0));
  346.     model[2]->setYaw(-90.0f);
  347.     model[2]->setScale(4.0f);
  348.     model[3]->setPosition(glm::vec3(0.0, -4.0, 0.0));
  349.     model[3]->setPitch(-90.0f);
  350.     model[3]->setScale(4.0f);
  351.     model[4]->setPosition(glm::vec3(0.0, 4.0, 0.0));
  352.     model[4]->setPitch(90.0f);
  353.     model[4]->setScale(4.0f);
  354.     model[5]->setPosition(glm::vec3(0.0, 0.0, 4.0));
  355.     model[5]->setYaw(180.0f);
  356.     model[5]->setScale(4.0f);
  357.     model[6]->setPosition(glm::vec3(-4.0, 0.0, 0.0));
  358.     model[6]->setYaw(90.0f);
  359.     model[6]->setScale(4.0f);
  360.  
  361.     std::static_pointer_cast<Mirror>(model[1])->addMirroredModel(model[0]);
  362.     std::static_pointer_cast<Mirror>(model[2])->addMirroredModel(model[0]);
  363.     std::static_pointer_cast<Mirror>(model[3])->addMirroredModel(model[0]);
  364.     std::static_pointer_cast<Mirror>(model[4])->addMirroredModel(model[0]);
  365.     std::static_pointer_cast<Mirror>(model[5])->addMirroredModel(model[0]);
  366.     std::static_pointer_cast<Mirror>(model[6])->addMirroredModel(model[0]);
  367. }
  368.  
  369. void Scene::draw()
  370. {
  371.     glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
  372.     glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
  373.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  374.  
  375.     for(const auto &m : model) m->draw();
  376.  
  377.     drawSurface();
  378. }
  379.  
  380. void Scene::eventLoop(SDL_Event &event)
  381. {
  382.     if (event.type == SDL_KEYDOWN)
  383.     {
  384.         switch(event.key.keysym.sym)
  385.         {
  386.             case SDLK_SPACE:
  387.                 stop = !stop;
  388.                 break;
  389.             case SDLK_LEFT:
  390.                 model[0]->changeYaw(-10.0f);
  391.                 break;
  392.             case SDLK_RIGHT:
  393.                 model[0]->changeYaw(10.0f);
  394.                 break;
  395.             case SDLK_UP:
  396.                 model[0]->changePitch(10.0f);
  397.                 break;
  398.             case SDLK_DOWN:
  399.                 model[0]->changePitch(-10.0f);
  400.                 break;
  401.         }
  402.     }
  403.     else if (event.type == SDL_MOUSEMOTION)
  404.     {
  405.         SDL_GetMouseState(&x, &y);
  406.         if (event.button.button == 1)
  407.         {
  408.             camera->changeGamma(0.01f*(y - old_y));
  409.             camera->changeTeta(0.01f*(x - old_x));
  410.         }
  411.         else if (event.button.button == 4)
  412.         {
  413.             camera->changeLength(0.1f*(y - old_y));
  414.         }
  415.         old_x = x;
  416.         old_y = y;
  417.     }
  418. }
  419.  
  420. void Scene::animate(float dt)
  421. {
  422.     if (!stop) for(const auto &m : model) m->animate(dt);
  423. }
  424.  
  425. void Scene::loadSceneProgram(std::string vertName, std::string fragName, std::string geoName)
  426. {
  427.     sceneProgram.push_back(std::make_shared<Program>(vertName, fragName, geoName));
  428. }
  429.  
  430. void Scene::loadModelProgram(std::string vertName, std::string fragName, std::string geoName)
  431. {
  432.     modelProgram.push_back(std::make_shared<Program>(vertName, fragName, geoName));
  433. }
  434.  
  435. void Scene::createFrameBuffer()
  436. {
  437.     glGenFramebuffers(1, &frameBuffer);
  438.     glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
  439.  
  440.     glGenTextures(1, &frameTex);
  441.     glActiveTexture(GL_TEXTURE0);
  442.     glBindTexture(GL_TEXTURE_2D, frameTex);
  443.  
  444.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
  445.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
  446.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_NEAREST);
  447.  
  448.     glGenRenderbuffers(1, &renderBuffer);
  449.     glBindRenderbuffer(GL_RENDERBUFFER, renderBuffer);
  450.     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
  451.  
  452.     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderBuffer);
  453.     glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, frameTex, 0);
  454.  
  455.     GLuint attachments[2] = {GL_COLOR_ATTACHMENT0, GL_DEPTH_STENCIL_ATTACHMENT};
  456.     glDrawBuffers(1, attachments);
  457.  
  458.     GLenum e = glCheckFramebufferStatus(GL_FRAMEBUFFER);
  459.     switch (e)
  460.     {
  461.  
  462.         case GL_FRAMEBUFFER_UNDEFINED:
  463.             std::cout << "FBO Undefined\n";
  464.             break;
  465.         case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT :
  466.             std::cout << "FBO Incomplete Attachment\n";
  467.             break;
  468.         case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT :
  469.             std::cout << "FBO Missing Attachment\n";
  470.             break;
  471.         case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER :
  472.             std::cout << "FBO Incomplete Draw Buffer\n";
  473.             break;
  474.         case GL_FRAMEBUFFER_UNSUPPORTED :
  475.             std::cout << "FBO Unsupported\n";
  476.             break;
  477.     }
  478. }
  479.  
  480. void Scene::createDrawSurface()
  481. {
  482.     GLfloat vertices[] =
  483.     {
  484.         -1.0f,  1.0f,    0.0f, 1.0f,
  485.          1.0f,  1.0f,    1.0f, 1.0f,
  486.          1.0f, -1.0f,    1.0f, 0.0f,
  487.         -1.0f, -1.0f,    0.0f, 0.0f
  488.     };
  489.  
  490.     GLuint elements[] =
  491.     {
  492.         1, 3, 2,
  493.         1, 0, 3
  494.     };
  495.  
  496.     glGenVertexArrays(1, &surfaceVao);
  497.     glGenBuffers(1, &surfaceVbo);
  498.     glGenBuffers(1, &surfaceEbo);
  499.  
  500.     glBindVertexArray(surfaceVao);
  501.     glBindBuffer(GL_ARRAY_BUFFER, surfaceVbo);
  502.     glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
  503.  
  504.     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, surfaceEbo);
  505.     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW);
  506.  
  507.     GLint v1 = glGetAttribLocation(sceneProgram[activeSceneProgram]->getID(), "position");
  508.     glEnableVertexAttribArray(v1);
  509.     glVertexAttribPointer(v1, 2, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), 0);
  510.  
  511.     GLint v2 = glGetAttribLocation(sceneProgram[activeSceneProgram]->getID(), "texcoord");
  512.     glEnableVertexAttribArray(v2);
  513.     glVertexAttribPointer(v2, 2, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), (void*)(2*sizeof(GLfloat)));
  514. }
  515.  
  516. void Scene::drawSurface()
  517. {
  518.     glUseProgram(sceneProgram[activeSceneProgram]->getID());
  519.  
  520.     glBindFramebuffer(GL_FRAMEBUFFER, 0);
  521.  
  522.     glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
  523.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  524.  
  525.     glBindTexture(GL_TEXTURE_2D, frameBuffer);
  526.     glGenerateTextureMipmap(frameBuffer);
  527.  
  528.     glBindVertexArray(surfaceVao);
  529.     glActiveTexture(GL_TEXTURE0);
  530.     glBindTexture(GL_TEXTURE_2D, frameTex);
  531.  
  532.     glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
  533.  
  534.     glUseProgram(sceneProgram[activeSceneProgram]->getID());
  535. }
  536. // scene.cpp ==============================================================================================================
  537.  
  538.  
  539. // program.h ==============================================================================================================
  540. #ifndef PROGRAM_H
  541. #define PROGRAM_H
  542.  
  543. #include <gl/glew.h>
  544. #include <gl/gl.h>
  545. #include <string>
  546. #include <vector>
  547. #include <map>
  548.  
  549. class Program
  550. {
  551.     public:
  552.         Program(std::string _vertexName, std::string _fragmentName = "", std::string _geometryName = "",
  553.                 bool _is_framebuffer = false);
  554.         virtual ~Program();
  555.  
  556.         GLuint getID() const { return id; }
  557.         GLint getUniform(std::string name);
  558.  
  559.     protected:
  560.         void createShader(GLenum type, std::string fileName);
  561.         std::string loadFile(std::string fileName);
  562.  
  563.         bool is_framebuffer = false;
  564.  
  565.         GLuint id;
  566.         std::vector<GLuint> shader;
  567.         std::map<std::string, GLint> uniform;
  568.  
  569.     private:
  570. };
  571.  
  572. #endif // PROGRAM_H
  573. // program.h ==============================================================================================================
  574.  
  575.  
  576. // program.cpp ==============================================================================================================
  577. #include "program.h"
  578. #include <GL/gl.h>
  579. #include <fstream>
  580. #include <iostream>
  581. #include <sstream>
  582.  
  583. #include <glm/glm.hpp>
  584. #include <glm/gtc/matrix_transform.hpp>
  585. #include <glm/gtc/type_ptr.hpp>
  586.  
  587. Program::Program(std::string _vertexName, std::string _fragmentName, std::string _geometryName,
  588.                  bool _is_framebuffer)
  589.     : is_framebuffer(_is_framebuffer)
  590. {
  591.     id = glCreateProgram();
  592.     createShader(GL_VERTEX_SHADER, _vertexName);
  593.     if (!_fragmentName.empty()) createShader(GL_FRAGMENT_SHADER, _fragmentName);
  594.     if (!_geometryName.empty()) createShader(GL_GEOMETRY_SHADER, _geometryName);
  595.  
  596.     if (_fragmentName.empty())
  597.     {
  598.         const GLchar *feedback[] = {"outValue"};
  599.         glTransformFeedbackVaryings(id, 1, feedback, GL_INTERLEAVED_ATTRIBS);
  600.     }
  601.  
  602.     glLinkProgram(id);
  603.  
  604.     GLint programSuccess = GL_TRUE;
  605.     glGetProgramiv(id, GL_LINK_STATUS, &programSuccess);
  606.     if(programSuccess != GL_TRUE)
  607.     {
  608.         std::stringstream err;
  609.         err << "Nie mozna utworzyc programu: " << glGetError();
  610.         throw err.str();
  611.     }
  612.  
  613.     glBindFragDataLocation(id, 0, "outColor");
  614.  
  615.     glUseProgram(id);
  616.         if (!is_framebuffer)
  617.         {
  618.             glUniform1i(getUniform("tex1"), 0);
  619.             glUniform1i(getUniform("tex2"), 1);
  620.             glUniform1f(getUniform("scale"), 1.0f);
  621.             glUniform1f(getUniform("overlap"), 1.0f);
  622.         }
  623.         else
  624.             glUniform1i(getUniform("framebuffer"), 0);
  625.     glUseProgram(0);
  626. }
  627.  
  628. Program::~Program()
  629. {
  630.     for (const auto &s: shader) glDeleteShader(s);
  631.     glDeleteProgram(id);
  632. }
  633.  
  634. GLint Program::getUniform(std::string name)
  635. {
  636.     auto it = uniform.find(name);
  637.     if (it == uniform.end())
  638.     {
  639.         GLint value = glGetUniformLocation(id, name.c_str());
  640.         if (value != -1) uniform[name] = value;
  641.         else return -1;
  642.     }
  643.  
  644.     return uniform[name];
  645. }
  646.  
  647. void Program::createShader(GLenum type, std::string fileName)
  648. {
  649.     GLuint s;
  650.  
  651.     if      (type == GL_VERTEX_SHADER)   s = glCreateShader(GL_VERTEX_SHADER);
  652.     else if (type == GL_FRAGMENT_SHADER) s = glCreateShader(GL_FRAGMENT_SHADER);
  653.     else if (type == GL_GEOMETRY_SHADER) s = glCreateShader(GL_GEOMETRY_SHADER);
  654.  
  655.     const GLchar *source = loadFile(fileName).c_str();
  656.     glShaderSource(s, 1, &source, nullptr);
  657.     glCompileShader(s);
  658.  
  659.     GLint vShaderCompiled = GL_FALSE;
  660.     glGetShaderiv(s, GL_COMPILE_STATUS, &vShaderCompiled);
  661.     if (vShaderCompiled != GL_TRUE)
  662.     {
  663.         std::stringstream err;
  664.         err << "Nie mozna skompilowac shadera: " << fileName << ". Blad: " << glGetError();
  665.         throw err.str();
  666.     }
  667.     glAttachShader(id, s);
  668.     shader.push_back(s);
  669. }
  670.  
  671. std::string Program::loadFile(std::string fileName)
  672. {
  673.     std::fstream file;
  674.     file.open(fileName.c_str(), std::ios::in);
  675.  
  676.     std::stringstream buffer;
  677.     buffer << file.rdbuf();
  678.     std::string data(buffer.str());
  679.  
  680.     return data;
  681. }
  682. // program.cpp ==============================================================================================================
  683.  
  684.  
  685. // model.h ==============================================================================================================
  686. #ifndef MODEL_H
  687. #define MODEL_H
  688.  
  689. #include <GL/glew.h>
  690. #include <SDL2/SDL_opengl.h>
  691. #include <vector>
  692. #include <memory>
  693. #include <glm/glm.hpp>
  694. #include "program.h"
  695.  
  696. enum Type
  697. {
  698.     CUBE = 1,
  699.     MIRROR = 2,
  700.     CONE = 3
  701. };
  702.  
  703. //============================================================================================================
  704. // Model
  705. class Model
  706. {
  707.     public:
  708.         Model(Type _type, unsigned int vaoCount = 1, unsigned int vboCount = 1, unsigned int eboCount = 1,
  709.               unsigned int texCount = 1);
  710.         virtual ~Model();
  711.  
  712.         virtual void init(std::shared_ptr<Program> &_program) = 0;
  713.         void draw(bool is_reflect = false);
  714.         virtual void animate(float dt) = 0;
  715.  
  716.         virtual void setProgram(std::shared_ptr<Program> &_program) { program = _program; }
  717.  
  718.         void setPosition(glm::vec3 _position) { position = _position; }
  719.         void changePosition(glm::vec3 _dp) { position += _dp; }
  720.         glm::vec3 getPosition() const { return position; }
  721.  
  722.         void setPitch(float _pitch) { pitch = _pitch; }
  723.         void changePitch(float dp) { pitch += dp; }
  724.         float getPitch() const { return pitch; }
  725.  
  726.         void setYaw(float _yaw) { yaw = _yaw; }
  727.         void changeYaw(float dy) { yaw += dy; }
  728.         float getYaw() const { return yaw; }
  729.  
  730.         void setRoll(float _roll) { roll = _roll; }
  731.         void changeRoll(float dr) { roll += dr; }
  732.         float getRoll() const { return roll; }
  733.  
  734.         void setScale(float _scale) { scale = _scale; }
  735.         void changeScale(float _ds) { scale += _ds; }
  736.         float getScale() const { return scale; }
  737.  
  738.         Type getType() const { return type; }
  739.  
  740.         void setMatrix(glm::mat4 _matrix) { matrix = _matrix; }
  741.         void changeMatrix(glm::mat4 _matrix);
  742.         glm::mat4 getMatrix() const { return matrix; }
  743.  
  744.     protected:
  745.         virtual void setAttrib() = 0;
  746.         virtual void drawModel() = 0;
  747.  
  748.         std::vector<GLuint> vao;
  749.         std::vector<GLuint> vbo;
  750.         std::vector<GLuint> ebo;
  751.         std::vector<GLuint> tex;
  752.  
  753.         std::shared_ptr<Program> program;
  754.  
  755.         glm::vec3 position;
  756.         float pitch = 0.0f;
  757.         float yaw   = 0.0f;
  758.         float roll  = 0.0f;
  759.         float scale = 1.0f;
  760.  
  761.         glm::mat4 matrix;
  762.  
  763.         glm::vec3 ambient;
  764.         glm::vec3 diffuse;
  765.         glm::vec3 specular;
  766.         float shininess;
  767.         glm::vec3 emission;
  768.  
  769.     private:
  770.         Type type;
  771. };
  772.  
  773. //============================================================================================================
  774. // Cube
  775. class Cube: public Model
  776. {
  777.     public:
  778.         Cube();
  779.         ~Cube();
  780.  
  781.         void init(std::shared_ptr<Program> &_program);
  782.         void animate(float dt);
  783.  
  784.     protected:
  785.         void setAttrib();
  786.         void drawModel();
  787.  
  788.     private:
  789. };
  790.  
  791. //============================================================================================================
  792. // Mirror
  793. class Mirror: public Model
  794. {
  795.     public:
  796.         Mirror();
  797.         ~Mirror();
  798.  
  799.         void init(std::shared_ptr<Program> &_program);
  800.         void animate(float dt);
  801.  
  802.         void setProgram(std::shared_ptr<Program> &_program);
  803.  
  804.         void addMirroredModel(std::shared_ptr<Model> &_model);
  805.         void removeMirroredModel(std::shared_ptr<Model> &_model);
  806.  
  807.     protected:
  808.         void setAttrib();
  809.         void drawModel();
  810.  
  811.         std::vector<std::shared_ptr<Model> > model;
  812.  
  813.     private:
  814. };
  815.  
  816. //============================================================================================================
  817. // Cone
  818. class Cone: public Model
  819. {
  820.     public:
  821.         Cone();
  822.         ~Cone();
  823.  
  824.         void init(std::shared_ptr<Program> &_program);
  825.         void animate(float dt);
  826.  
  827.     protected:
  828.         void setAttrib();
  829.         void drawModel();
  830.  
  831.     private:
  832. };
  833.  
  834. #endif // MODEL_H
  835. // model.h ==============================================================================================================
  836.  
  837.  
  838. // model.cpp ==============================================================================================================
  839. #include "model.h"
  840. #include <GL/gl.h>
  841. #include <SDL2/SDL_image.h>
  842. #include <string>
  843. #include <sstream>
  844. #include <iostream>
  845. #include <algorithm>
  846. #include <cmath>
  847. #include <glm/gtc/matrix_transform.hpp>
  848. #include <glm/gtc/type_ptr.hpp>
  849. #include <fstream>
  850.  
  851. //============================================================================================================
  852. // Model
  853. Model::Model(Type _type, unsigned int vaoCount, unsigned int vboCount, unsigned int eboCount, unsigned int texCount)
  854.     : type(_type)
  855. {
  856.     vao.resize(vaoCount);
  857.     vbo.resize(vboCount);
  858.     ebo.resize(eboCount);
  859.     tex.resize(texCount);
  860.  
  861.     glGenVertexArrays(vao.size(), vao.data());
  862.     glGenBuffers(vbo.size(), vbo.data());
  863.     glGenBuffers(ebo.size(), ebo.data());
  864.     glGenTextures(tex.size(), tex.data());
  865. }
  866.  
  867. Model::~Model()
  868. {
  869.     glDeleteBuffers(ebo.size(), ebo.data());
  870.     glDeleteBuffers(vbo.size(), vbo.data());
  871.     glDeleteVertexArrays(vao.size(), vao.data());
  872.     glDeleteTextures(tex.size(), tex.data());
  873. }
  874.  
  875. void Model::draw(bool is_reflect)
  876. {
  877.     glUseProgram(program->getID());
  878.         matrix = glm::translate(matrix, position);
  879.         matrix = glm::rotate(matrix, glm::radians(pitch), glm::vec3(1, 0, 0));
  880.         matrix = glm::rotate(matrix, glm::radians(yaw), glm::vec3(0, 1, 0));
  881.         matrix = glm::rotate(matrix, glm::radians(roll), glm::vec3(0, 0, 1));
  882.         glUniform1f(program->getUniform("scale"), scale);
  883.         glUniformMatrix4fv(program->getUniform("model"), 1, GL_FALSE, glm::value_ptr(matrix));
  884.  
  885.         glUniform4f(program->getUniform("ambient"), ambient.r, ambient.g, ambient.b, 1.0);
  886.         glUniform4f(program->getUniform("diffuse"), diffuse.r, diffuse.g, diffuse.b, 1.0);
  887.         glUniform4f(program->getUniform("specular"), specular.r, specular.g, specular.b, 1.0);
  888.         glUniform1f(program->getUniform("shininess"), shininess);
  889.         glUniform4f(program->getUniform("emission"), emission.r, emission.g, emission.b, 1.0);
  890.  
  891.         if (is_reflect)
  892.         {
  893.             changeMatrix(glm::scale(getMatrix(), glm::vec3(1.0f, -1.0f, 1.0f)));
  894.             glUniform4f(program->getUniform("ambient"), 0.1, 0.1, 0.1, 1.0);
  895.             glUniform4f(program->getUniform("diffuse"), 0.2, 0.2, 0.2, 1.0);
  896.         }
  897.  
  898.         setAttrib();
  899.         drawModel();
  900.         matrix = glm::mat4();
  901.     glUseProgram(0);
  902. }
  903.  
  904. void Model::changeMatrix(glm::mat4 _matrix)
  905. {
  906.     matrix = _matrix;
  907.     glUniformMatrix4fv(program->getUniform("model"), 1, GL_FALSE, glm::value_ptr(matrix));
  908. }
  909.  
  910. //============================================================================================================
  911. // Cube
  912. Cube::Cube()
  913.     : Model(CUBE, 1, 1, 1, 2)
  914. {
  915.     ambient = glm::vec3(0.3, 0.3, 0.3);
  916.     diffuse = glm::vec3(0.4, 0.4, 0.4);
  917.     specular = glm::vec3(0.3, 0.3, 0.3);
  918.     shininess = 12;
  919.     emission = glm::vec3(0.0, 0.0, 0.0);
  920. }
  921.  
  922. Cube::~Cube()
  923. {
  924.  
  925. }
  926.  
  927. void Cube::init(std::shared_ptr<Program> &_program)
  928. {
  929.     program = _program;
  930.     glBindVertexArray(vao[0]);
  931.  
  932.     GLfloat vertices[] =
  933.     {
  934.          1.0,  1.0,  1.0,     1.0,  1.0,  1.0,    1.0, 0.0,  // 0
  935.         -1.0,  1.0,  1.0,    -1.0,  1.0,  1.0,    0.0, 0.0,  // 1
  936.         -1.0, -1.0,  1.0,    -1.0, -1.0,  1.0,    0.0, 1.0,  // 2
  937.          1.0, -1.0,  1.0,     1.0, -1.0,  1.0,    1.0, 1.0,  // 3
  938.          1.0, -1.0, -1.0,     1.0, -1.0, -1.0,    0.0, 1.0,  // 4
  939.         -1.0, -1.0, -1.0,    -1.0, -1.0, -1.0,    1.0, 1.0,  // 5
  940.         -1.0,  1.0, -1.0,    -1.0,  1.0, -1.0,    1.0, 0.0,  // 6
  941.          1.0,  1.0, -1.0,     1.0,  1.0, -1.0,    0.0, 0.0,  // 7
  942.     };
  943.     glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
  944.     glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
  945.  
  946.     GLuint elements[] =
  947.     {
  948.         0, 1, 2,
  949.         0, 2, 3,
  950.         5, 6, 4,
  951.         4, 6, 7,
  952.         4, 0, 3,
  953.         4, 7, 0,
  954.         5, 2, 1,
  955.         5, 1, 6,
  956.         0, 6, 1,
  957.         0, 7, 6,
  958.         2, 5, 3,
  959.         5, 4, 3,
  960.     };
  961.  
  962.     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo[0]);
  963.     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW);
  964.  
  965.     SDL_Surface *img;
  966.     std::string file;
  967.  
  968.     glActiveTexture(GL_TEXTURE0);
  969.     glBindTexture(GL_TEXTURE_2D, tex[0]);
  970.     file = "data/textures/tex1.png";
  971.     img = IMG_Load(file.c_str());
  972.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img->w, img->h, 0, GL_RGB, GL_UNSIGNED_BYTE, img->pixels);
  973.     SDL_FreeSurface(img);
  974.  
  975.     glGenerateMipmap(GL_TEXTURE_2D);
  976.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
  977.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_NEAREST);
  978.  
  979.     glActiveTexture(GL_TEXTURE1);
  980.     glBindTexture(GL_TEXTURE_2D, tex[1]);
  981.     file = "data/textures/tex2.png";
  982.     img = IMG_Load(file.c_str());
  983.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img->w, img->h, 0, GL_RGB, GL_UNSIGNED_BYTE,
  984.                  img->pixels);
  985.     SDL_FreeSurface(img);
  986.  
  987.     glGenerateMipmap(GL_TEXTURE_2D);
  988.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
  989.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_NEAREST);
  990. }
  991.  
  992. void Cube::animate(float dt)
  993. {
  994.  
  995. }
  996.  
  997. void Cube::setAttrib()
  998. {
  999.     glBindVertexArray(vao[0]);
  1000.     glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
  1001.  
  1002.     GLint value1 = glGetAttribLocation(program->getID(), "position");
  1003.     glEnableVertexAttribArray(value1);
  1004.     glVertexAttribPointer(value1, 3, GL_FLOAT, GL_FALSE, 8*sizeof(GLfloat), 0);
  1005.  
  1006.     GLint value2 = glGetAttribLocation(program->getID(), "normal");
  1007.     glEnableVertexAttribArray(value2);
  1008.     glVertexAttribPointer(value2, 3, GL_FLOAT, GL_FALSE, 8*sizeof(GLfloat), (void*)(3*sizeof(GLfloat)));
  1009.  
  1010.     GLint value3 = glGetAttribLocation(program->getID(), "texcoord");
  1011.     glEnableVertexAttribArray(value3);
  1012.     glVertexAttribPointer(value3, 2, GL_FLOAT, GL_FALSE, 8*sizeof(float), (void*)(6*sizeof(float)));
  1013. }
  1014.  
  1015. void Cube::drawModel()
  1016. {
  1017.     glBindVertexArray(vao[0]);
  1018.     glActiveTexture(GL_TEXTURE0);
  1019.     glBindTexture(GL_TEXTURE_2D, tex[0]);
  1020.     glActiveTexture(GL_TEXTURE1);
  1021.     glBindTexture(GL_TEXTURE_2D, tex[1]);
  1022.     glDrawElements(GL_TRIANGLES, 3*12, GL_UNSIGNED_INT, 0);
  1023. }
  1024.  
  1025. //============================================================================================================
  1026. // Mirror
  1027. Mirror::Mirror()
  1028.     : Model(MIRROR, 1, 1, 1, 2)
  1029. {
  1030.     ambient = glm::vec3(0.1, 0.1, 0.1);
  1031.     diffuse = glm::vec3(0.5, 0.5, 0.5);
  1032.     specular = glm::vec3(0.8, 0.8, 0.8);
  1033.     shininess = 52;
  1034.     emission = glm::vec3(0.2, 0.2, 0.2);
  1035. }
  1036.  
  1037. Mirror::~Mirror()
  1038. {
  1039.  
  1040. }
  1041.  
  1042. void Mirror::init(std::shared_ptr<Program> &_program)
  1043. {
  1044.     program = _program;
  1045.     glBindVertexArray(vao[0]);
  1046.     glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
  1047.  
  1048.     GLfloat vertices[] =
  1049.     {
  1050.         -1.0,  1.0,  0.0,    0.0, 0.0, 1.0,    0.0, 1.0,  // 0
  1051.          1.0,  1.0,  0.0,    0.0, 0.0, 1.0,    1.0, 1.0,  // 1
  1052.          1.0, -1.0,  0.0,    0.0, 0.0, 1.0,    1.0, 0.0,  // 2
  1053.         -1.0, -1.0,  0.0,    0.0, 0.0, 1.0,    0.0, 0.0,  // 3
  1054.     };
  1055.     glBufferData(GL_ARRAY_BUFFER, 32*sizeof(GLfloat), vertices, GL_STATIC_DRAW);
  1056.  
  1057.     GLint elements[] =
  1058.     {
  1059.         1, 3, 2,
  1060.         1, 0, 3
  1061.     };
  1062.     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo[0]);
  1063.     glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6*sizeof(GLint), elements, GL_STATIC_DRAW);
  1064.  
  1065.     SDL_Surface *img;
  1066.     std::string file;
  1067.  
  1068.     glActiveTexture(GL_TEXTURE0);
  1069.     glBindTexture(GL_TEXTURE_2D, tex[0]);
  1070.     file = "data/textures/tex3.png";
  1071.     img = IMG_Load(file.c_str());
  1072.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img->w, img->h, 0, GL_RGB, GL_UNSIGNED_BYTE, img->pixels);
  1073.     SDL_FreeSurface(img);
  1074.     glGenerateMipmap(GL_TEXTURE_2D);
  1075.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
  1076.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_NEAREST);
  1077.  
  1078.     glActiveTexture(GL_TEXTURE1);
  1079.     glBindTexture(GL_TEXTURE_2D, tex[1]);
  1080.     file = "data/textures/tex4.png";
  1081.     img = IMG_Load(file.c_str());
  1082.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img->w, img->h, 0, GL_RGB, GL_UNSIGNED_BYTE, img->pixels);
  1083.     SDL_FreeSurface(img);
  1084.     glGenerateMipmap(GL_TEXTURE_2D);
  1085.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
  1086.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_NEAREST);
  1087. }
  1088.  
  1089. void Mirror::animate(float dt)
  1090. {
  1091.  
  1092. }
  1093.  
  1094. void Mirror::setAttrib()
  1095. {
  1096.     glBindVertexArray(vao[0]);
  1097.     glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
  1098.  
  1099.     GLint value1 = glGetAttribLocation(program->getID(), "position");
  1100.     glEnableVertexAttribArray(value1);
  1101.     glVertexAttribPointer(value1, 3, GL_FLOAT, GL_FALSE, 8*sizeof(GLfloat), 0);
  1102.  
  1103.     GLint value2 = glGetAttribLocation(program->getID(), "normal");
  1104.     glEnableVertexAttribArray(value2);
  1105.     glVertexAttribPointer(value2, 3, GL_FLOAT, GL_FALSE, 8*sizeof(GLfloat), (void*)(3*sizeof(GLfloat)));
  1106.  
  1107.     GLint value3 = glGetAttribLocation(program->getID(), "texcoord");
  1108.     glEnableVertexAttribArray(value3);
  1109.     glVertexAttribPointer(value3, 2, GL_FLOAT, GL_FALSE, 8*sizeof(float), (void*)(6*sizeof(float)));
  1110. }
  1111.  
  1112. void Mirror::drawModel()
  1113. {
  1114.     glClear(GL_STENCIL_BUFFER_BIT);
  1115.     glEnable(GL_STENCIL_TEST);
  1116.  
  1117.     glStencilFunc(GL_ALWAYS, 1, 1);
  1118.     glStencilOp(GL_ZERO, GL_ZERO, GL_REPLACE);
  1119.     glStencilMask(1);
  1120.     glDepthMask(GL_FALSE);
  1121.  
  1122.     glBindVertexArray(vao[0]);
  1123.     glActiveTexture(GL_TEXTURE0);
  1124.     glBindTexture(GL_TEXTURE_2D, tex[0]);
  1125.     glActiveTexture(GL_TEXTURE1);
  1126.     glBindTexture(GL_TEXTURE_2D, tex[1]);
  1127.     glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
  1128.  
  1129.     glDepthMask(GL_TRUE);
  1130.     glStencilFunc(GL_EQUAL, 1, 1);
  1131.  
  1132.     for (const auto &m: model)
  1133.     {
  1134.         glm::vec3 p = position - m->getPosition();
  1135.         float lenp = std::sqrt(p.x*p.x + p.y*p.y + p.z*p.z);
  1136.         glm::vec3 n = glm::vec3(sin(glm::radians(getYaw())*cos(glm::radians(getPitch()))),
  1137.                                 sin(glm::radians(getPitch())),
  1138.                                 cos(glm::radians(getYaw()))*cos(glm::radians(getPitch())));
  1139.  
  1140.         float dot = p.x*n.x + p.y*n.y + p.z*n.z;
  1141.         glm::vec3 d = dot*n;
  1142.  
  1143.         float alfa = acos(std::fabs(dot)/lenp);
  1144.  
  1145.         m->changeMatrix(glm::translate(m->getMatrix(), 2.0f*d));
  1146.         m->changeMatrix(glm::rotate(m->getMatrix(), glm::radians(180.0f) - 2.0f*alfa, glm::vec3(
  1147.                                      sin(glm::radians(getYaw()))*cos(glm::radians(getPitch())),
  1148.                                      sin(glm::radians(getPitch())),
  1149.                                      cos(glm::radians(getYaw()))*cos(glm::radians(getPitch()))
  1150.                                      )));
  1151.  
  1152.         glDisable(GL_CULL_FACE);
  1153.         m->draw(true);
  1154.         glEnable(GL_CULL_FACE);
  1155.     }
  1156.  
  1157.     glDisable(GL_STENCIL_TEST);
  1158. }
  1159.  
  1160. void Mirror::setProgram(std::shared_ptr<Program> &_program)
  1161. {
  1162.     program = _program;
  1163.     for (const auto &m: model) m->setProgram(_program);
  1164. }
  1165.  
  1166. void Mirror::addMirroredModel(std::shared_ptr<Model> &_model)
  1167. {
  1168.     model.push_back(_model);
  1169. }
  1170.  
  1171. void Mirror::removeMirroredModel(std::shared_ptr<Model> &_model)
  1172. {
  1173.     auto it = std::find(model.begin(), model.end(), _model);
  1174.     if (it != model.end()) model.erase(it);
  1175. }
  1176.  
  1177. //============================================================================================================
  1178. // Cone
  1179. Cone::Cone()
  1180.     : Model(CONE, 1, 1, 1, 2)
  1181. {
  1182.     ambient = glm::vec3(0.3, 0.3, 0.3);
  1183.     diffuse = glm::vec3(0.4, 0.4, 0.4);
  1184.     specular = glm::vec3(0.3, 0.3, 0.3);
  1185.     shininess = 12;
  1186.     emission = glm::vec3(0.0, 0.0, 0.0);
  1187. }
  1188. Cone::~Cone()
  1189. {
  1190.  
  1191. }
  1192.  
  1193. void Cone::init(std::shared_ptr<Program> &_program)
  1194. {
  1195.     program = _program;
  1196.     glBindVertexArray(vao[0]);
  1197.     glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
  1198.  
  1199.     GLfloat vertices[] =
  1200.     {
  1201.         // vertices        // normal        // texcoord
  1202.         1.0, -1.0,  1.0,   -1.0, -1.0,  1.0,   0.0, 0.0,  // 0
  1203.         1.0, -1.0, -1.0,    1.0, -1.0, -1.0,   1.0, 1.0,  // 2
  1204.         1.0, -1.0,  1.0,    1.0, -1.0,  1.0,   0.0, 1.0,  // 1
  1205.  
  1206.        -1.0, -1.0,  1.0,   -1.0, -1.0,  1.0,   0.0, 0.0,  // 0
  1207.        -1.0, -1.0, -1.0,   -1.0, -1.0, -1.0,   1.0, 0.0,  // 3
  1208.         1.0, -1.0, -1.0,    1.0, -1.0, -1.0,   1.0, 1.0,  // 2
  1209.  
  1210.         1.0, -1.0,  1.0,    1.0, -1.0,  1.0,   1.0, 0.0,  // 1
  1211.         0.0,  1.0,  0.0,    0.0,  1.0,  1.0,   0.5, 0.5,  // 4
  1212.        -1.0, -1.0,  1.0,   -1.0, -1.0,  1.0,   0.0, 0.0,  // 0
  1213.  
  1214.         1.0, -1.0,  1.0,    1.0, -1.0,  1.0,   0.0, 0.0,  // 1
  1215.         1.0, -1.0, -1.0,    1.0, -1.0, -1.0,   1.0, 0.0,  // 2
  1216.         0.0,  1.0,  0.0,    0.0,  1.0,  0.0,   0.5, 0.5,  // 4
  1217.  
  1218.         0.0,  1.0,  0.0,    0.0,  1.0,  0.0,   0.5, 0.5,  // 4
  1219.         1.0, -1.0, -1.0,    1.0, -1.0, -1.0,   0.0, 0.0,  // 2
  1220.        -1.0, -1.0, -1.0,   -1.0, -1.0, -1.0,   1.0, 0.0,  // 3
  1221.  
  1222.        -1.0, -1.0,  1.0,   -1.0, -1.0,  1.0,   1.0, 0.0,  // 0
  1223.         0.0,  1.0,  0.0,    0.0,  1.0,  0.0,   0.5, 0.5,  // 4
  1224.        -1.0, -1.0, -1.0,   -1.0, -1.0, -1.0,   0.0, 0.0   // 3
  1225.     };
  1226.  
  1227.     glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
  1228.  
  1229.     glActiveTexture(GL_TEXTURE0);
  1230.     glBindTexture(GL_TEXTURE_2D, tex[0]);
  1231.  
  1232.     SDL_Surface *img = IMG_Load("data/textures/tex1.png");
  1233.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img->w, img->h, 0, GL_RGB, GL_UNSIGNED_BYTE, img->pixels);
  1234.     SDL_FreeSurface(img);
  1235.  
  1236.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  1237.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  1238.  
  1239.     glActiveTexture(GL_TEXTURE1);
  1240.     glBindTexture(GL_TEXTURE_2D, tex[1]);
  1241.  
  1242.     img = IMG_Load("data/textures/tex4.png");
  1243.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img->w, img->h, 0, GL_RGB, GL_UNSIGNED_BYTE, img->pixels);
  1244.     SDL_FreeSurface(img);
  1245.  
  1246.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  1247.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  1248. }
  1249.  
  1250. void Cone::animate(float dt)
  1251. {
  1252.  
  1253. }
  1254.  
  1255. void Cone::setAttrib()
  1256. {
  1257.     glBindVertexArray(vao[0]);
  1258.     glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
  1259.  
  1260.     GLint value1 = glGetAttribLocation(program->getID(), "position");
  1261.     glEnableVertexAttribArray(value1);
  1262.     glVertexAttribPointer(value1, 3, GL_FLOAT, GL_FALSE, 8*sizeof(GLfloat), 0);
  1263.  
  1264.     GLint value2 = glGetAttribLocation(program->getID(), "normal");
  1265.     glEnableVertexAttribArray(value2);
  1266.     glVertexAttribPointer(value2, 3, GL_FLOAT, GL_FALSE, 8*sizeof(GLfloat), (void*)(3*sizeof(GLfloat)));
  1267.  
  1268.     GLint value3 = glGetAttribLocation(program->getID(), "texcoord");
  1269.     glEnableVertexAttribArray(value3);
  1270.     glVertexAttribPointer(value3, 2, GL_FLOAT, GL_FALSE, 8*sizeof(float), (void*)(6*sizeof(float)));
  1271. }
  1272.  
  1273. void Cone::drawModel()
  1274. {
  1275.     glBindVertexArray(vao[0]);
  1276.     glActiveTexture(GL_TEXTURE0);
  1277.     glBindTexture(GL_TEXTURE_2D, tex[0]);
  1278.     glDrawArrays(GL_TRIANGLES, 0, 18);
  1279. }
  1280. // model.cpp ==============================================================================================================
  1281.  
  1282.  
  1283.  
  1284. // camera.h ==============================================================================================================
  1285. #ifndef CAMERA_H
  1286. #define CAMERA_H
  1287.  
  1288. #include <glm/glm.hpp>
  1289. #include <memory>
  1290. #include "program.h"
  1291.  
  1292. class Camera
  1293. {
  1294.     public:
  1295.         Camera(glm::vec3 _pos, glm::vec3 _dir, glm::vec3 _up);
  1296.         virtual ~Camera();
  1297.  
  1298.         void setProgram(std::shared_ptr<Program> &_program);
  1299.  
  1300.         void setPos(glm::vec3 _pos);
  1301.         void changePos(glm::vec3 _dp);
  1302.         glm::vec3 getPos() const { return pos; }
  1303.  
  1304.         void setDir(glm::vec3 _dir);
  1305.         void changeDir(glm::vec3 _dd);
  1306.         glm::vec3 getDir() const { return dir; }
  1307.  
  1308.         void setUp(glm::vec3 _up);
  1309.         void changeUp(glm::vec3 _du);
  1310.         glm::vec3 getUp() const { return up; }
  1311.  
  1312.         void setGamma(float _gamma);
  1313.         void changeGamma(float _dg);
  1314.         float getGamma() const { return gamma; }
  1315.  
  1316.         void setTeta(float _teta);
  1317.         void changeTeta(float _dt);
  1318.         float getTeta() const { return teta; }
  1319.  
  1320.         void setLength(float _length);
  1321.         void changeLength(float _dl);
  1322.         float getLength() const { return length; }
  1323.  
  1324.     protected:
  1325.         void update();
  1326.  
  1327.         glm::vec3 pos;
  1328.         glm::vec3 dir;
  1329.         glm::vec3 up;
  1330.  
  1331.         float gamma;
  1332.         float teta;
  1333.         float length;
  1334.  
  1335.     private:
  1336.         std::shared_ptr<Program> program;
  1337. };
  1338.  
  1339. #endif // CAMERA_H
  1340. // camera.h ==============================================================================================================
  1341.  
  1342.  
  1343. // camera.cpp ==============================================================================================================
  1344. #include "camera.h"
  1345. #include <glm/gtc/matrix_transform.hpp>
  1346. #include <glm/gtc/type_ptr.hpp>
  1347. #include <cmath>
  1348.  
  1349. Camera::Camera(glm::vec3 _pos, glm::vec3 _dir, glm::vec3 _up)
  1350.     : pos(_pos), dir(_dir), up(_up)
  1351. {
  1352.     length = std::sqrt(pos.x*pos.x + pos.y*pos.y + pos.z*pos.z);
  1353.     gamma = asin(pos.y/length);
  1354.     teta = acos(pos.x/(length*cos(gamma)));
  1355. }
  1356.  
  1357. Camera::~Camera()
  1358. {
  1359.     //dtor
  1360. }
  1361.  
  1362. void Camera::setProgram(std::shared_ptr<Program> &_program)
  1363. {
  1364.     program = _program;
  1365.     update();
  1366. }
  1367.  
  1368. void Camera::setPos(glm::vec3 _pos)
  1369. {
  1370.     pos = _pos;
  1371.     length = std::sqrt(pos.x*pos.x + pos.y*pos.y + pos.z*pos.z);
  1372.     update();
  1373. }
  1374.  
  1375. void Camera::changePos(glm::vec3 _dp)
  1376. {
  1377.     pos += _dp;
  1378.     setPos(pos);
  1379.     update();
  1380. }
  1381.  
  1382. void Camera::setDir(glm::vec3 _dir)
  1383. {
  1384.     dir = _dir;
  1385.     update();
  1386. }
  1387.  
  1388. void Camera::changeDir(glm::vec3 _dd)
  1389. {
  1390.     dir +=  _dd;
  1391.     update();
  1392. }
  1393.  
  1394. void Camera::setUp(glm::vec3 _up)
  1395. {
  1396.     up = _up;
  1397.     update();
  1398. }
  1399.  
  1400. void Camera::changeUp(glm::vec3 _du)
  1401. {
  1402.     up += _du;
  1403.     update();
  1404. }
  1405.  
  1406. void Camera::setGamma(float _gamma)
  1407. {
  1408.     gamma = _gamma;
  1409.     if (gamma > 1.5707963f) gamma = 1.5707963f;
  1410.     else if (gamma < -1.5707963f) gamma = -1.5707963f;
  1411.  
  1412.     pos.x = length*cos(gamma)*cos(teta);
  1413.     pos.y = length*sin(gamma);
  1414.     pos.z = length*cos(gamma)*sin(teta);
  1415.     update();
  1416. }
  1417.  
  1418. void Camera::changeGamma(float _dg)
  1419. {
  1420.     gamma += _dg;
  1421.     setGamma(gamma);
  1422. }
  1423.  
  1424. void Camera::setTeta(float _teta)
  1425. {
  1426.     teta = _teta;
  1427.     if (teta > 6.2831853f) teta = 0.0f;
  1428.     else if (teta < 0.0f) teta = 6.2831853f;
  1429.  
  1430.     pos.x = length*cos(gamma)*cos(teta);
  1431.     pos.y = length*sin(gamma);
  1432.     pos.z = length*cos(gamma)*sin(teta);
  1433.     update();
  1434. }
  1435.  
  1436. void Camera::changeTeta(float _dt)
  1437. {
  1438.     teta += _dt;
  1439.     setTeta(teta);
  1440. }
  1441.  
  1442. void Camera::setLength(float _length)
  1443. {
  1444.     length = _length;
  1445.     pos.x = length*cos(gamma)*cos(teta);
  1446.     pos.y = length*sin(gamma);
  1447.     pos.z = length*cos(gamma)*sin(teta);
  1448.     update();
  1449. }
  1450.  
  1451. void Camera::changeLength(float _dl)
  1452. {
  1453.     length += _dl;
  1454.     setLength(length);
  1455. }
  1456.  
  1457. void Camera::update()
  1458. {
  1459.     glUseProgram(program->getID());
  1460.         glm::mat4 view;
  1461.         view = glm::lookAt(pos, dir, up);
  1462.         glUniformMatrix4fv(program->getUniform("view"), 1, GL_FALSE, glm::value_ptr(view));
  1463.     glUseProgram(0);
  1464. }
  1465. // camera.cpp ==============================================================================================================
  1466.  
  1467.  
  1468. // lightning.h ==============================================================================================================
  1469. #ifndef LIGHTNING_H
  1470. #define LIGHTNING_H
  1471.  
  1472. #include <program.h>
  1473. #include <glm/glm.hpp>
  1474. #include <memory>
  1475.  
  1476. class Lightning
  1477. {
  1478.     public:
  1479.         Lightning(std::shared_ptr<Program> _program);
  1480.         virtual ~Lightning();
  1481.  
  1482.         void setAmbient(glm::vec3 _ambient);
  1483.         void addLight(glm::vec3 _position, glm::vec3 _color, float _attenuation = 1.0f);
  1484.         void removeLight(unsigned int number);
  1485.  
  1486.         unsigned int getLightsCount() const { return lightsCount; }
  1487.  
  1488.     protected:
  1489.         void update();
  1490.  
  1491.         std::shared_ptr<Program> program;
  1492.         unsigned int lightsCount = 0;
  1493.  
  1494.         const unsigned int maxLightsCount = 20;
  1495.  
  1496.         glm::vec3 ambient;
  1497.         std::vector<float> position;
  1498.         std::vector<float> color;
  1499.         std::vector<float> attenuation;
  1500.  
  1501.     private:
  1502. };
  1503.  
  1504. #endif // LIGHTNING_H
  1505. // lightning.h ==============================================================================================================
  1506.  
  1507.  
  1508. // lightning.cpp ==============================================================================================================
  1509. #include "lightning.h"
  1510. #include <iostream>
  1511.  
  1512. Lightning::Lightning(std::shared_ptr<Program> _program)
  1513.     : program(_program)
  1514. {
  1515.     //ctor
  1516. }
  1517.  
  1518. Lightning::~Lightning()
  1519. {
  1520.     //dtor
  1521. }
  1522.  
  1523. void Lightning::setAmbient(glm::vec3 _ambient)
  1524. {
  1525.     ambient = _ambient;
  1526.     glUseProgram(program->getID());
  1527.         glUniform4f(program->getUniform("lightAmbient"), ambient.x, ambient.y, ambient.z, 1.0f);
  1528.     glUseProgram(0);
  1529. }
  1530.  
  1531. void Lightning::addLight(glm::vec3 _position, glm::vec3 _color, float _attenuation)
  1532. {
  1533.     lightsCount++;
  1534.     if (lightsCount > maxLightsCount)
  1535.     {
  1536.         lightsCount--;
  1537.         std::cout << "Lightning::addLight: Operacja anulowana, nie moze byc wiecej niz " << maxLightsCount << " zrodel swiatla\n";
  1538.     }
  1539.     position.push_back(_position.x);
  1540.     position.push_back(_position.y);
  1541.     position.push_back(_position.z);
  1542.  
  1543.     color.push_back(_color.r);
  1544.     color.push_back(_color.g);
  1545.     color.push_back(_color.b);
  1546.     color.push_back(1.0f);
  1547.  
  1548.     attenuation.push_back(_attenuation);
  1549.  
  1550.     update();
  1551. }
  1552.  
  1553. void Lightning::removeLight(unsigned int number)
  1554. {
  1555.     lightsCount--;
  1556.  
  1557.     unsigned int pos = 3*(number - 1);
  1558.     position.erase(position.begin() + pos, position.begin() + pos + 2);
  1559.  
  1560.     pos = 4*(number - 1);
  1561.     color.erase(color.begin() + pos, color.begin() + pos + 3);
  1562.     attenuation.erase(attenuation.begin() + number);
  1563.  
  1564.     update();
  1565. }
  1566.  
  1567. void Lightning::update()
  1568. {
  1569.     glUseProgram(program->getID());
  1570.         glUniform1i (program->getUniform("lightsCount"), lightsCount);
  1571.         glUniform3fv(program->getUniform("lightPos"), lightsCount, position.data());
  1572.         glUniform4fv(program->getUniform("lightColor"), lightsCount, color.data());
  1573.         glUniform1fv(program->getUniform("lightAttenuation"), lightsCount, attenuation.data());
  1574.     glUseProgram(0);
  1575. }
  1576. // lightning.cpp ==============================================================================================================
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement