[FEATURE] simple GUI support

This commit is contained in:
Menno
2021-05-25 12:36:58 +02:00
parent 97a7501cda
commit 21a7f4f4b2
15 changed files with 260 additions and 25 deletions

BIN
res/Mayo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 323 KiB

20
src/gui/gui_texture.h Normal file
View File

@@ -0,0 +1,20 @@
#pragma once
#include <glm/gtc/matrix_transform.hpp>
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;
};
}

View File

@@ -74,6 +74,16 @@ int main(void)
entities::Camera camera(glm::vec3(0, 0, 0), glm::vec3(0, 0, 0)); entities::Camera camera(glm::vec3(0, 0, 0), glm::vec3(0, 0, 0));
// GUI stuff
shaders::GuiShader gui_shader;
gui_shader.Init();
std::vector<gui::GuiTexture> 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 // Main game loop
while (!glfwWindowShouldClose(window)) while (!glfwWindowShouldClose(window))
{ {
@@ -83,27 +93,33 @@ int main(void)
// Render // Render
render_engine::renderer::Prepare(); render_engine::renderer::Prepare();
shader.Start(); shader.Start();
shader.LoadSkyColor(render_engine::renderer::SKY_COLOR); shader.LoadSkyColor(render_engine::renderer::SKY_COLOR);
shader.LoadLights(lights); shader.LoadLights(lights);
shader.LoadViewMatrix(camera); shader.LoadViewMatrix(camera);
/** // Renders each entity in the entities list
* renders eacht entitie in the entities list
**/
for (entities::Entity& entity : entities) for (entities::Entity& entity : entities)
{ {
render_engine::renderer::Render(entity, shader); render_engine::renderer::Render(entity, shader);
} }
// Finish up // Stop rendering the entities
shader.Stop(); shader.Stop();
// Render GUI items
render_engine::renderer::Render(guis, gui_shader);
// Finish up
glfwSwapBuffers(window); glfwSwapBuffers(window);
glfwPollEvents(); glfwPollEvents();
} }
// Clean up // Clean up
shader.CleanUp(); shader.CleanUp();
gui_shader.CleanUp();
render_engine::loader::CleanUp(); render_engine::loader::CleanUp();
glfwTerminate(); glfwTerminate();
return 0; return 0;

View File

@@ -15,7 +15,7 @@ namespace models
{ {
GLuint vao_id; GLuint vao_id;
int vertex_count; int vertex_count;
glm::vec3 model_size; glm::vec3 model_size = { -1, -1, -1 };
}; };
/* /*

View File

@@ -19,7 +19,7 @@ namespace render_engine
static std::vector<GLuint> textures; static std::vector<GLuint> 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<float>& positions, std::vector<float>& texture_coords, std::vector<float>& normals, std::vector<unsigned int>& indices) models::RawModel LoadToVAO(std::vector<float>& positions, std::vector<float>& texture_coords, std::vector<float>& normals, std::vector<unsigned int>& indices)
{ {
@@ -35,6 +35,17 @@ namespace render_engine
return { vao_id, static_cast<int>(indices.size()), model_size }; return { vao_id, static_cast<int>(indices.size()), model_size };
} }
/*
This function will generate a Model from vertex positions.
*/
models::RawModel LoadToVAO(std::vector<float>& positions)
{
const GLuint vao_id = CreateVao();
StoreDataInAttributeList(0, 2, positions);
glBindVertexArray(0);
return { vao_id, static_cast<int>(positions.size()) / 2 };
}
/* /*
Loads an image as texture into openGL Loads an image as texture into openGL
*/ */

View File

@@ -9,24 +9,36 @@ namespace render_engine
namespace loader namespace loader
{ {
/* /*
@brief: This function generates a model from model data. * @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 position: The positions of each vertex (in order: x, y, z) in the model
@param texture_coords: The texture coordinates of the model * @param texture_coords: The texture coordinates of the model
@param normals: The normals of each face 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 * @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<float>& positions, std::vector<float>& texture_coords, std::vector<float>& normals, std::vector<unsigned int>& indices); models::RawModel LoadToVAO(std::vector<float>& positions, std::vector<float>& texture_coords, std::vector<float>& normals, std::vector<unsigned int>& indices);
/* /*
@brief: Loads a texture from a file into openGL using stb_image.h * @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<float>& positions);
@param file_name: The filepath to the texture /*
* @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); 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(); void CleanUp();
} }

View File

@@ -1,8 +1,11 @@
#include <GL/glew.h> #include <GL/glew.h>
#include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/matrix_transform.hpp>
#include "../models/model.h" #include "../models/model.h"
#include "renderer.h" #include "loader.h"
#include "../toolbox/toolbox.h" #include "../toolbox/toolbox.h"
#include "renderer.h"
#include <iostream>
namespace render_engine namespace render_engine
{ {
@@ -12,9 +15,10 @@ namespace render_engine
static const float NEAR_PLANE = 0.01f; static const float NEAR_PLANE = 0.01f;
static const float FAR_PLANE = 1000.0f; static const float FAR_PLANE = 1000.0f;
/* // GUI variables
This function will load the projectionMatrix into the shader static models::RawModel quad;
*/
void Init(shaders::EntityShader& shader) void Init(shaders::EntityShader& shader)
{ {
// Faces which are not facing the camera are not rendered // Faces which are not facing the camera are not rendered
@@ -28,6 +32,10 @@ namespace render_engine
shader.Start(); shader.Start();
shader.LoadProjectionMatrix(projectionMatrix); shader.LoadProjectionMatrix(projectionMatrix);
shader.Stop(); shader.Stop();
// Initialize the quad for the GUI
std::vector<float> 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::RawModel raw_model = model.raw_model;
const models::ModelTexture texture = model.texture; const models::ModelTexture texture = model.texture;
// Enable the model // Enable the model (VAO)
glBindVertexArray(raw_model.vao_id); glBindVertexArray(raw_model.vao_id);
// Enable the VBO's from the model (VAO) // Enable the VBO's from the model (VAO)
@@ -67,11 +75,52 @@ namespace render_engine
glBindTexture(GL_TEXTURE_2D, model.texture.texture_id); glBindTexture(GL_TEXTURE_2D, model.texture.texture_id);
glDrawElements(GL_TRIANGLES, raw_model.vertex_count, GL_UNSIGNED_INT, 0); 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(0);
glDisableVertexAttribArray(1); glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2); glDisableVertexAttribArray(2);
glBindVertexArray(0); glBindVertexArray(0);
} }
void Render(std::vector<gui::GuiTexture>& 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();
}
} }
} }

View File

@@ -1,7 +1,9 @@
#pragma once #pragma once
#include "../gui/gui_texture.h"
#include "../entities/entity.h" #include "../entities/entity.h"
#include "../shaders/entity_shader.h" #include "../shaders/entity_shader.h"
#include "../shaders/gui_shader.h"
namespace render_engine namespace render_engine
{ {
@@ -29,5 +31,13 @@ namespace render_engine
@param shader: The shader the entity needs to be rendered with @param shader: The shader the entity needs to be rendered with
*/ */
void Render(entities::Entity& entity, shaders::EntityShader& shader); 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<gui::GuiTexture>& guis, shaders::GuiShader& shader);
} }
} }

View File

@@ -124,8 +124,7 @@ namespace shaders
EntityShader::EntityShader(): ShaderProgram(vertex_shader, fragment_shader) EntityShader::EntityShader(): ShaderProgram(vertex_shader, fragment_shader)
{ { }
}
void EntityShader::LoadModelMatrix(const glm::mat4& matrix) const void EntityShader::LoadModelMatrix(const glm::mat4& matrix) const
{ {

View File

@@ -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");
}
}

31
src/shaders/gui_shader.h Normal file
View File

@@ -0,0 +1,31 @@
#pragma once
#include <glm/gtc/matrix_transform.hpp>
#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;
};
}

View File

@@ -2,6 +2,14 @@
namespace toolbox 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 CreateModelMatrix(glm::vec3 translation, glm::vec3 rotation, float scale)
{ {
glm::mat4 matrix(1.0f); glm::mat4 matrix(1.0f);

View File

@@ -8,6 +8,16 @@ namespace toolbox
#define WINDOW_WIDTH 1400.0f #define WINDOW_WIDTH 1400.0f
#define WINDOW_HEIGT 800.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 * @brief: This function will create a model matrix
* *

View File

@@ -25,6 +25,7 @@
<ClCompile Include="src\renderEngine\loader.cpp" /> <ClCompile Include="src\renderEngine\loader.cpp" />
<ClCompile Include="src\renderEngine\obj_loader.cpp" /> <ClCompile Include="src\renderEngine\obj_loader.cpp" />
<ClCompile Include="src\renderEngine\renderer.cpp" /> <ClCompile Include="src\renderEngine\renderer.cpp" />
<ClCompile Include="src\shaders\gui_shader.cpp" />
<ClCompile Include="src\shaders\shader_program.cpp" /> <ClCompile Include="src\shaders\shader_program.cpp" />
<ClCompile Include="src\shaders\entity_shader.cpp" /> <ClCompile Include="src\shaders\entity_shader.cpp" />
<ClCompile Include="src\toolbox\toolbox.cpp" /> <ClCompile Include="src\toolbox\toolbox.cpp" />
@@ -33,10 +34,12 @@
<ClInclude Include="src\entities\camera.h" /> <ClInclude Include="src\entities\camera.h" />
<ClInclude Include="src\entities\entity.h" /> <ClInclude Include="src\entities\entity.h" />
<ClInclude Include="src\entities\light.h" /> <ClInclude Include="src\entities\light.h" />
<ClInclude Include="src\gui\gui_texture.h" />
<ClInclude Include="src\models\model.h" /> <ClInclude Include="src\models\model.h" />
<ClInclude Include="src\renderEngine\loader.h" /> <ClInclude Include="src\renderEngine\loader.h" />
<ClInclude Include="src\renderEngine\obj_loader.h" /> <ClInclude Include="src\renderEngine\obj_loader.h" />
<ClInclude Include="src\renderEngine\renderer.h" /> <ClInclude Include="src\renderEngine\renderer.h" />
<ClInclude Include="src\shaders\gui_shader.h" />
<ClInclude Include="src\shaders\shader_program.h" /> <ClInclude Include="src\shaders\shader_program.h" />
<ClInclude Include="src\shaders\entity_shader.h" /> <ClInclude Include="src\shaders\entity_shader.h" />
<ClInclude Include="src\stb_image.h" /> <ClInclude Include="src\stb_image.h" />

View File

@@ -42,6 +42,9 @@
<ClCompile Include="src\shaders\entity_shader.cpp"> <ClCompile Include="src\shaders\entity_shader.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\shaders\gui_shader.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="src\entities\Camera.h"> <ClInclude Include="src\entities\Camera.h">
@@ -77,5 +80,11 @@
<ClInclude Include="src\shaders\entity_shader.h"> <ClInclude Include="src\shaders\entity_shader.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="src\gui\gui_texture.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\shaders\gui_shader.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
</Project> </Project>