Compare commits
2 Commits
ef498ba210
...
ec7ef40aea
| Author | SHA1 | Date | |
|---|---|---|---|
| ec7ef40aea | |||
| 7b9858cffa |
@ -5,6 +5,8 @@ set(SOURCES
|
||||
src/IO/file_manager.cpp
|
||||
src/renderer/debug.cpp
|
||||
|
||||
src/input/input.cpp
|
||||
|
||||
src/scene/scene.cpp
|
||||
src/window/window.cpp
|
||||
|
||||
|
||||
@ -3,6 +3,8 @@
|
||||
|
||||
#include "engine/scene/scene.h"
|
||||
#include "engine/window/event.hpp"
|
||||
#include "engine/time/timestep.h"
|
||||
|
||||
#include "engine/export.h"
|
||||
|
||||
namespace Core {
|
||||
@ -11,7 +13,7 @@ namespace Core {
|
||||
virtual ~IApplication() = default;
|
||||
|
||||
virtual void OnInit(std::shared_ptr<Scene> scene) {};
|
||||
virtual void OnUpdate() {};
|
||||
virtual void OnUpdate(Timestep dt) {};
|
||||
virtual void OnShutdown() {};
|
||||
|
||||
virtual void OnEvent(const Event& event) {};
|
||||
|
||||
29
engine/include/engine/input/input.h
Normal file
29
engine/include/engine/input/input.h
Normal file
@ -0,0 +1,29 @@
|
||||
#ifndef ENGINE_INPUT_H_
|
||||
#define ENGINE_INPUT_H_
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include "engine/time/timestep.h"
|
||||
|
||||
#include "engine/export.h"
|
||||
|
||||
namespace Core {
|
||||
|
||||
class ENGINE_API Input {
|
||||
public:
|
||||
Input() = delete;
|
||||
private:
|
||||
friend class Engine;
|
||||
static void Update(Timestep dt);
|
||||
public:
|
||||
[[nodiscard]] static glm::vec2 GetRelativeMouse();
|
||||
[[nodiscard]] static bool IsKeyPressed(SDL_Scancode keyCode);
|
||||
private:
|
||||
static bool* s_keys_state;
|
||||
static int s_keys_state_size;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // ENGINE_INPUT_H_
|
||||
@ -30,6 +30,7 @@ private:
|
||||
std::shared_ptr<Window> m_window;
|
||||
std::unique_ptr<Renderer> m_renderer;
|
||||
std::shared_ptr<Scene> m_scene;
|
||||
uint64_t m_elapsed;
|
||||
bool m_running;
|
||||
};
|
||||
|
||||
|
||||
22
engine/include/engine/time/timestep.h
Normal file
22
engine/include/engine/time/timestep.h
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef TIME_TIMESTEP_H_
|
||||
#define TIME_TIMESTEP_H_
|
||||
|
||||
namespace Core {
|
||||
class Timestep {
|
||||
public:
|
||||
Timestep(float time = 0.0f)
|
||||
: m_time(time) {}
|
||||
|
||||
[[nodiscard]] float GetSeconds() const { return m_time; }
|
||||
[[nodiscard]] float GetMilliseconds() const { return m_time * 1000.f; }
|
||||
|
||||
operator float() const { return m_time; }
|
||||
public:
|
||||
static Timestep FromMilliseconds(float milliseconds) { return Timestep(milliseconds * 0.001f); }
|
||||
static Timestep FromSeconds(float seconds) { return Timestep(seconds); }
|
||||
private:
|
||||
float m_time;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // TIME_TIMESTEP_H_
|
||||
24
engine/src/input/input.cpp
Normal file
24
engine/src/input/input.cpp
Normal file
@ -0,0 +1,24 @@
|
||||
#include "engine/input/input.h"
|
||||
|
||||
namespace Core {
|
||||
|
||||
bool* Input::s_keys_state = nullptr;
|
||||
int Input::s_keys_state_size = 0;
|
||||
|
||||
// Engine only function
|
||||
void Input::Update(Timestep dt) {
|
||||
s_keys_state = (bool*)SDL_GetKeyboardState(&s_keys_state_size);
|
||||
}
|
||||
|
||||
glm::vec2 Input::GetRelativeMouse() {
|
||||
glm::vec2 mouse;
|
||||
SDL_GetRelativeMouseState(&mouse.x, &mouse.y);
|
||||
return mouse;
|
||||
}
|
||||
|
||||
bool Input::IsKeyPressed(SDL_Scancode keyCode) {
|
||||
assert(keyCode < s_keys_state_size && "Key is out of bounds of the key input state");
|
||||
return s_keys_state[keyCode];
|
||||
}
|
||||
|
||||
}
|
||||
@ -5,6 +5,9 @@
|
||||
#include "engine/window/event.hpp"
|
||||
#include "engine/renderer/wavefront.h"
|
||||
|
||||
#include "engine/time/timestep.h"
|
||||
#include "engine/input/input.h"
|
||||
|
||||
namespace Core {
|
||||
|
||||
Engine* Engine::s_instance = nullptr;
|
||||
@ -21,10 +24,19 @@ void Engine::Run(std::unique_ptr<IApplication> app) {
|
||||
|
||||
m_window->Subscribe(this);
|
||||
|
||||
uint64_t now = SDL_GetPerformanceCounter();
|
||||
m_elapsed = 0;
|
||||
|
||||
while (m_running) {
|
||||
m_elapsed = now;
|
||||
now = SDL_GetPerformanceCounter();
|
||||
|
||||
auto dt = Timestep::FromMilliseconds((float)((now - m_elapsed)*1000 / (float)SDL_GetPerformanceFrequency()));
|
||||
|
||||
m_window->ProcessEvents();
|
||||
|
||||
m_app->OnUpdate();
|
||||
Input::Update(dt);
|
||||
m_app->OnUpdate(dt);
|
||||
|
||||
m_renderer->Render();
|
||||
|
||||
|
||||
@ -20,6 +20,7 @@
|
||||
#include "engine/components/batch.h"
|
||||
|
||||
#include "engine/scene/scene.h"
|
||||
#include "engine/input/input.h"
|
||||
|
||||
#include "engine/api.h"
|
||||
|
||||
@ -83,30 +84,17 @@ public:
|
||||
std::cout << "Game initialized" << std::endl;
|
||||
|
||||
m_angle = 3.45f;
|
||||
m_lastTicks = SDL_GetTicks();
|
||||
|
||||
m_paused = false;
|
||||
|
||||
m_yaw = -90.0f; // looking along -Z initially
|
||||
m_pitch = 0.0f; // no vertical tilt
|
||||
|
||||
// FPS tracking
|
||||
m_startTicks = SDL_GetTicks();
|
||||
m_frameCount = 0;
|
||||
}
|
||||
|
||||
void OnUpdate() override {
|
||||
m_currentTicks = SDL_GetTicks();
|
||||
float deltaTime = static_cast<float>(m_currentTicks - m_lastTicks) / 1000.0f; // seconds
|
||||
|
||||
m_lastTicks = m_currentTicks;
|
||||
|
||||
float mouseXRel, mouseYRel;
|
||||
SDL_GetRelativeMouseState(&mouseXRel, &mouseYRel);
|
||||
void OnUpdate(Timestep dt) override {
|
||||
glm::vec2 mouseRel = Input::GetRelativeMouse();
|
||||
|
||||
float sensitivity = 0.1f; // tweak as needed
|
||||
m_yaw += mouseXRel * sensitivity;
|
||||
m_pitch -= mouseYRel * sensitivity; // invert Y for typical FPS control
|
||||
m_yaw += mouseRel.x * sensitivity;
|
||||
m_pitch -= mouseRel.y * sensitivity; // invert Y for typical FPS control
|
||||
|
||||
// clamp pitch to avoid flipping
|
||||
// if (pitch > 89.0f) pitch = 89.0f;
|
||||
@ -122,34 +110,28 @@ public:
|
||||
|
||||
glm::vec3 velocity(0.f);
|
||||
|
||||
const bool* state = SDL_GetKeyboardState(nullptr);
|
||||
|
||||
if (state[SDL_SCANCODE_P]) m_paused = !m_paused;
|
||||
|
||||
glm::vec3 front = glm::normalize(glm::vec3(cameraViewDirection.x, 0.f, cameraViewDirection.z));
|
||||
glm::vec3 right = glm::normalize(glm::cross(front, glm::vec3(0.f, 1.f, 0.f)));
|
||||
|
||||
if (state[SDL_SCANCODE_W]) velocity += front;
|
||||
if (state[SDL_SCANCODE_S]) velocity -= front;
|
||||
if (state[SDL_SCANCODE_A]) velocity -= right;
|
||||
if (state[SDL_SCANCODE_D]) velocity += right;
|
||||
if (state[SDL_SCANCODE_SPACE]) velocity.y += 1.f;
|
||||
if (state[SDL_SCANCODE_LSHIFT]) velocity.y -= 1.f;
|
||||
if (Input::IsKeyPressed(SDL_SCANCODE_W)) velocity += front;
|
||||
if (Input::IsKeyPressed(SDL_SCANCODE_S)) velocity -= front;
|
||||
if (Input::IsKeyPressed(SDL_SCANCODE_A)) velocity -= right;
|
||||
if (Input::IsKeyPressed(SDL_SCANCODE_D)) velocity += right;
|
||||
if (Input::IsKeyPressed(SDL_SCANCODE_SPACE)) velocity.y += 1.f;
|
||||
if (Input::IsKeyPressed(SDL_SCANCODE_LSHIFT)) velocity.y -= 1.f;
|
||||
|
||||
auto& camTransform = cameraEntity.GetComponent<transform>();
|
||||
camTransform.position += velocity * deltaTime * 2.5f; // speed is e.g. 2.5f
|
||||
camTransform.position += velocity * (float)dt * 2.5f; // speed is e.g. 2.5f
|
||||
camTransform.rotation = cameraViewDirection;
|
||||
|
||||
// update rotation
|
||||
if (!m_paused) {
|
||||
m_angle += glm::radians(45.0f) * deltaTime; // 72° per second
|
||||
m_angle += glm::radians(45.0f) * dt; // 72° per second
|
||||
if (m_angle > glm::two_pi<float>()) {
|
||||
m_angle -= glm::two_pi<float>(); // keep value small
|
||||
}
|
||||
}
|
||||
|
||||
// ---- Day-night simulation ----
|
||||
m_dayTime += deltaTime;
|
||||
m_dayTime += dt;
|
||||
if (m_dayTime > m_dayLength)
|
||||
m_dayTime -= m_dayLength; // loop every "day"
|
||||
|
||||
@ -181,23 +163,12 @@ public:
|
||||
l.intensity = intensity;
|
||||
}
|
||||
|
||||
// auto rotateEntts = m_scene->m_registry.view<transform, rotate>();
|
||||
// for (auto [entity, t] : rotateEntts.each()) {
|
||||
// // auto targetTransform = rotateEntts.get<transform>(entity);
|
||||
// if (!m_scene->m_registry.all_of<light>(entity)) {
|
||||
// t.rotation.y = m_angle;
|
||||
// }
|
||||
// }
|
||||
m_elapsed += dt.GetMilliseconds();
|
||||
|
||||
m_frameCount++;
|
||||
m_currentTicks = SDL_GetTicks();
|
||||
Uint64 elapsed = m_currentTicks - m_startTicks;
|
||||
|
||||
if (elapsed >= 1000) { // one second passed
|
||||
double fps = static_cast<double>(m_frameCount) / (static_cast<double>(elapsed) / 1000.0);
|
||||
if (m_elapsed >= 1000) { // one second passed
|
||||
m_elapsed = 0;
|
||||
double fps = 1 / dt;
|
||||
std::cout << "FPS: " << fps << std::endl;
|
||||
m_frameCount = 0;
|
||||
m_startTicks = m_currentTicks;
|
||||
}
|
||||
}
|
||||
|
||||
@ -211,6 +182,9 @@ public:
|
||||
}
|
||||
}
|
||||
private:
|
||||
// for internal 1-second timer
|
||||
int m_elapsed;
|
||||
|
||||
std::shared_ptr<Scene> m_scene;
|
||||
|
||||
Entity lightEntity;
|
||||
@ -218,21 +192,12 @@ private:
|
||||
Entity modelEntity;
|
||||
|
||||
float m_angle;
|
||||
Uint64 m_lastTicks;
|
||||
|
||||
float m_dayTime = 0.0f; // accumulates time for day-night cycle
|
||||
float m_dayLength = 60.0f; // seconds per full day cycle
|
||||
|
||||
bool m_paused = false;
|
||||
|
||||
float m_yaw = -90.0f; // looking along -Z initially
|
||||
float m_pitch = 0.0f; // no vertical tilt
|
||||
|
||||
// FPS tracking
|
||||
Uint64 m_startTicks;
|
||||
int m_frameCount;
|
||||
|
||||
Uint64 m_currentTicks;
|
||||
};
|
||||
|
||||
IApplication* CreateApplication() {
|
||||
|
||||
Reference in New Issue
Block a user