diff --git a/res/Mayo.png b/res/Mayo.png new file mode 100644 index 0000000..512c3f4 Binary files /dev/null and b/res/Mayo.png differ diff --git a/src/gui/gui_texture.h b/src/gui/gui_texture.h new file mode 100644 index 0000000..2e06d0c --- /dev/null +++ b/src/gui/gui_texture.h @@ -0,0 +1,20 @@ +#pragma once + +#include + +namespace gui +{ + /* + * Structure for representing a gui item to display on the screen + * + * texture = The texture for the gui + * position = The center position of the gui + * scale = The size (scale) of the gui + */ + struct GuiTexture + { + int texture; + glm::vec2 position; + glm::vec2 scale; + }; +} diff --git a/src/main.cpp b/src/main.cpp index adf61f2..546afea 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -73,6 +73,16 @@ int main(void) render_engine::renderer::Init(shader); entities::Camera camera(glm::vec3(0, 0, 0), glm::vec3(0, 0, 0)); + + + // GUI stuff + shaders::GuiShader gui_shader; + gui_shader.Init(); + + std::vector guis; + gui::GuiTexture gui = { render_engine::loader::LoadTexture("res/Mayo.png"), glm::vec2(0.5f, 0.5f), glm::vec2(0.25f, 0.25f) }; + guis.push_back(gui); + // Main game loop while (!glfwWindowShouldClose(window)) @@ -83,27 +93,33 @@ int main(void) // Render render_engine::renderer::Prepare(); + shader.Start(); shader.LoadSkyColor(render_engine::renderer::SKY_COLOR); shader.LoadLights(lights); shader.LoadViewMatrix(camera); - /** - * renders eacht entitie in the entities list - **/ + // Renders each entity in the entities list for (entities::Entity& entity : entities) { render_engine::renderer::Render(entity, shader); } - // Finish up + // Stop rendering the entities shader.Stop(); + + + // Render GUI items + render_engine::renderer::Render(guis, gui_shader); + + // Finish up glfwSwapBuffers(window); glfwPollEvents(); } // Clean up shader.CleanUp(); + gui_shader.CleanUp(); render_engine::loader::CleanUp(); glfwTerminate(); return 0; diff --git a/src/models/Model.h b/src/models/Model.h index b2e6d98..2df9e94 100644 --- a/src/models/Model.h +++ b/src/models/Model.h @@ -15,7 +15,7 @@ namespace models { GLuint vao_id; int vertex_count; - glm::vec3 model_size; + glm::vec3 model_size = { -1, -1, -1 }; }; /* diff --git a/src/renderEngine/Loader.cpp b/src/renderEngine/Loader.cpp index 4fff7dc..aefa6be 100644 --- a/src/renderEngine/Loader.cpp +++ b/src/renderEngine/Loader.cpp @@ -19,7 +19,7 @@ namespace render_engine static std::vector textures; /* - This function will generate a Model from vertex positions, textureCoordinates and indices. + This function will generate a Model from vertex positions, textureCoordinates normals and indices. */ models::RawModel LoadToVAO(std::vector& positions, std::vector& texture_coords, std::vector& normals, std::vector& indices) { @@ -35,6 +35,17 @@ namespace render_engine return { vao_id, static_cast(indices.size()), model_size }; } + /* + This function will generate a Model from vertex positions. + */ + models::RawModel LoadToVAO(std::vector& positions) + { + const GLuint vao_id = CreateVao(); + StoreDataInAttributeList(0, 2, positions); + glBindVertexArray(0); + return { vao_id, static_cast(positions.size()) / 2 }; + } + /* Loads an image as texture into openGL */ diff --git a/src/renderEngine/Loader.h b/src/renderEngine/Loader.h index 2a360f2..02298c7 100644 --- a/src/renderEngine/Loader.h +++ b/src/renderEngine/Loader.h @@ -9,24 +9,36 @@ namespace render_engine namespace loader { /* - @brief: This function generates a model from model data. - - @param position: The positions of each vertex (in order: x, y, z) in the model - @param texture_coords: The texture coordinates of the model - @param normals: The normals of each face of the model - @param indices: A list with a sort of lookup table to the positions parameter + * @brief: This function generates a model from model data. + * + * @param position: The positions of each vertex (in order: x, y, z) in the model + * @param texture_coords: The texture coordinates of the model + * @param normals: The normals of each face of the model + * @param indices: A list with a sort of lookup table to the positions parameter + * + * @return: A new rawmodel which represents al the parameters in one struct */ models::RawModel LoadToVAO(std::vector& positions, std::vector& texture_coords, std::vector& normals, std::vector& indices); /* - @brief: Loads a texture from a file into openGL using stb_image.h - - @param file_name: The filepath to the texture + * @brief: Overloaded function of the function above, but does not need normals and indices. + * Use this function to for example load GUI items to OpenGL. + * + * @param position: The positions of each vertex (in order: x, y, z) in the model + * + * @return: A new rawmodel which represents al the parameters in one struct + */ + models::RawModel LoadToVAO(std::vector& positions); + + /* + * @brief: Loads a texture from a file into openGL using stb_image.h + * + * @param file_name: The filepath to the texture */ GLuint LoadTexture(std::string file_name); /* - @brief: Call this function when cleaning up all the meshes (when exiting the program). + * @brief: Call this function when cleaning up all the meshes (when exiting the program). */ void CleanUp(); } diff --git a/src/renderEngine/Renderer.cpp b/src/renderEngine/Renderer.cpp index 10bd908..7a6559b 100644 --- a/src/renderEngine/Renderer.cpp +++ b/src/renderEngine/Renderer.cpp @@ -1,8 +1,11 @@ #include #include #include "../models/model.h" -#include "renderer.h" +#include "loader.h" #include "../toolbox/toolbox.h" +#include "renderer.h" + +#include namespace render_engine { @@ -12,9 +15,10 @@ namespace render_engine static const float NEAR_PLANE = 0.01f; static const float FAR_PLANE = 1000.0f; - /* - This function will load the projectionMatrix into the shader - */ + // GUI variables + static models::RawModel quad; + + void Init(shaders::EntityShader& shader) { // Faces which are not facing the camera are not rendered @@ -28,6 +32,10 @@ namespace render_engine shader.Start(); shader.LoadProjectionMatrix(projectionMatrix); shader.Stop(); + + // Initialize the quad for the GUI + std::vector quad_positions = { -1, 1, -1, -1, 1, 1, 1, -1 }; + quad = loader::LoadToVAO(quad_positions); } /* @@ -49,7 +57,7 @@ namespace render_engine const models::RawModel raw_model = model.raw_model; const models::ModelTexture texture = model.texture; - // Enable the model + // Enable the model (VAO) glBindVertexArray(raw_model.vao_id); // Enable the VBO's from the model (VAO) @@ -67,11 +75,52 @@ namespace render_engine glBindTexture(GL_TEXTURE_2D, model.texture.texture_id); glDrawElements(GL_TRIANGLES, raw_model.vertex_count, GL_UNSIGNED_INT, 0); - // Disable the VBO's and model + // Disable the VBO's and model (VAO) glDisableVertexAttribArray(0); glDisableVertexAttribArray(1); glDisableVertexAttribArray(2); glBindVertexArray(0); } + + void Render(std::vector& guis, shaders::GuiShader& shader) + { + shader.Start(); + + // Enable the VAO and the positions VBO + glBindVertexArray(quad.vao_id); + glEnableVertexAttribArray(0); + + // Enable alpha blending (for transparency in the texture) + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + // Disable depth testing to textures with transparency can overlap + glDisable(GL_DEPTH_TEST); + + // Render each gui to the screen + for (gui::GuiTexture& gui : guis) + { + // Bind the texture of the gui to the shader + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, gui.texture); + + glm::mat4 matrix = toolbox::CreateModelMatrix(gui.position, gui.scale); + shader.LoadModelMatrix(matrix); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, quad.vertex_count); + } + + // Enable depth test again + glEnable(GL_DEPTH_TEST); + + // Disable alpha blending + glDisable(GL_BLEND); + + // Disable the VBO and VAO + glDisableVertexAttribArray(0); + glBindVertexArray(0); + + shader.Stop(); + } } -} \ No newline at end of file +} diff --git a/src/renderEngine/Renderer.h b/src/renderEngine/Renderer.h index 2379ebf..ed6d1d7 100644 --- a/src/renderEngine/Renderer.h +++ b/src/renderEngine/Renderer.h @@ -1,7 +1,9 @@ #pragma once +#include "../gui/gui_texture.h" #include "../entities/entity.h" #include "../shaders/entity_shader.h" +#include "../shaders/gui_shader.h" namespace render_engine { @@ -29,5 +31,13 @@ namespace render_engine @param shader: The shader the entity needs to be rendered with */ void Render(entities::Entity& entity, shaders::EntityShader& shader); + + /* + @brief: Call this function to render gui_textures on the screen + + @param guis: A list with all the GUI textures you want to render + @param shade: The shader the GUI textures need to be rendered with + */ + void Render(std::vector& guis, shaders::GuiShader& shader); } } \ No newline at end of file diff --git a/src/shaders/entity_shader.cpp b/src/shaders/entity_shader.cpp index 67112d2..3a5a0c0 100644 --- a/src/shaders/entity_shader.cpp +++ b/src/shaders/entity_shader.cpp @@ -124,8 +124,7 @@ namespace shaders EntityShader::EntityShader(): ShaderProgram(vertex_shader, fragment_shader) - { - } + { } void EntityShader::LoadModelMatrix(const glm::mat4& matrix) const { diff --git a/src/shaders/gui_shader.cpp b/src/shaders/gui_shader.cpp new file mode 100644 index 0000000..e56258e --- /dev/null +++ b/src/shaders/gui_shader.cpp @@ -0,0 +1,57 @@ +#include "gui_shader.h" + +namespace shaders +{ + static std::string vertex_shader = R"( + #version 140 + + in vec2 position; + + out vec2 texture_coords; + + uniform mat4 model_matrix; + + void main(void) + { + gl_Position = model_matrix * vec4(position, 0.0, 1.0); + + // This makes top left corner coordinate (0, 0) and bottom right (1, 1) + texture_coords = vec2((position.x + 1.0) / 2.0, 1 - (position.y + 1.0) / 2.0); + } + )"; + + + static std::string fragment_shader = R"( + #version 140 + + in vec2 texture_coords; + + out vec4 out_color; + + uniform sampler2D gui_texture; + + void main(void) + { + out_color = texture(gui_texture, texture_coords); + } + )"; + + + GuiShader::GuiShader() : ShaderProgram(vertex_shader, fragment_shader) + { } + + void GuiShader::LoadModelMatrix(const glm::mat4& matrix) const + { + LoadMatrix(location_model_matrix, matrix); + } + + void GuiShader::SetAttributes() const + { + SetAttribute(0, "position"); + } + + void GuiShader::GetAllUniformLocations() + { + location_model_matrix = GetUniformLocation("model_matrix"); + } +} diff --git a/src/shaders/gui_shader.h b/src/shaders/gui_shader.h new file mode 100644 index 0000000..40eb3b6 --- /dev/null +++ b/src/shaders/gui_shader.h @@ -0,0 +1,31 @@ +#pragma once + +#include +#include "shader_program.h" + +namespace shaders +{ + /* + * This class handles the shaders for all the GUI items + */ + + class GuiShader : public ShaderProgram + { + private: + GLuint location_model_matrix; + + public: + GuiShader(); + + /* + * @brief: A method to load the model matrix into the shader + * + * @param matrix: The model matrix + */ + void LoadModelMatrix(const glm::mat4& matrix) const; + + protected: + void SetAttributes() const override; + void GetAllUniformLocations() override; + }; +} diff --git a/src/toolbox/toolbox.cpp b/src/toolbox/toolbox.cpp index e95d716..57473a9 100644 --- a/src/toolbox/toolbox.cpp +++ b/src/toolbox/toolbox.cpp @@ -2,6 +2,14 @@ namespace toolbox { + glm::mat4 CreateModelMatrix(glm::vec2 translation, glm::vec2 scale) + { + glm::mat4 matrix(1.0f); + matrix = glm::translate(matrix, glm::vec3(translation.x, translation.y, 0)); + matrix = glm::scale(matrix, glm::vec3(scale.x, scale.y, 0)); + return matrix; + } + glm::mat4 CreateModelMatrix(glm::vec3 translation, glm::vec3 rotation, float scale) { glm::mat4 matrix(1.0f); diff --git a/src/toolbox/toolbox.h b/src/toolbox/toolbox.h index 7e443f2..fde57aa 100644 --- a/src/toolbox/toolbox.h +++ b/src/toolbox/toolbox.h @@ -8,6 +8,16 @@ namespace toolbox #define WINDOW_WIDTH 1400.0f #define WINDOW_HEIGT 800.0f + /* + * @brief: This function will create a model matrix + * + * @param translation: The position of the model + * @param scale: The scale of the model + * + * @return: The model matrix of the model + */ + glm::mat4 CreateModelMatrix(glm::vec2 translation, glm::vec2 scale); + /* * @brief: This function will create a model matrix * diff --git a/wk2_fps.vcxproj b/wk2_fps.vcxproj index d284abf..13e3572 100644 --- a/wk2_fps.vcxproj +++ b/wk2_fps.vcxproj @@ -25,6 +25,7 @@ + @@ -33,10 +34,12 @@ + + diff --git a/wk2_fps.vcxproj.filters b/wk2_fps.vcxproj.filters index 570d12e..552a987 100644 --- a/wk2_fps.vcxproj.filters +++ b/wk2_fps.vcxproj.filters @@ -42,6 +42,9 @@ Source Files + + Source Files + @@ -77,5 +80,11 @@ Header Files + + Header Files + + + Header Files + \ No newline at end of file