diff --git a/CMakeLists.txt b/CMakeLists.txt index fffe941..66d5ecf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ find_package(OpenGL REQUIRED) find_package(glfw3 REQUIRED) find_package(glm REQUIRED) -add_executable(ecsgame Util/glad.c Util/OBJ_Loader.h Rendering/Shader.cpp Rendering/Shader.h main.cpp ECS/Components/Transform.h ECS/Components/Movement.h ECS/Events/InputEvent.h ECS/Systems/GravitySystem.h ECS/Systems/PositionDebugSystem.h ECS/Systems/KeyboardMovementSystem.h ECS/Components/Camera.h) +add_executable(ecsgame Util/glad.c Util/OBJ_Loader.h Rendering/Shader.cpp Rendering/Shader.h main.cpp ECS/Components/Transform.h ECS/Components/Movement.h ECS/Events/InputEvent.h ECS/Systems/GravitySystem.h ECS/Systems/PositionDebugSystem.h ECS/Systems/KeyboardMovementSystem.h ECS/Components/Camera.h ECS/Systems/RenderSystem.h ECS/Components/Mesh.h) include_directories(${OPENGL_INCLUDE_DIRS}) diff --git a/ECS/Components/Camera.h b/ECS/Components/Camera.h new file mode 100644 index 0000000..6bf6c4a --- /dev/null +++ b/ECS/Components/Camera.h @@ -0,0 +1,19 @@ +// +// Created by karl on 07.01.20. +// + +#ifndef ECSGAME_CAMERA_H +#define ECSGAME_CAMERA_H + +#include +#include + +struct Camera { + /// Create a camera with a field of view (in degrees), width and height (in any unit) and near and far distances + Camera(float fov, float width, float height, float near, float far) : projection( + glm::perspective(glm::radians(fov), width / height, near, far)) {} + + glm::mat4 projection; +}; + +#endif //ECSGAME_CAMERA_H diff --git a/ECS/Components/Mesh.h b/ECS/Components/Mesh.h new file mode 100644 index 0000000..eb28920 --- /dev/null +++ b/ECS/Components/Mesh.h @@ -0,0 +1,45 @@ +// +// Created by karl on 07.01.20. +// + +#ifndef ECSGAME_MESH_H +#define ECSGAME_MESH_H + +#include +#include +#include + +struct Mesh { + explicit Mesh(std::vector vertices_vector) : vertices(&vertices_vector[0]), vertex_count(vertices_vector.size()) { + glGenVertexArrays(1, &VAO); + glGenBuffers(1, &VBO); + + glBindVertexArray(VAO); + + glBindBuffer(GL_ARRAY_BUFFER, VBO); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + + // position attribute + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); + glEnableVertexAttribArray(0); + + // texture coord attribute + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); + glEnableVertexAttribArray(1); + } + + void render() { + glBindVertexArray(VAO); + glDrawArrays(GL_TRIANGLES, 0, vertex_count); + } + +private: + unsigned int VBO; + unsigned int VAO; + unsigned int vertex_count; + + /// Vertices in the format x, y, z, u, v + float *vertices; +}; + +#endif //ECSGAME_MESH_H diff --git a/ECS/Components/Transform.h b/ECS/Components/Transform.h index 0a58126..e29cb78 100644 --- a/ECS/Components/Transform.h +++ b/ECS/Components/Transform.h @@ -26,6 +26,10 @@ struct Transform { matrix = glm::scale(matrix, factors); } + void rotate(float degrees, glm::vec3 axis) { + matrix = glm::rotate(matrix, glm::radians(degrees), axis); + } + glm::vec3 getPosition() { return matrix * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); } diff --git a/ECS/Systems/RenderSystem.h b/ECS/Systems/RenderSystem.h new file mode 100644 index 0000000..f36c714 --- /dev/null +++ b/ECS/Systems/RenderSystem.h @@ -0,0 +1,35 @@ +// +// Created by karl on 07.01.20. +// + +#ifndef ECSGAME_RENDERSYSTEM_H +#define ECSGAME_RENDERSYSTEM_H + +#include "../ECS.h" +#include "../Components/Transform.h" +#include "../Components/Mesh.h" +#include "../Components/Camera.h" +#include "../../Rendering/Shader.h" + +using namespace ECS; + +class RenderSystem : public EntitySystem { +public: + void render(World *pWorld, Shader shader) { + pWorld->each([&](Entity *ent, ComponentHandle camera, ComponentHandle camera_transform) { + shader.setMat4("projection", camera->projection); + shader.setMat4("view", camera_transform->matrix); + + pWorld->each([&](Entity *ent, ComponentHandle mesh, ComponentHandle transform) { + shader.setMat4("model", transform->matrix); + + mesh->render(); + }); + }); + } + +private: + float gravityAmount; +}; + +#endif //ECSGAME_RENDERSYSTEM_H diff --git a/README.md b/README.md index 25aa3ad..76ea08e 100644 --- a/README.md +++ b/README.md @@ -4,4 +4,6 @@ C++ ECS OpenGL game demo Some code adapted from Joey de Vries' (https://twitter.com/JoeyDeVriez) tutorials at https://learnopengl.com/About licensed under https://creativecommons.org/licenses/by-nc/4.0/. -OBJ-Loader from https://github.com/Bly7/OBJ-Loader. \ No newline at end of file +OBJ-Loader from https://github.com/Bly7/OBJ-Loader. + +ECS library from https://github.com/redxdev/ECS. \ No newline at end of file diff --git a/Rendering/Shader.cpp b/Rendering/Shader.cpp index 5bd4417..7350bc3 100644 --- a/Rendering/Shader.cpp +++ b/Rendering/Shader.cpp @@ -9,6 +9,7 @@ #include #include #include +#include Shader::Shader(const char *vertexPath, const char *fragmentPath) { // 1. retrieve the vertex/fragment source code from filePath @@ -87,6 +88,10 @@ void Shader::setFloat(const std::string &name, float value) const { glUniform1f(glGetUniformLocation(ID, name.c_str()), value); } +void Shader::setMat4(const std::string &name, glm::mat4 mat) const { + glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 10, GL_FALSE, glm::value_ptr(mat)); +} + void Shader::checkCompileErrors(unsigned int shader, const std::string &type) { int success; char infoLog[1024]; diff --git a/Rendering/Shader.h b/Rendering/Shader.h index fbc8954..45af02d 100644 --- a/Rendering/Shader.h +++ b/Rendering/Shader.h @@ -6,6 +6,7 @@ #define ECSGAME_SHADER_H #include +#include class Shader { public: @@ -28,6 +29,9 @@ public: /// Set a uniform float in the shader void setFloat(const std::string &name, float value) const; + /// Set a uniform mat4 in the shader + void setMat4(const std::string &name, glm::mat4 mat) const; + private: static void checkCompileErrors(unsigned int shader, const std::string &type); }; diff --git a/main.cpp b/main.cpp index dfb4d29..4e8764e 100644 --- a/main.cpp +++ b/main.cpp @@ -9,6 +9,7 @@ #include "ECS/Systems/GravitySystem.h" #include "ECS/Systems/PositionDebugSystem.h" #include "ECS/Systems/KeyboardMovementSystem.h" +#include "ECS/Systems/RenderSystem.h" using namespace ECS; @@ -24,17 +25,6 @@ static void key_callback(GLFWwindow *window, int key, int scancode, int action, } int main() { - // TODO: Could be automated by getting all classes within 'ECS/Systems' - world->registerSystem(new GravitySystem(-9.8f)); - world->registerSystem(new PositionDebugOutputSystem()); - world->registerSystem(new KeyboardMovementSystem()); - - Entity *ent = world->create(); - ent->assign(); - ent->assign(glm::vec3(1.f, 1.f, 1.f)); - - ComponentHandle pos = ent->get(); - GLFWwindow *window; /* Initialize the library */ @@ -61,6 +51,21 @@ int main() { return -1; } + // TODO: Could be automated by getting all classes within 'ECS/Systems' + // world->registerSystem(new GravitySystem(-9.8f)); + world->registerSystem(new PositionDebugOutputSystem()); + world->registerSystem(new KeyboardMovementSystem()); + world->registerSystem(new RenderSystem()); + + Entity *player = world->create(); + player->assign(); + player->assign(glm::vec3(1.f, 1.f, 1.f)); + player->assign(70.0f, 640, 480, 0.1f, 100.0f); + + Entity *box = world->create(); + box->assign(); + box->get()->translate(glm::vec3(0.0f, 0.0f, -10.0f)); + Shader defaultShader("Shaders/default-vertex.vs", "Shaders/default-fragment.fs"); // set up vertex data (and buffer(s)) and configure vertex attributes