diff --git a/CMakeLists.txt b/CMakeLists.txt index 66d5ecf..386cd09 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 ECS/Systems/RenderSystem.h ECS/Components/Mesh.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/Events/MouseMoveEvent.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 ECS/Systems/MouseLookSystem.h ECS/Components/MouseLook.h) include_directories(${OPENGL_INCLUDE_DIRS}) diff --git a/ECS/Components/Camera.h b/ECS/Components/Camera.h index 6bf6c4a..f4be5c2 100644 --- a/ECS/Components/Camera.h +++ b/ECS/Components/Camera.h @@ -14,6 +14,8 @@ struct Camera { glm::perspective(glm::radians(fov), width / height, near, far)) {} glm::mat4 projection; + + glm::mat4 view; }; #endif //ECSGAME_CAMERA_H diff --git a/ECS/Components/MouseLook.h b/ECS/Components/MouseLook.h new file mode 100644 index 0000000..a60ed5c --- /dev/null +++ b/ECS/Components/MouseLook.h @@ -0,0 +1,14 @@ +// +// Created by karl on 07.01.20. +// + +#ifndef ECSGAME_MOUSELOOK_H +#define ECSGAME_MOUSELOOK_H + +struct MouseLook { + explicit MouseLook(float sensitivity) : sensitivity(sensitivity) {} + + float sensitivity; +}; + +#endif //ECSGAME_MOUSELOOK_H diff --git a/ECS/Components/Transform.h b/ECS/Components/Transform.h index e29cb78..593f7c7 100644 --- a/ECS/Components/Transform.h +++ b/ECS/Components/Transform.h @@ -33,6 +33,18 @@ struct Transform { glm::vec3 getPosition() { return matrix * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); } + + glm::vec3 forward() { + return matrix * glm::vec4(0.0, 0.0, -1.0, 1.0); + } + + glm::vec3 up() { + return matrix * glm::vec4(0.0, 1.0, 0.0, 1.0); + } + + glm::vec3 right() { + return matrix * glm::vec4(1.0, 0.0, 0.0, 1.0); + } }; #endif //ECSGAME_TRANSFORM_H diff --git a/ECS/Events/MouseMoveEvent.h b/ECS/Events/MouseMoveEvent.h new file mode 100644 index 0000000..e9405ba --- /dev/null +++ b/ECS/Events/MouseMoveEvent.h @@ -0,0 +1,13 @@ +// +// Created by karl on 04.01.20. +// + +#ifndef ECSGAME_MOUSEMOVEEVENT_H +#define ECSGAME_MOUSEMOVEEVENT_H + +struct MouseMoveEvent { + double newX; + double newY; +}; + +#endif //ECSGAME_INPUTEVENT_H diff --git a/ECS/Systems/KeyboardMovementSystem.h b/ECS/Systems/KeyboardMovementSystem.h index e9bd690..0b63113 100644 --- a/ECS/Systems/KeyboardMovementSystem.h +++ b/ECS/Systems/KeyboardMovementSystem.h @@ -64,7 +64,7 @@ class KeyboardMovementSystem : public EntitySystem, public EventSubscribereach( [&](Entity *ent, ComponentHandle transform, ComponentHandle movement) { - transform->translate(glm::vec3(movement->moving) * movement->speed * deltaTime); + transform->translate(glm::mat3x3(transform->matrix) * glm::vec3(movement->moving) * movement->speed * deltaTime); }); } diff --git a/ECS/Systems/MouseLookSystem.h b/ECS/Systems/MouseLookSystem.h new file mode 100644 index 0000000..fbfcfbf --- /dev/null +++ b/ECS/Systems/MouseLookSystem.h @@ -0,0 +1,73 @@ +// +// Created by karl on 07.01.20. +// + +#ifndef ECSGAME_MOUSELOOKSYSTEM_H +#define ECSGAME_MOUSELOOKSYSTEM_H + +#include "../ECS.h" +#include "../Components/Transform.h" +#include "../Components/MouseLook.h" +#include "../Events/MouseMoveEvent.h" + +using namespace ECS; + +class MouseLookSystem : public EntitySystem, public EventSubscriber { +public: + explicit MouseLookSystem(int width, int height) : lastX(width / 2.0), lastY(height / 2.0) {} + + void configure(World *pWorld) override { + myWorld = pWorld; + + myWorld->subscribe(this); + } + + void unconfigure(World *pWorld) override { + pWorld->unsubscribeAll(this); + } + + void receive(World *pWorld, const MouseMoveEvent &event) override { + pWorld->each([&](Entity *ent, ComponentHandle transform, ComponentHandle mouse, ComponentHandle camera) { + double xOffset = event.newX - lastX; + double yOffset = lastY - event.newY; + + lastX = event.newX; + lastY = event.newY; + + yaw += xOffset * mouse->sensitivity; + pitch += yOffset * mouse->sensitivity; + }); + } + + void tick(World *pWorld, float deltaTime) override { + pWorld->each([&](Entity *ent, ComponentHandle transform, ComponentHandle mouse, ComponentHandle camera) { + if(pitch > 89.0f) + pitch = 89.0f; + if(pitch < -89.0f) + pitch = -89.0f; + + glm::vec3 direction; + direction.x = cos(glm::radians(yaw)) * cos(glm::radians(pitch)); + direction.y = sin(glm::radians(pitch)); + direction.z = sin(glm::radians(yaw)) * cos(glm::radians(pitch)); + + glm::vec3 cameraOrigin = transform->getPosition(); + glm::vec3 cameraFront = glm::normalize(direction); + glm::vec3 cameraUp = glm::vec3(0.0, 1.0, 0.0); + glm::vec3 cameraRight = glm::cross(cameraFront, cameraUp); + + camera->view = glm::lookAt(cameraOrigin, cameraOrigin + cameraFront, cameraUp); + }); + } + +private: + double lastX; + double lastY; + + double pitch = 0.0; + double yaw = 0.0; + + World *myWorld; +}; + +#endif //ECSGAME_MOUSELOOKSYSTEM_H diff --git a/ECS/Systems/RenderSystem.h b/ECS/Systems/RenderSystem.h index dcb03e5..6a2c687 100644 --- a/ECS/Systems/RenderSystem.h +++ b/ECS/Systems/RenderSystem.h @@ -23,7 +23,7 @@ public: shader.use(); shader.setMat4("projection", camera->projection); - shader.setMat4("view", cameraTransform->matrix); + shader.setMat4("view", camera->view); pWorld->each([&](Entity *ent, ComponentHandle mesh, ComponentHandle transform) { shader.setMat4("model", transform->matrix); diff --git a/main.cpp b/main.cpp index 71aed38..760a802 100644 --- a/main.cpp +++ b/main.cpp @@ -6,10 +6,12 @@ #include "Rendering/Shader.h" #include "ECS/ECS.h" #include "ECS/Events/InputEvent.h" +#include "ECS/Events/MouseMoveEvent.h" #include "ECS/Systems/GravitySystem.h" #include "ECS/Systems/PositionDebugSystem.h" #include "ECS/Systems/KeyboardMovementSystem.h" #include "ECS/Systems/RenderSystem.h" +#include "ECS/Systems/MouseLookSystem.h" using namespace ECS; @@ -24,6 +26,10 @@ static void key_callback(GLFWwindow *window, int key, int scancode, int action, world->emit({key, action}); } +static void mouse_callback(GLFWwindow* window, double xpos, double ypos) { + world->emit({xpos, ypos}); +} + int main() { GLFWwindow *window; @@ -41,6 +47,10 @@ int main() { /* Make the window's context current */ glfwMakeContextCurrent(window); + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + + glfwSetCursorPosCallback(window, mouse_callback); + glfwSetKeyCallback(window, key_callback); // glad: load all OpenGL function pointers @@ -55,8 +65,9 @@ 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 PositionDebugOutputSystem()); world->registerSystem(new KeyboardMovementSystem()); + world->registerSystem(new MouseLookSystem(640, 480)); RenderSystem* renderSystem = new RenderSystem(); world->registerSystem(renderSystem); @@ -65,6 +76,7 @@ int main() { player->assign(); player->assign(glm::vec3(1.f, 1.f, 1.f)); player->assign(70.0f, 640, 480, 0.1f, 100.0f); + player->assign(0.1); Entity *box = world->create(); box->assign(); @@ -111,7 +123,7 @@ int main() { -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f }); - box->get()->translate(glm::vec3(0.0f, 0.0f, -10.0f)); + box->get()->translate(glm::vec3(0.0f, 0.0f, -5.0f)); Shader defaultShader("Shaders/default-vertex.vs", "Shaders/default-fragment.fs"); @@ -125,8 +137,6 @@ int main() { timeInLastFrame = glfwGetTime(); elapsed_time += delta; - std::cout << "Elapsed time: " << elapsed_time << std::endl; - world->tick(delta); renderSystem->render(world, defaultShader);