Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /// main.cpp ==========================================================================================================================
- #include "scene.h"
- int main(int argc, char* args[])
- {
- Scene *s = new Scene(800, 600);
- s->init();
- s->eventLoop();
- delete s;
- return 0;
- }
- /// scene.h ==========================================================================================================================
- #ifndef SCENE_H
- #define SCENE_H
- #include "rectangle.h"
- #include <SDL2/SDL.h>
- class Scene
- {
- public:
- Scene(int _width, int _height);
- virtual ~Scene();
- void init();
- void draw();
- void eventLoop();
- protected:
- void checkCollisions();
- void createWindow();
- int width;
- int height;
- std::shared_ptr<Program> program;
- SDL_Window* window = nullptr;
- SDL_GLContext glContext;
- SDL_TimerID timerID;
- std::vector<std::shared_ptr<Rectangle> > rect;
- };
- #endif // SCENE_H
- // scene.cpp ==========================================================================================================================
- #include "scene.h"
- #include <glm/gtc/matrix_transform.hpp>
- #include <glm/gtc/type_ptr.hpp>
- #include <SDL2/SDL_image.h>
- Scene::Scene(int _width, int _height)
- : width(_width), height(_height)
- {
- }
- Scene::~Scene()
- {
- SDL_GL_DeleteContext(glContext);
- SDL_DestroyWindow(window);
- IMG_Quit();
- SDL_Quit();
- }
- void Scene::init()
- {
- createWindow();
- glewExperimental = GL_TRUE;
- glewInit();
- program = std::make_shared<Program>("model.glvs", "model.glfs");
- rect.push_back(std::make_shared<Rectangle>());
- rect[0]->init(program, "ludzik.png", glm::vec2(-50.0f, -50.0f), 20.0f);
- rect.push_back(std::make_shared<Rectangle>());
- rect[1]->init(program, "kwadrat.png", glm::vec2(0.0f, 0.0f), 20.0f);
- rect.push_back(std::make_shared<Rectangle>());
- rect[2]->init(program, "kwadrat.png", glm::vec2(50.0f, -50.0f), 20.0f);
- rect.push_back(std::make_shared<Rectangle>());
- rect[3]->init(program, "kwadrat.png", glm::vec2(-50.0f, 50.0f), 20.0f);
- glUseProgram(program->getID());
- glm::mat4 proj = glm::ortho(-static_cast<float>(width)/2.0f,
- static_cast<float>(width)/2.0f,
- -static_cast<float>(height)/2.0f,
- static_cast<float>(height)/2.0f,
- -1.0f, 1.0f);
- glUniformMatrix4fv(program->getUniform("proj"), 1, GL_FALSE, glm::value_ptr(proj));
- glUseProgram(0);
- }
- void Scene::draw()
- {
- glClearColor(0.0f, 1.0f, 1.0f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- for(const auto &r : rect) r->draw();
- SDL_GL_SwapWindow(window);
- }
- void Scene::eventLoop()
- {
- bool quit = false;
- SDL_Event event;
- while (!quit)
- {
- while (SDL_PollEvent(&event) != 0)
- {
- if (event.type == SDL_QUIT)
- {
- quit = true;
- }
- else if (event.type == SDL_KEYDOWN)
- {
- switch(event.key.keysym.sym)
- {
- case SDLK_ESCAPE:
- quit = true;
- break;
- }
- }
- const Uint8* currentKeyStates = SDL_GetKeyboardState(NULL);
- if (currentKeyStates[SDL_SCANCODE_W] || currentKeyStates[SDL_SCANCODE_UP]) rect[0]->changePosition(glm::vec2(0.0f, 0.8f));
- else if (currentKeyStates[SDL_SCANCODE_S] || currentKeyStates[SDL_SCANCODE_DOWN]) rect[0]->changePosition(glm::vec2(0.0f, -0.8f));
- else if (currentKeyStates[SDL_SCANCODE_A] || currentKeyStates[SDL_SCANCODE_LEFT]) rect[0]->changePosition(glm::vec2(-0.8f, 0.0f));
- else if (currentKeyStates[SDL_SCANCODE_D] || currentKeyStates[SDL_SCANCODE_RIGHT]) rect[0]->changePosition(glm::vec2(0.8f, 0.0f));
- checkCollisions();
- }
- draw();
- }
- }
- void Scene::checkCollisions()
- {
- for (unsigned int i = 0; i < rect.size(); i++)
- {
- for (unsigned int j = 0; j < rect.size(); j++)
- {
- if (i == j) continue;
- if ((rect[i]->getPoint(0).x >= rect[j]->getPoint(0).x &&
- rect[i]->getPoint(0).x <= rect[j]->getPoint(1).x &&
- rect[i]->getPoint(0).y <= rect[j]->getPoint(0).y &&
- rect[i]->getPoint(0).y >= rect[j]->getPoint(3).y) ||
- (rect[i]->getPoint(1).x >= rect[j]->getPoint(0).x &&
- rect[i]->getPoint(1).x <= rect[j]->getPoint(1).x &&
- rect[i]->getPoint(1).y <= rect[j]->getPoint(0).y &&
- rect[i]->getPoint(1).y >= rect[j]->getPoint(3).y) ||
- (rect[i]->getPoint(2).x >= rect[j]->getPoint(0).x &&
- rect[i]->getPoint(2).x <= rect[j]->getPoint(1).x &&
- rect[i]->getPoint(2).y <= rect[j]->getPoint(0).y &&
- rect[i]->getPoint(2).y >= rect[j]->getPoint(3).y) ||
- (rect[i]->getPoint(3).x >= rect[j]->getPoint(0).x &&
- rect[i]->getPoint(3).x <= rect[j]->getPoint(1).x &&
- rect[i]->getPoint(3).y <= rect[j]->getPoint(0).y &&
- rect[i]->getPoint(3).y >= rect[j]->getPoint(3).y))
- rect[0]->undo();
- }
- }
- }
- void Scene::createWindow()
- {
- SDL_Init( SDL_INIT_VIDEO );
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
- SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
- SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
- window = SDL_CreateWindow("OpenGL", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width,
- height, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);
- glContext = SDL_GL_CreateContext(window);
- int imgFlags = IMG_INIT_PNG;
- IMG_Init((imgFlags) & imgFlags);
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_CULL_FACE);
- glCullFace(GL_FRONT);
- glFrontFace(GL_CW);
- }
- /// rectangle.h =======================================================================================================================
- #ifndef RECTANGLE_H
- #define RECTANGLE_H
- #include "program.h"
- #include <memory>
- #include <glm/glm.hpp>
- class Rectangle
- {
- public:
- Rectangle();
- virtual ~Rectangle();
- void init(std::shared_ptr<Program> &_program, std::string textureName, glm::vec2 _position, float _scale);
- void draw();
- virtual void setProgram(std::shared_ptr<Program> &_program) { program = _program; }
- void setPosition(glm::vec2 _position);
- void changePosition(glm::vec2 _dp);
- glm::vec2 getPosition() const { return position; }
- float getScale() const { return scale; }
- void setMatrix(glm::mat4 _matrix) { matrix = _matrix; }
- void changeMatrix(glm::mat4 _matrix);
- glm::mat4 getMatrix() const { return matrix; }
- glm::vec2 getPoint(unsigned int number) { return points[number]; }
- void undo() { position = prevPos; }
- protected:
- glm::vec2 position = glm::vec2();
- glm::vec2 prevPos;
- float scale = 1.0f;
- glm::mat4 matrix;
- std::vector<glm::vec2> points;
- std::shared_ptr<Program> program;
- GLuint vao;
- GLuint vbo;
- GLuint ebo;
- GLuint tex;
- };
- #endif // RECTANGLE_H
- /// rectangle.cpp =====================================================================================================================
- #include "rectangle.h"
- #include <SDL2/SDL_image.h>
- #include <glm/gtc/matrix_transform.hpp>
- #include <glm/gtc/type_ptr.hpp>
- Rectangle::Rectangle()
- {
- glGenVertexArrays(1, &vao);
- glGenBuffers(1, &vbo);
- glGenBuffers(1, &ebo);
- glGenTextures(1, &tex);
- }
- Rectangle::~Rectangle()
- {
- glDeleteBuffers(1, &ebo);
- glDeleteBuffers(1, &vbo);
- glDeleteVertexArrays(1, &vao);
- glDeleteTextures(1, &tex);
- }
- void Rectangle::init(std::shared_ptr<Program> &_program, std::string textureName, glm::vec2 _position, float _scale)
- {
- program = _program;
- position = _position;
- scale = _scale;
- glBindVertexArray(vao);
- points.push_back(position + scale*glm::vec2(-1.0f, 1.0f));
- points.push_back(position + scale*glm::vec2(1.0f, 1.0f));
- points.push_back(position + scale*glm::vec2(1.0f, -1.0f));
- points.push_back(position + scale*glm::vec2(-1.0f, -1.0f));
- GLfloat vertices[] =
- {
- -1.0f, 1.0f, 0.0f, 1.0f,
- 1.0f, 1.0f, 1.0f, 1.0f,
- 1.0f, -1.0f, 1.0f, 0.0f,
- -1.0f, -1.0f, 0.0f, 0.0f
- };
- glBindBuffer(GL_ARRAY_BUFFER, vbo);
- glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
- GLuint elements[] =
- {
- 1, 3, 2, 1, 0, 3
- };
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW);
- SDL_Surface *img;
- std::string file;
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, tex);
- file = textureName;
- img = IMG_Load(file.c_str());
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img->w, img->h, 0, GL_RGB, GL_UNSIGNED_BYTE, img->pixels);
- SDL_FreeSurface(img);
- glGenerateMipmap(GL_TEXTURE_2D);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_NEAREST);
- glGenerateMipmap(GL_TEXTURE_2D);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_NEAREST);
- glUseProgram(_program->getID());
- glUniform1i(program->getUniform("tex0"), 0);
- glUseProgram(0);
- }
- void Rectangle::draw()
- {
- glUseProgram(program->getID());
- matrix = glm::translate(matrix, glm::vec3(position.x, position.y, 0.0f));
- glUniform1f(program->getUniform("scale"), scale);
- glUniformMatrix4fv(program->getUniform("model"), 1, GL_FALSE, glm::value_ptr(matrix));
- glBindVertexArray(vao);
- glBindBuffer(GL_ARRAY_BUFFER, vbo);
- glEnableVertexAttribArray(0);
- glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), 0);
- glEnableVertexAttribArray(1);
- glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), (void*)(2*sizeof(GLfloat)));
- glBindVertexArray(vao);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, tex);
- glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
- matrix = glm::mat4();
- glUseProgram(0);
- }
- void Rectangle::setPosition(glm::vec2 _position)
- {
- prevPos = position;
- position = _position;
- points[0] = glm::vec2(position + scale*glm::vec2(-1.0f, 1.0f));
- points[1] = glm::vec2(position + scale*glm::vec2(1.0f, 1.0f));
- points[2] = glm::vec2(position + scale*glm::vec2(1.0f, -1.0f));
- points[3] = glm::vec2(position + scale*glm::vec2(-1.0f, -1.0f));
- }
- void Rectangle::changePosition(glm::vec2 _dp)
- {
- prevPos = position;
- position += _dp;
- points[0] = glm::vec2(position + scale*glm::vec2(-1.0f, 1.0f));
- points[1] = glm::vec2(position + scale*glm::vec2(1.0f, 1.0f));
- points[2] = glm::vec2(position + scale*glm::vec2(1.0f, -1.0f));
- points[3] = glm::vec2(position + scale*glm::vec2(-1.0f, -1.0f));
- }
- void Rectangle::changeMatrix(glm::mat4 _matrix)
- {
- matrix = _matrix;
- glUniformMatrix4fv(program->getUniform("model"), 1, GL_FALSE, glm::value_ptr(matrix));
- }
- /// program.h =========================================================================================================================
- #ifndef PROGRAM_H
- #define PROGRAM_H
- #include <gl/glew.h>
- #include <gl/gl.h>
- #include <string>
- #include <vector>
- #include <map>
- class Program
- {
- public:
- Program(std::string _vertexName, std::string _fragmentName = "", std::string _geometryName = "");
- virtual ~Program();
- GLuint getID() const { return id; }
- GLint getUniform(std::string name);
- protected:
- void createShader(GLenum type, std::string fileName);
- std::string loadFile(std::string fileName);
- GLuint id;
- std::vector<GLuint> shader;
- std::map<std::string, GLint> uniform;
- private:
- };
- #endif // PROGRAM_H
- /// program.cpp =======================================================================================================================
- #include "program.h"
- #include <fstream>
- #include <iostream>
- #include <sstream>
- Program::Program(std::string _vertexName, std::string _fragmentName, std::string _geometryName)
- {
- id = glCreateProgram();
- createShader(GL_VERTEX_SHADER, _vertexName);
- if (!_fragmentName.empty()) createShader(GL_FRAGMENT_SHADER, _fragmentName);
- if (!_geometryName.empty()) createShader(GL_GEOMETRY_SHADER, _geometryName);
- glLinkProgram(id);
- GLint programSuccess = GL_TRUE;
- glGetProgramiv(id, GL_LINK_STATUS, &programSuccess);
- if (programSuccess != GL_TRUE)
- std::cout << "Nie mozna utworzyc programu: " << glGetError();
- glBindFragDataLocation(id, 0, "outColor");
- }
- Program::~Program()
- {
- for (const auto &s: shader) glDeleteShader(s);
- glDeleteProgram(id);
- }
- GLint Program::getUniform(std::string name)
- {
- auto it = uniform.find(name);
- if (it == uniform.end())
- {
- GLint value = glGetUniformLocation(id, name.c_str());
- if (value != -1) uniform[name] = value;
- else return -1;
- }
- return uniform[name];
- }
- void Program::createShader(GLenum type, std::string fileName)
- {
- GLuint s;
- if (type == GL_VERTEX_SHADER) s = glCreateShader(GL_VERTEX_SHADER);
- else if (type == GL_FRAGMENT_SHADER) s = glCreateShader(GL_FRAGMENT_SHADER);
- else if (type == GL_GEOMETRY_SHADER) s = glCreateShader(GL_GEOMETRY_SHADER);
- const GLchar *source = loadFile(fileName).c_str();
- glShaderSource(s, 1, &source, nullptr);
- glCompileShader(s);
- GLint vShaderCompiled = GL_FALSE;
- glGetShaderiv(s, GL_COMPILE_STATUS, &vShaderCompiled);
- if (vShaderCompiled != GL_TRUE)
- std::cout << "Nie mozna skompilowac shadera: " << fileName << ". Blad: " << glGetError();
- glAttachShader(id, s);
- shader.push_back(s);
- }
- std::string Program::loadFile(std::string fileName)
- {
- std::fstream file;
- file.open(fileName.c_str(), std::ios::in);
- std::stringstream buffer;
- buffer << file.rdbuf();
- std::string data(buffer.str());
- return data;
- }
- // model.glvs =========================================================================================================================
- #version 330
- layout (location = 0) in vec2 position;
- layout (location = 1) in vec2 texcoord;
- out vec2 vTexcoord;
- uniform mat4 model;
- uniform mat4 proj;
- uniform float scale;
- void main()
- {
- 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);
- vTexcoord = vec2(texcoord.x, 1.0 - texcoord.y);
- gl_Position = proj*model*scaleMat*vec4(position.x, position.y, 0.0, 1.0);
- }
- /// model.glfs ========================================================================================================================
- #version 330
- out vec4 outColor;
- in vec2 vTexcoord;
- uniform sampler2D tex0;
- void main()
- {
- outColor = texture(tex0, vTexcoord);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement