diff --git a/gui/include/overlay.hpp b/gui/include/overlay.hpp new file mode 100644 index 0000000000000000000000000000000000000000..2339c43c18a12f0bcc7c2c79b9a4a992769b89b1 --- /dev/null +++ b/gui/include/overlay.hpp @@ -0,0 +1,30 @@ +#pragma once +#include <string> +#include <glad/glad.h> +#include <glm/glm.hpp> +#include <shader.hpp> + +class Overlay { +public: + static void init(); + static void loadImage(std::string filename); + + static void draw(glm::mat4 projection, glm::mat4 view, glm::mat4 model); + + //controlled by gui + static float radians; + static glm::vec2 offset; + static float scale; + static float opacity; + +private: + static int _width, _height, _nrChannels; + static unsigned char* _data; + static GLuint _texture; + static Shader _shader; + static GLuint _vbo; + static GLuint _vao; + static GLuint _ebo; + + static bool _imageLoaded; +}; \ No newline at end of file diff --git a/gui/src/overlay.cpp b/gui/src/overlay.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ebc8d4ba9b3fdea8de47a2e1d01f6d4443163dc2 --- /dev/null +++ b/gui/src/overlay.cpp @@ -0,0 +1,131 @@ +#include <overlay.hpp> +#include <vector> +#include <paths.hpp> +#include <shader.hpp> +#define STB_IMAGE_IMPLEMENTATION +#include <stb_image.h> +#include <iostream> +#include <INIReader.h> + +float Overlay::radians = 0.f; +glm::vec2 Overlay::offset = { 0.f, 0.f }; +float Overlay::scale = 0.f; +float Overlay::opacity = 0.f; + +int Overlay::_width = -1; +int Overlay::_height = -1; +int Overlay::_nrChannels = 0; +unsigned char* Overlay::_data = nullptr; +GLuint Overlay::_texture = 0; +Shader Overlay::_shader = {}; +GLuint Overlay::_vbo = 0; +GLuint Overlay::_vao = 0; +GLuint Overlay::_ebo = 0; + +bool Overlay::_imageLoaded = false; + +void Overlay::init() { + //generate opengl objects + glGenBuffers(1, &_vbo); + glGenBuffers(1, &_ebo); + glGenVertexArrays(1, &_vao); + glGenTextures(1, &_texture); + + //setup texture parameters + glBindTexture(GL_TEXTURE_2D, _texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glBindTexture(GL_TEXTURE_2D, 0); + + //setup shader + INIReader inireader("config.ini"); + std::string vertFile = inireader.GetString("paths", "pathShaders", "NONE") + std::string("overlayShader.vert"); + std::string fragFile = inireader.GetString("paths", "pathShaders", "NONE") + std::string("overlayShader.frag"); + _shader = Shader(vertFile.c_str(), fragFile.c_str()); + _shader.use(); + _shader.setFloat("opacity", opacity); + _shader.setFloat("radians", radians); + _shader.setFloat("scale", scale); + _shader.setVec2("offset", offset); + _shader.setInt("imTexture", 0); + _shader.unuse(); +} + +void Overlay::loadImage(std::string filename) { + //load image + std::cout << "Loading " << filename << std::endl; + _data = stbi_load(filename.c_str(), &_width, &_height, &_nrChannels, 0); + std::cout << "Loaded, " << _width << " x " << _height << ", " << _nrChannels << " channels." << std::endl; + if (!_data) { + std::cout << "Error loading overlay file " << filename << std::endl; + return; + } + + glBindTexture(GL_TEXTURE_2D, _texture); + std::cout << "Uploading Texture" << std::endl; + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _width, _height, 0, GL_RGB, GL_UNSIGNED_BYTE, _data); + glGenerateMipmap(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, 0); + std::cout << "Freeing data" << std::endl; + stbi_image_free(_data); + std::cout << "Done loading image." << std::endl; + + //generate quad + float ratio = float(_height) / float(_width); + float length_half = 40.f; + std::vector<float> vbo_vec = { + //position //uv + -length_half, -length_half * ratio, 0.f, 0.f, //bottom left + length_half, -length_half * ratio, 1.f, 0.f, //bottom right + length_half, length_half * ratio, 1.f, 1.f, //top right + -length_half, length_half * ratio, 0.f, 1.f //top left + }; + std::vector<unsigned> ebo_vec = { + 0, 1, 2, //lower right triangle + 0, 2, 3 //top left triangle + }; + + //Upload EBO data + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned) * ebo_vec.size(), ebo_vec.data(), GL_STATIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + //Upload VBO data + glBindBuffer(GL_ARRAY_BUFFER, _vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vbo_vec.size(), vbo_vec.data(), GL_STATIC_DRAW); + + //Setup VAO + glBindVertexArray(_vao); + glBindBuffer(GL_ARRAY_BUFFER, _vbo); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(0)); + glEnableVertexAttribArray(0); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float))); + glEnableVertexAttribArray(1); + glBindVertexArray(0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glBindBuffer(GL_ARRAY_BUFFER, 0); +} + +void Overlay::draw(glm::mat4 projection, glm::mat4 view, glm::mat4 model) { + _shader.use(); + _shader.setFloat("opacity", opacity); + _shader.setFloat("radians", radians); + _shader.setFloat("scale", scale); + _shader.setVec2("offset", offset); + _shader.setInt("imTexture", 0); + glBindVertexArray(_vao); + glBindBuffer(GL_ARRAY_BUFFER, _vbo); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, _texture); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); + glBindVertexArray(0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindTexture(GL_TEXTURE_2D, 0); + + _shader.unuse(); +} \ No newline at end of file