Skip to content

Commit

Permalink
Added a camera.
Browse files Browse the repository at this point in the history
  • Loading branch information
davemackintosh committed Oct 8, 2023
1 parent 0398503 commit 47ce6b1
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 21 deletions.
26 changes: 26 additions & 0 deletions include/gim/ecs/components/camera.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#pragma once

#include <gim/ecs/engine/component_array.hpp>
#include <glm/vec3.hpp>

namespace gim::ecs::components::Camera {
enum Mode : uint32_t {
FirstPerson = 0,
RTS = 1,
};

class Component : public gim::ecs::IComponent {
public:
Mode mode = Mode::FirstPerson;
glm::vec3 position = glm::vec3(0.0f, 0.0f, -0.0f);
glm::vec3 front = glm::vec3(0.0f, 0.0f, -1.0f);
glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f);
float speed = 0.05f;
float yaw = -90.0f;
float pitch = 0.0f;
float sensitivity = 0.1f;

Component() = default;
~Component() override = default;
};
} // namespace gim::ecs::components::Camera
65 changes: 64 additions & 1 deletion include/gim/ecs/systems/vulkan.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include "gim/ecs/components/camera.hpp"
#include "gim/ecs/engine/entity_manager.hpp"
#include "vulkan/vulkan_core.h"
#include <SDL2/SDL.h>
Expand All @@ -13,6 +14,7 @@
#include <gim/engine.hpp>
#include <gim/vulkan/instance.hpp>
#include <gim/vulkan/utils.hpp>
#include <glm/glm.hpp>
#include <memory>
#include <utility>

Expand All @@ -28,10 +30,13 @@ class VulkanRendererSystem : public gim::ecs::ISystem {
// Vulkan.
gim::vulkan::Instance instance;
VkBuffer vertexBuffer;
std::shared_ptr<gim::ecs::components::Shader::TriangleShader> shader;
bool readyToFinishInitialization = false;
VkDeviceMemory vertexBufferMemory;

// Engine.
std::shared_ptr<gim::ecs::components::Shader::TriangleShader> shader;
std::shared_ptr<gim::ecs::components::Camera::Component> camera;

public:
VulkanRendererSystem() : instance(gim::vulkan::Instance()) {}
~VulkanRendererSystem() override {
Expand All @@ -42,17 +47,65 @@ class VulkanRendererSystem : public gim::ecs::ISystem {

auto getSignature() -> std::shared_ptr<Signature> override {
auto signature = std::make_shared<Signature>();
signature->set<gim::ecs::components::Camera::Component>();
signature->set<gim::ecs::components::EngineState::Component>();
signature->set<gim::ecs::components::Shader::TriangleShader>();

return signature;
}

auto processInput(SDL_Event &event) -> void {
if (event.type == SDL_KEYDOWN || event.type == SDL_KEYUP) {
if (event.key.keysym.sym == SDLK_w)
camera->position += camera->speed * camera->front;
if (event.key.keysym.sym == SDLK_s)
camera->position -= camera->speed * camera->front;
if (event.key.keysym.sym == SDLK_a)
camera->position -=
glm::normalize(glm::cross(camera->front, camera->up)) *
camera->speed;
if (event.key.keysym.sym == SDLK_d)
camera->position +=
glm::normalize(glm::cross(camera->front, camera->up)) *
camera->speed;
}
}

auto handleMouseMotion(SDL_Event &event) -> void {
// Update cameraYaw and cameraPitch based on mouse movement
if (event.type == SDL_MOUSEMOTION) {
float xoffset = event.motion.xrel * camera->sensitivity;
float yoffset = -event.motion.yrel *
camera->sensitivity; // y-coordinates are reversed

std::cout << "X offset: " << xoffset << " y offset: " << yoffset
<< std::endl;
camera->yaw += xoffset;
camera->pitch += yoffset;

// Clamp pitch to prevent flipping
if (camera->pitch > 89.0f)
camera->pitch = 89.0f;
if (camera->pitch < -89.0f)
camera->pitch = -89.0f;

glm::vec3 front;
front.x = cos(glm::radians(camera->yaw)) *
cos(glm::radians(camera->pitch));
front.y = sin(glm::radians(camera->pitch));
front.z = sin(glm::radians(camera->yaw)) *
cos(glm::radians(camera->pitch));
camera->front = glm::normalize(front);
}
}

auto update() -> void override {
auto engineStatePair = componentManager->getTComponentWithEntity<
gim::ecs::components::EngineState::Component>(getEntities());
auto triangleShaderPair = componentManager->getTComponentWithEntity<
gim::ecs::components::Shader::TriangleShader>(getEntities());
auto cameraPair = componentManager->getTComponentWithEntity<
gim::ecs::components::Camera::Component>(getEntities());

if (!engineStatePair.has_value()) {
std::cout << "Engine state component not found!" << std::endl;
Expand All @@ -64,10 +117,17 @@ class VulkanRendererSystem : public gim::ecs::ISystem {
return;
}

if (!cameraPair.has_value()) {
std::cout << "Camera not found!" << std::endl;
return;
}

auto [_e, engineState] = engineStatePair.value();
auto [_t, triangleShaderComponent] = triangleShaderPair.value();
auto [_c, cameraComponent] = cameraPair.value();

shader = triangleShaderComponent;
camera = cameraComponent;

if (!readyToFinishInitialization) {
readyToFinishInitialization = true;
Expand All @@ -84,6 +144,9 @@ class VulkanRendererSystem : public gim::ecs::ISystem {
} else if (event.type == SDL_WINDOWEVENT &&
event.window.event == SDL_WINDOWEVENT_RESIZED) {
}

processInput(event);
handleMouseMotion(event);
}

drawFrame();
Expand Down
56 changes: 36 additions & 20 deletions src/platforms/linux.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <SDL_video.h>
#include <cstdlib>
#include <gim/ecs/components/camera.hpp>
#include <gim/ecs/components/engine-state.hpp>
#include <gim/ecs/components/shader-base.hpp>
#include <gim/ecs/components/triangle-shader.hpp>
Expand All @@ -13,47 +14,62 @@ struct VertexData {};
int main() {
auto ecs = std::make_shared<gim::ecs::ECS>();

#pragma mark - Register components

// Register all the components.
ecs->registerComponent<gim::ecs::components::EngineState::Component>();
ecs->registerComponent<gim::ecs::components::Shader::TriangleShader>();
ecs->registerComponent<gim::ecs::components::Camera::Component>();

#pragma mark - Systems
// Register all the systems.
ecs->registerSystem<gim::ecs::systems::VulkanRendererSystem>();

#pragma mark - Game content

// Track internal state.
auto cameraEntity = ecs->createEntity();
auto engineStateEntity = ecs->createEntity();
auto engineState =
std::make_shared<gim::ecs::components::EngineState::Component>();
auto camera = std::make_shared<gim::ecs::components::Camera::Component>();

#pragma mark - Shaders

auto triangleShaderEntity = ecs->createEntity();
auto triangleBindings =
std::make_shared<gim::ecs::components::Shader::TriangleBindings>(
std::make_shared<gim::ecs::components::Shader::TriangleVertexShaderData>(gim::ecs::components::Shader::TriangleVertexShaderData{
.vertices =
std::vector<gim::ecs::components::Shader::Vertex>{
{
.position = glm::vec3{1.f, 1.f, 0.f},
.color = glm::vec4(1.f, 0.f, 0.f, 1.f),
},
{
.position = glm::vec3{-1.f, 1.f, 0.f},
.color = glm::vec4(0.f, 1.f, 0.f, 1.f),
std::make_shared<
gim::ecs::components::Shader::TriangleVertexShaderData>(
gim::ecs::components::Shader::TriangleVertexShaderData{
.vertices =
std::vector<gim::ecs::components::Shader::Vertex>{
{
.position = glm::vec3{1.f, 1.f, 0.f},
.color = glm::vec4(1.f, 0.f, 0.f, 1.f),
},
{
.position = glm::vec3{-1.f, 1.f, 0.f},
.color = glm::vec4(0.f, 1.f, 0.f, 1.f),
},
{
.position = glm::vec3{0.f, -1.f, 0.f},
.color = glm::vec4(0.f, 0.f, 1.f, 1.f),
},
},
{
.position = glm::vec3{0.f, -1.f, 0.f},
.color = glm::vec4(0.f, 0.f, 1.f, 1.f),
},
},
}));
}));
auto triangleShader =
std::make_shared<gim::ecs::components::Shader::TriangleShader>(
triangleBindings);

#pragma mark - Add components

// Register the components.
ecs->addComponent<gim::ecs::components::EngineState::Component>(
engineStateEntity, engineState);
ecs->addComponent<gim::ecs::components::Shader::TriangleShader>(
triangleShaderEntity, triangleShader);
ecs->addComponent(cameraEntity, camera);
ecs->addComponent(engineStateEntity, engineState);
ecs->addComponent(triangleShaderEntity, triangleShader);

#pragma mark - Run the game.

while (engineState->state != gim::ecs::components::EngineState::Quitting) {
ecs->update();
Expand Down

0 comments on commit 47ce6b1

Please sign in to comment.