Create input update loop with varying timestep

This commit is contained in:
SeanOMik 2022-10-16 15:23:35 -04:00
parent 4a53c24e9c
commit 0a5dc66e4c
Signed by: SeanOMik
GPG Key ID: 568F326C7EB33ACB
10 changed files with 71 additions and 78 deletions

View File

@ -1,5 +1,6 @@
--- ---
Checks: "clang-diagnostic-*,clang-analyzer-*,cppcoreguidelines-*,modernize-*,-modernize-use-trailing-return-type" Checks: "clang-diagnostic-*,clang-analyzer-*,cppcoreguidelines-*,modernize-*,-modernize-use-trailing-return-type,
-*-non-private-member-variables-in-classes,-*-magic-numbers"
WarningsAsErrors: true WarningsAsErrors: true
HeaderFilterRegex: "" HeaderFilterRegex: ""
AnalyzeTemporaryDtors: false AnalyzeTemporaryDtors: false
@ -11,8 +12,6 @@ CheckOptions:
value: "0" value: "0"
- key: cppcoreguidelines-explicit-virtual-functions.IgnoreDestructors - key: cppcoreguidelines-explicit-virtual-functions.IgnoreDestructors
value: "1" value: "1"
- key: cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic
value: "1"
- key: google-readability-braces-around-statements.ShortStatementLines - key: google-readability-braces-around-statements.ShortStatementLines
value: "1" value: "1"
- key: google-readability-function-size.StatementThreshold - key: google-readability-function-size.StatementThreshold
@ -23,21 +22,4 @@ CheckOptions:
value: "2" value: "2"
- key: modernize-loop-convert.MaxCopySize - key: modernize-loop-convert.MaxCopySize
value: "16" value: "16"
- key: modernize-loop-convert.MinConfidence
value: reasonable
- key: modernize-loop-convert.NamingStyle
value: CamelCase
- key: modernize-pass-by-value.IncludeStyle
value: llvm
- key: modernize-replace-auto-ptr.IncludeStyle
value: llvm
- key: modernize-use-nullptr.NullMacros
value: "NULL"
- key: readability-magic-numbers
value: "0"
- key: cppcoreguidelines-avoid-magic-numbers
value: "0"
- key: cppcoreguidelines-non-private-member-variables-in-classes
value: "0"
--- ---

View File

@ -65,7 +65,7 @@ int main(int argc, char *argv[]) {
se::gfx::shaders::Core3dShader core_shader; se::gfx::shaders::Core3dShader core_shader;
auto camera = std::make_shared<se::Camera>(game.get_window(), core_shader, 70, glm::vec3(0, 0, 0)); auto camera = std::make_shared<se::Camera>(game.get_window(), core_shader, 70, glm::vec3(0, 0, 0));
game.add_event(camera); //game.add_event(camera);
// Create a renderer // Create a renderer
auto renderer = std::make_shared<se::gfx::Renderer>(game.get_window(), core_shader, camera); auto renderer = std::make_shared<se::gfx::Renderer>(game.get_window(), core_shader, camera);
@ -73,11 +73,11 @@ int main(int argc, char *argv[]) {
//game.add_renderable(renderer); //game.add_renderable(renderer);
// Create a Scene and give it the renderer // Create a Scene and give it the renderer
auto scene = std::make_shared<se::Scene>(renderer); auto scene = std::make_shared<se::Scene>(renderer, camera);
//game.add_event(scene); //game.add_event(scene);
game.add_renderable(scene); game.add_renderable(scene);
se::ecs::Entity other_e = scene->create_entity(); /* se::ecs::Entity other_e = scene->create_entity();
other_e.add_component<se::ModelComponent>("examples/dev_testing/resources/transparent_window.fbx", other_e.add_component<se::ModelComponent>("examples/dev_testing/resources/transparent_window.fbx",
se::gfx::ModelProcessingFlags::MdlProcFlag_TRANSPARENT); se::gfx::ModelProcessingFlags::MdlProcFlag_TRANSPARENT);
auto &other_transform = other_e.add_component<se::TransformComponent>(); auto &other_transform = other_e.add_component<se::TransformComponent>();
@ -86,13 +86,11 @@ int main(int argc, char *argv[]) {
// Create an Entity in the Scene and add components to it. // Create an Entity in the Scene and add components to it.
se::ecs::Entity entity = scene->create_entity(); se::ecs::Entity entity = scene->create_entity();
// entity.add_component<se::ModelComponent>("examples/dev_testing/resources/planks/planks.fbx", simpleengine::gfx::ModelProcessingFlags::MdlProcFlag_CALCULATE_TANGENT_SPACE);
//entity.add_component<se::ModelComponent>("examples/dev_testing/resources/bricks/bricks.fbx", simpleengine::gfx::ModelProcessingFlags::MdlProcFlag_CALCULATE_TANGENT_SPACE);
entity.add_component<se::ModelComponent>("examples/dev_testing/resources/transparent_window.fbx", entity.add_component<se::ModelComponent>("examples/dev_testing/resources/transparent_window.fbx",
se::gfx::ModelProcessingFlags::MdlProcFlag_TRANSPARENT); se::gfx::ModelProcessingFlags::MdlProcFlag_TRANSPARENT);
auto &transform_comp = entity.add_component<se::TransformComponent>(); auto &transform_comp = entity.add_component<se::TransformComponent>();
transform_comp.translate(4.f, 0.f, 0.f); transform_comp.translate(4.f, 0.f, 0.f); */
se::ecs::Entity brick_e = scene->create_entity(); se::ecs::Entity brick_e = scene->create_entity();
brick_e.add_component<se::ModelComponent>("examples/dev_testing/resources/bricks/bricks.fbx"); brick_e.add_component<se::ModelComponent>("examples/dev_testing/resources/bricks/bricks.fbx");

View File

@ -5,24 +5,12 @@
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#include <glm/ext/matrix_clip_space.hpp>
#include <glm/ext/matrix_transform.hpp>
#include <glm/glm.hpp> #include <glm/glm.hpp>
namespace simpleengine { namespace simpleengine {
namespace gfx {
class Renderer;
}
class Camera : public simpleengine::Event { class Camera : public simpleengine::Event {
friend gfx::Renderer;
private: private:
GLFWwindow* window; GLFWwindow* window;
glm::vec3 last_position;
glm::vec3 last_rotation;
glm::mat4 last_view_matrix;
glm::vec3 last_camera_front;
public: public:
glm::vec3 position; glm::vec3 position;
@ -40,13 +28,12 @@ namespace simpleengine {
float movement_speed = 2.5f; float movement_speed = 2.5f;
Camera(GLFWwindow* window, gfx::Shader shader, float fov = 70, glm::vec3 position = glm::vec3(0.f), glm::vec3 rotation = glm::vec3(0.f), Camera(GLFWwindow* window, gfx::Shader shader, float fov = 70, glm::vec3 position = glm::vec3(0.f), glm::vec3 rotation = glm::vec3(0.f),
float near_plane = 0.1f, float far_plane = 1000.f, glm::vec3 world_up = glm::vec3(0.f, 1.f, 0.f), float near_plane = 0.1f, float far_plane = 1000.f);
glm::vec3 cam_front = glm::vec3(0.f, 0.f, -1.f));
Camera(GLFWwindow* window, GLuint shader_prog, float fov = 70, glm::vec3 position = glm::vec3(0.f), Camera(GLFWwindow* window, GLuint shader_prog, float fov = 70, glm::vec3 position = glm::vec3(0.f),
glm::vec3 rotation = glm::vec3(0.f), float near_plane = 0.1f, float far_plane = 1000.f, glm::vec3 world_up = glm::vec3(0.f, 1.f, 0.f), glm::vec3 rotation = glm::vec3(0.f), float near_plane = 0.1f, float far_plane = 1000.f);
glm::vec3 cam_front = glm::vec3(0.f, 0.f, -1.f));
virtual void update(const float& delta_time) override; virtual void update(const float& delta_time) override;
virtual void input_update(const float& delta_time) override;
}; };
} }

View File

@ -10,6 +10,22 @@ namespace simpleengine {
Event() = default; Event() = default;
virtual ~Event() = default; virtual ~Event() = default;
/**
* @brief The update function with fixed-timestep.
*
* Since this is fixed timestep, this function is primarily for game-logic and physics updates.
*
* @param delta_time
*/
virtual void update(const float& delta_time) = 0; virtual void update(const float& delta_time) = 0;
/**
* @brief The update function with varying-timestep.
*
* Since this has a varying timestep, this function is primarily for input related updates.
*
* @param delta_time
*/
virtual void input_update(const float& delta_time) {}
}; };
} }

View File

@ -41,7 +41,7 @@ namespace simpleengine {
void set_enable_vsync(const bool& enabled); void set_enable_vsync(const bool& enabled);
void update(const float& delta_time); void update(const float& delta_time);
void handle_input(const float& delta_time); void input_update(const float& delta_time);
void render_window(const float& interpolate_alpha, const float& delta_time); void render_window(const float& interpolate_alpha, const float& delta_time);
void render_items(const float& interpolate_alpha, const float& delta_time); void render_items(const float& interpolate_alpha, const float& delta_time);
void exit(); void exit();

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include "camera.h"
#include "entt/entity/fwd.hpp" #include "entt/entity/fwd.hpp"
#include "gfx/mesh.h" #include "gfx/mesh.h"
#include "event/event.h" #include "event/event.h"
@ -27,12 +28,15 @@ namespace simpleengine {
// Last transform matrixes for all entities. // Last transform matrixes for all entities.
std::unordered_map<uint32_t, glm::mat4> last_transforms; std::unordered_map<uint32_t, glm::mat4> last_transforms;
std::shared_ptr<Camera> camera;
public: public:
Scene(std::shared_ptr<gfx::Renderer> renderer); Scene(std::shared_ptr<gfx::Renderer> renderer, std::shared_ptr<Camera> camera);
ecs::Entity create_entity(); ecs::Entity create_entity();
virtual void update(const float& delta_time) override; virtual void update(const float& delta_time) override;
virtual void input_update(const float& delta_time) override;
virtual void render(const float& interpolate_alpha, const float& frame_time) override; virtual void render(const float& interpolate_alpha, const float& frame_time) override;
virtual void destroy() override; virtual void destroy() override;

View File

@ -1,29 +1,34 @@
#include "camera.h" #include "camera.h"
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#include <glm/ext/quaternion_common.hpp>
#include <glm/ext/quaternion_geometric.hpp> #include <glm/ext/quaternion_geometric.hpp>
#include <glm/gtc/quaternion.hpp>
#include <glm/gtx/string_cast.hpp>
#include <glm/trigonometric.hpp> #include <glm/trigonometric.hpp>
namespace simpleengine { namespace simpleengine {
Camera::Camera(GLFWwindow* window, gfx::Shader shader, float fov, glm::vec3 position, glm::vec3 rotation, Camera::Camera(GLFWwindow* window, gfx::Shader shader, float fov, glm::vec3 position, glm::vec3 rotation,
float near_plane, float far_plane, glm::vec3 world_up, glm::vec3 cam_front) : window(window), shader(shader), float near_plane, float far_plane) : window(window), shader(shader),
projection_matrix(1.f), view_matrix(1.f), fov(fov), position(position), rotation(rotation), near_plane(near_plane), far_plane(far_plane) { projection_matrix(1.f), fov(fov), position(position), rotation(rotation), near_plane(near_plane), far_plane(far_plane) {
// TODO: Update width and height on window resize. // TODO: Update width and height on window resize.
int width, height; int width, height;
glfwGetFramebufferSize(window, &width, &height); glfwGetFramebufferSize(window, &width, &height);
projection_matrix = glm::perspective(glm::radians(fov), ((float) width) / height, near_plane, far_plane); projection_matrix = glm::perspective(glm::radians(fov), ((float) width) / height, near_plane, far_plane);
//rotation = glm::vec3(0.f, 0.f, -1.f);
} }
Camera::Camera(GLFWwindow* window, GLuint shader_prog, float fov, glm::vec3 position, glm::vec3 rotation, Camera::Camera(GLFWwindow* window, GLuint shader_prog, float fov, glm::vec3 position, glm::vec3 rotation,
float near_plane, float far_plane, glm::vec3 world_up, glm::vec3 cam_front) : Camera(window, gfx::Shader(shader_prog), fov, position, float near_plane, float far_plane) : Camera(window, gfx::Shader(shader_prog), fov, position,
rotation, near_plane, far_plane, world_up, cam_front) { rotation, near_plane, far_plane) {
} }
void Camera::update(const float& delta_time) { void Camera::update(const float& delta_time) {
}
void Camera::input_update(const float& delta_time) {
if (glfwGetKey(window, GLFW_KEY_MINUS) == GLFW_PRESS) { if (glfwGetKey(window, GLFW_KEY_MINUS) == GLFW_PRESS) {
movement_speed -= abs(movement_speed - .2f); movement_speed -= abs(movement_speed - .2f);
} }
@ -94,11 +99,5 @@ namespace simpleengine {
camera_front = glm::normalize(direction); camera_front = glm::normalize(direction);
view_matrix = glm::lookAt(position, position + camera_front, camera_up); view_matrix = glm::lookAt(position, position + camera_front, camera_up);
shader.use();
shader.set_uniform_float_vec3("u_view_pos", position);
shader.set_uniform_matrix_4f("u_view_matrix", view_matrix);
shader.set_uniform_matrix_4f("u_projection_matrix", projection_matrix);
shader.unuse();
} }
} }

View File

@ -107,13 +107,15 @@ void simpleengine::Game::update_enabled_vsync() const {
} }
} }
void simpleengine::Game::handle_input(const float& delta_time) { void simpleengine::Game::input_update(const float& delta_time) {
// TODO // TODO
for (const std::shared_ptr<Event>& event : events) {
event->input_update(delta_time);
}
} }
void simpleengine::Game::update(const float& delta_time) { void simpleengine::Game::update(const float& delta_time) {
handle_input(delta_time);
// Update items // Update items
for (const std::shared_ptr<Event>& event : events) { for (const std::shared_ptr<Event>& event : events) {
event->update(delta_time); event->update(delta_time);
@ -162,10 +164,12 @@ int simpleengine::Game::run() {
// Poll input events // Poll input events
glfwPollEvents(); glfwPollEvents();
const double max_delta_time = 0.5; const double max_delta_time = 0.25;
tps_accumulator += delta_time; tps_accumulator += delta_time;
input_update(delta_time);
while (tps_accumulator >= max_delta_time) { while (tps_accumulator >= max_delta_time) {
update(max_delta_time); update(max_delta_time);

View File

@ -14,6 +14,7 @@
#include <stdexcept> #include <stdexcept>
#include <glm/gtx/string_cast.hpp> #include <glm/gtx/string_cast.hpp>
#include <glm/gtx/matrix_interpolation.hpp>
namespace simpleengine::gfx { namespace simpleengine::gfx {
void create_mesh_buffers(simpleengine::gfx::Mesh &mesh); void create_mesh_buffers(simpleengine::gfx::Mesh &mesh);
@ -47,9 +48,7 @@ namespace simpleengine::gfx {
} }
void Renderer::sort_jobs() { void Renderer::sort_jobs() {
// Sort transparents
// std::sort()
} }
void Renderer::queue_job(RenderingType rendering_type, gfx::Mesh &mesh, glm::mat4 last_position, glm::mat4 position) { void Renderer::queue_job(RenderingType rendering_type, gfx::Mesh &mesh, glm::mat4 last_position, glm::mat4 position) {
@ -63,8 +62,6 @@ namespace simpleengine::gfx {
switch (job.rendering_type) { switch (job.rendering_type) {
case RenderingType::RendType_TRANSPARENT: { case RenderingType::RendType_TRANSPARENT: {
/* glm::vec3 pos = job.transform_mat[3];
float distance = glm::distance(pos, camera->position); */
this->transparent_render_queue.emplace(job); this->transparent_render_queue.emplace(job);
break; break;
} }
@ -131,24 +128,21 @@ namespace simpleengine::gfx {
std::cout << "Destroying renderer..." << std::endl; std::cout << "Destroying renderer..." << std::endl;
shader.delete_program(); shader.delete_program();
/* for (auto& [handle, rendering] : rendering_models) {
rendering.destroy_buffers();
} */
} }
glm::mat4 lerp(glm::mat4 a, glm::mat4 b, float alpha) { glm::mat4 lerp(glm::mat4 to, glm::mat4 from, float alpha) {
//return a * (1.f - alpha) + b * alpha; //return a * (1.f - alpha) + b * alpha;
glm::quat rot0 = glm::quat_cast(a); glm::quat rot0 = glm::quat_cast(to);
glm::quat rot1= glm::quat_cast(b); glm::quat rot1 = glm::quat_cast(from);
glm::quat finalRot = glm::slerp(rot0, rot1, alpha); glm::quat final_rot = glm::slerp(rot0, rot1, alpha);
glm::mat4 finalMat = glm::mat4_cast(finalRot); glm::mat4 final_mat = glm::mat4_cast(final_rot);
finalMat[3] = a[3] * (1 - alpha) + b[3] * alpha; // Interpolate position
final_mat[3] = glm::mix(to[3], from[3], alpha);
return finalMat; return final_mat;
} }
bool Renderer::render_job(const float& interpolate_alpha, const RenderingJob &job) { bool Renderer::render_job(const float& interpolate_alpha, const RenderingJob &job) {
@ -240,6 +234,11 @@ namespace simpleengine::gfx {
void Renderer::render(const float& interpolate_alpha, const float& frame_time) { void Renderer::render(const float& interpolate_alpha, const float& frame_time) {
check_if_initialized(); check_if_initialized();
// Set camera related uniforms
shader.set_uniform_float_vec3("u_view_pos", camera->position);
shader.set_uniform_matrix_4f("u_view_matrix", camera->view_matrix);
shader.set_uniform_matrix_4f("u_projection_matrix", camera->projection_matrix);
// Render other (opaque) objects first // Render other (opaque) objects first
render_job_queue(interpolate_alpha, other_render_queue); render_job_queue(interpolate_alpha, other_render_queue);

View File

@ -10,7 +10,7 @@
#include <stdexcept> #include <stdexcept>
namespace simpleengine { namespace simpleengine {
Scene::Scene(std::shared_ptr<gfx::Renderer> renderer) : renderer(renderer) { Scene::Scene(std::shared_ptr<gfx::Renderer> renderer, std::shared_ptr<Camera> camera) : renderer(renderer), camera(camera) {
} }
@ -18,6 +18,10 @@ namespace simpleengine {
return ecs::Entity(registry, registry.create()); return ecs::Entity(registry, registry.create());
} }
void Scene::input_update(const float& delta_time) {
camera->input_update(delta_time); // Update camera input
}
void Scene::update(const float& delta_time) { void Scene::update(const float& delta_time) {
// Update the last transform matrix // Update the last transform matrix
registry.view<TransformComponent>().each([this, &delta_time](TransformComponent& transform) { registry.view<TransformComponent>().each([this, &delta_time](TransformComponent& transform) {