Merge pull request #6 from SeanOMik/feature/fixed-timestep
Implement fixed timestep
This commit is contained in:
commit
8493e2aa86
18
.clang-tidy
18
.clang-tidy
|
@ -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,17 +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"
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "simpleengine/gfx/renderer.h"
|
#include "simpleengine/gfx/renderer.h"
|
||||||
#include "simpleengine/gfx/texture.h"
|
#include "simpleengine/gfx/texture.h"
|
||||||
#include "simpleengine/vector.h"
|
#include "simpleengine/vector.h"
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
#include <simpleengine/ecs/component/model_component.h>
|
#include <simpleengine/ecs/component/model_component.h>
|
||||||
#include <simpleengine/ecs/component/rotating_component.h>
|
#include <simpleengine/ecs/component/rotating_component.h>
|
||||||
#include <simpleengine/event/event.h>
|
#include <simpleengine/event/event.h>
|
||||||
|
@ -33,27 +34,67 @@
|
||||||
|
|
||||||
namespace se = simpleengine;
|
namespace se = simpleengine;
|
||||||
|
|
||||||
class FPSCounterEvent : public se::Event {
|
class FPSCounterEvent : public se::Renderable {
|
||||||
public:
|
public:
|
||||||
double last_frame_time;
|
double last_frame_time_input;
|
||||||
int frame_count;
|
int frame_count_input;
|
||||||
|
|
||||||
FPSCounterEvent() : se::Event() {
|
double last_frame_time_tps;
|
||||||
this->last_frame_time = glfwGetTime();
|
int frame_count_tps;
|
||||||
frame_count = 0;
|
|
||||||
|
double last_frame_time_render;
|
||||||
|
int frame_count_render;
|
||||||
|
|
||||||
|
FPSCounterEvent() : se::Renderable() {
|
||||||
|
last_frame_time_input = glfwGetTime();
|
||||||
|
frame_count_input = 0;
|
||||||
|
|
||||||
|
last_frame_time_tps = glfwGetTime();
|
||||||
|
frame_count_tps = 0;
|
||||||
|
|
||||||
|
last_frame_time_render = glfwGetTime();
|
||||||
|
frame_count_render = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void update(const float &delta_time) {
|
virtual void update(const float &delta_time) {
|
||||||
double current_time = glfwGetTime();
|
double current_time = glfwGetTime();
|
||||||
frame_count++;
|
frame_count_tps++;
|
||||||
|
|
||||||
// Check if the last print was 1 second ago.
|
// Check if the last print was 1 second ago.
|
||||||
if (current_time - last_frame_time >= 1.0) {
|
if (current_time - last_frame_time_tps >= 1.0) {
|
||||||
double ms_per_frame = 1000 / (double)frame_count;
|
double ms_per_frame = 1000 / (double)frame_count_tps;
|
||||||
|
|
||||||
printf("%d fps, %f ms/frame\n", frame_count, ms_per_frame);
|
printf("Fixed update: %d tps, %f ms/frame\n", frame_count_tps, ms_per_frame);
|
||||||
frame_count = 0;
|
frame_count_tps = 0;
|
||||||
last_frame_time += 1.0;
|
last_frame_time_tps += 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void input_update(const float &delta_time) {
|
||||||
|
double current_time = glfwGetTime();
|
||||||
|
frame_count_input++;
|
||||||
|
|
||||||
|
// Check if the last print was 1 second ago.
|
||||||
|
if (current_time - last_frame_time_input >= 1.0) {
|
||||||
|
double ms_per_frame = 1000 / (double)frame_count_input;
|
||||||
|
|
||||||
|
printf("Input: %d tps, %f ms/frame\n", frame_count_input, ms_per_frame);
|
||||||
|
frame_count_input = 0;
|
||||||
|
last_frame_time_input += 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void render(const float& interpolate_alpha, const float& frame_time) {
|
||||||
|
double current_time = glfwGetTime();
|
||||||
|
frame_count_render++;
|
||||||
|
|
||||||
|
// Check if the last print was 1 second ago.
|
||||||
|
if (current_time - last_frame_time_render >= 1.0) {
|
||||||
|
double ms_per_frame = 1000 / (double)frame_count_render;
|
||||||
|
|
||||||
|
printf("Render: %d fps, %f ms/frame\n\n", frame_count_render, ms_per_frame);
|
||||||
|
frame_count_render = 0;
|
||||||
|
last_frame_time_render += 1.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -65,18 +106,19 @@ 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);
|
||||||
renderer->initialize();
|
renderer->initialize();
|
||||||
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);
|
||||||
|
|
||||||
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>();
|
||||||
|
@ -85,28 +127,29 @@ 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");
|
||||||
|
brick_e.add_component<se::RotatingComponent>();
|
||||||
auto &brick_transf = brick_e.add_component<se::TransformComponent>();
|
auto &brick_transf = brick_e.add_component<se::TransformComponent>();
|
||||||
brick_transf.translate(6.f, -0.5f, 1.f);
|
brick_transf.translate(6.f, 0.f, 0.f);
|
||||||
|
//brick_transf.translate(6.f, -0.5f, 1.f);
|
||||||
|
|
||||||
auto light = std::make_shared<se::gfx::Light>(core_shader, glm::vec3(0.f, 0.f, 0.f), glm::vec3(1.f, 1.f, 1.f));
|
auto light = std::make_shared<se::gfx::Light>(core_shader, glm::vec3(0.f, 0.f, 0.f), glm::vec3(1.f, 1.f, 1.f));
|
||||||
game.add_event(light);
|
game.add_event(light);
|
||||||
|
|
||||||
auto fps_counter = std::make_shared<FPSCounterEvent>();
|
auto fps_counter = std::make_shared<FPSCounterEvent>();
|
||||||
game.add_event(fps_counter);
|
game.add_renderable(fps_counter);
|
||||||
|
|
||||||
game.set_enable_vsync(true);
|
/* game.set_enable_vsync(false);
|
||||||
// game.set_fps_limit(120);
|
game.set_fps_limit(100); */
|
||||||
int res = game.run();
|
int res = game.run();
|
||||||
|
|
||||||
std::cout << "Engine result: " << res << std::endl;
|
std::cout << "Engine result: " << res << std::endl;
|
||||||
|
|
||||||
renderer->destroy();
|
renderer->destroy();
|
||||||
|
|
|
@ -5,8 +5,6 @@
|
||||||
|
|
||||||
#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 {
|
||||||
|
@ -14,6 +12,7 @@ namespace simpleengine {
|
||||||
private:
|
private:
|
||||||
GLFWwindow* window;
|
GLFWwindow* window;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
glm::vec3 position;
|
glm::vec3 position;
|
||||||
glm::vec3 rotation;
|
glm::vec3 rotation;
|
||||||
gfx::Shader shader;
|
gfx::Shader shader;
|
||||||
|
@ -29,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;
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
//#include "simpleengine/scene.h"
|
||||||
#include <glm/ext/matrix_transform.hpp>
|
#include <glm/ext/matrix_transform.hpp>
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
@ -9,14 +10,18 @@ namespace simpleengine {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class TransformComponent {
|
class TransformComponent {
|
||||||
|
friend class Scene;
|
||||||
|
private:
|
||||||
|
// This is the transform from the last render loop. The renderer uses this for frame interprelation
|
||||||
|
glm::mat4 last_transform_matrix;
|
||||||
public:
|
public:
|
||||||
glm::mat4 transform_matrix;
|
glm::mat4 transform_matrix;
|
||||||
|
|
||||||
TransformComponent() : transform_matrix(glm::mat4(1.f)) {
|
TransformComponent() : transform_matrix(1.f), last_transform_matrix(1.f) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TransformComponent(glm::mat4 transform_matrix) : transform_matrix(transform_matrix) {
|
TransformComponent(glm::mat4 transform_matrix) : transform_matrix(transform_matrix), last_transform_matrix(1.f) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {}
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -32,18 +32,15 @@ namespace simpleengine {
|
||||||
const int& minor_version = 4, const bool& resizeable = false, const int& forward_compat = GL_TRUE);
|
const int& minor_version = 4, const bool& resizeable = false, const int& forward_compat = GL_TRUE);
|
||||||
virtual ~Game();
|
virtual ~Game();
|
||||||
|
|
||||||
void enable_default_gl_options() const;
|
|
||||||
void enable_gl_option(GLenum option) const;
|
|
||||||
|
|
||||||
void add_event(std::shared_ptr<simpleengine::Event> event);
|
void add_event(std::shared_ptr<simpleengine::Event> event);
|
||||||
void add_renderable(std::shared_ptr<simpleengine::Renderable> renderable_event);
|
void add_renderable(std::shared_ptr<simpleengine::Renderable> renderable_event);
|
||||||
void set_fps_limit(const int& fps_limit);
|
void set_fps_limit(const int& fps_limit);
|
||||||
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& delta_time);
|
void render_window(const float& interpolate_alpha, const float& delta_time);
|
||||||
void render_items(const float& delta_time);
|
void render_items(const float& interpolate_alpha, const float& delta_time);
|
||||||
void exit();
|
void exit();
|
||||||
int run();
|
int run();
|
||||||
|
|
||||||
|
@ -63,8 +60,13 @@ namespace simpleengine {
|
||||||
// FPS related stuff
|
// FPS related stuff
|
||||||
void update_enabled_vsync() const;
|
void update_enabled_vsync() const;
|
||||||
void limit_framerate(const float& delta_time) const; // Triggered at the end of a draw to help limit the FPS to `fps_limit`.
|
void limit_framerate(const float& delta_time) const; // Triggered at the end of a draw to help limit the FPS to `fps_limit`.
|
||||||
int fps_limit;
|
int fps_limit = -1;
|
||||||
bool enable_vsync;
|
bool enable_vsync = true;
|
||||||
|
|
||||||
|
// Engine TPS related stuff
|
||||||
|
int max_engine_tps = 120; // The maximum engine TPS
|
||||||
|
float fixed_delta_time = 1.f / (float) max_engine_tps; // The delta time from fixed timestep
|
||||||
|
float tps_accumulator = 0.f;
|
||||||
|
|
||||||
float get_delta_time();
|
float get_delta_time();
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ namespace simpleengine::gfx {
|
||||||
shader.unuse();
|
shader.unuse();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void render() override {
|
virtual void render(const float& interpolate_alpha, const float& frame_time) override {
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,9 +17,10 @@ namespace simpleengine::gfx {
|
||||||
public:
|
public:
|
||||||
RenderingType rendering_type;
|
RenderingType rendering_type;
|
||||||
gfx::Mesh* rendering_mesh;
|
gfx::Mesh* rendering_mesh;
|
||||||
|
glm::mat4 last_transform_mat;
|
||||||
glm::mat4 transform_mat;
|
glm::mat4 transform_mat;
|
||||||
|
|
||||||
RenderingJob(RenderingType rendering_type, gfx::Mesh& mesh, glm::mat4 position);
|
RenderingJob(RenderingType rendering_type, gfx::Mesh& mesh, glm::mat4 last_pos, glm::mat4 position);
|
||||||
};
|
};
|
||||||
|
|
||||||
class Renderer : public simpleengine::Renderable {
|
class Renderer : public simpleengine::Renderable {
|
||||||
|
@ -41,9 +42,10 @@ namespace simpleengine::gfx {
|
||||||
Renderer(GLFWwindow* window, GLuint shader_program, std::shared_ptr<Camera> camera);
|
Renderer(GLFWwindow* window, GLuint shader_program, std::shared_ptr<Camera> camera);
|
||||||
|
|
||||||
void enable_debug();
|
void enable_debug();
|
||||||
|
void enable_gl_option(GLenum option) const;
|
||||||
|
|
||||||
virtual void sort_jobs();
|
virtual void sort_jobs();
|
||||||
virtual void queue_job(RenderingType rendering_type, gfx::Mesh& mesh, glm::mat4 position);
|
virtual void queue_job(RenderingType rendering_type, gfx::Mesh& mesh, glm::mat4 last_position, glm::mat4 position);
|
||||||
virtual void queue_job(RenderingJob job);
|
virtual void queue_job(RenderingJob job);
|
||||||
virtual void create_job_buffers(RenderingJob& job);
|
virtual void create_job_buffers(RenderingJob& job);
|
||||||
|
|
||||||
|
@ -52,7 +54,7 @@ namespace simpleengine::gfx {
|
||||||
|
|
||||||
virtual void update(const float& delta_time) override;
|
virtual void update(const float& delta_time) override;
|
||||||
|
|
||||||
virtual void render() override;
|
virtual void render(const float& interpolate_alpha, const float& frame_time) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Renders a single job.
|
* @brief Renders a single job.
|
||||||
|
@ -61,8 +63,8 @@ namespace simpleengine::gfx {
|
||||||
* @return true if the job was rendered successfully.
|
* @return true if the job was rendered successfully.
|
||||||
* @return false if there was an error when trying to render the job.
|
* @return false if there was an error when trying to render the job.
|
||||||
*/
|
*/
|
||||||
virtual bool render_job(const RenderingJob& job);
|
virtual bool render_job(const float& interpolate_alpha, const RenderingJob& job);
|
||||||
virtual void render_job_queue(std::queue<RenderingJob>& queue);
|
virtual void render_job_queue(const float& interpolate_alpha, std::queue<RenderingJob>& queue);
|
||||||
virtual void render_job_queue(std::map<float, RenderingJob, std::greater<>>& queue);
|
virtual void render_job_queue(const float& interpolate_alpha, std::map<float, RenderingJob, std::greater<>>& queue);
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -14,6 +14,6 @@ namespace simpleengine {
|
||||||
Renderable() = default;
|
Renderable() = default;
|
||||||
virtual ~Renderable() = default;
|
virtual ~Renderable() = default;
|
||||||
|
|
||||||
virtual void render() = 0;
|
virtual void render(const float& interpolate_alpha, const float& frame_time) = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -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"
|
||||||
|
@ -9,6 +10,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <entt/entt.hpp>
|
#include <entt/entt.hpp>
|
||||||
|
@ -18,16 +20,24 @@ namespace simpleengine {
|
||||||
class Entity;
|
class Entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Scene : public simpleengine::Event {
|
//class Scene : public simpleengine::Event {
|
||||||
|
class Scene : public simpleengine::Renderable {
|
||||||
protected:
|
protected:
|
||||||
entt::registry registry;
|
entt::registry registry;
|
||||||
std::shared_ptr<gfx::Renderer> renderer;
|
std::shared_ptr<gfx::Renderer> renderer;
|
||||||
|
|
||||||
|
// Last transform matrixes for all entities.
|
||||||
|
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 destroy() override;
|
virtual void destroy() override;
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,7 +26,7 @@ struct Material {
|
||||||
|
|
||||||
bool has_specular_map;
|
bool has_specular_map;
|
||||||
sampler2D specular_map;
|
sampler2D specular_map;
|
||||||
|
|
||||||
bool has_normal_map;
|
bool has_normal_map;
|
||||||
sampler2D normal_map;
|
sampler2D normal_map;
|
||||||
|
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
58
src/game.cpp
58
src/game.cpp
|
@ -10,16 +10,14 @@
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
#include <GL/gl.h>
|
|
||||||
#else
|
#else
|
||||||
#include <gl/glew.h>
|
#include <gl/glew.h>
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
#include <gl/gl.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
simpleengine::Game::Game(int w, int h, const std::string& window_name, const int& gl_profile, const int& major_version,
|
simpleengine::Game::Game(int w, int h, const std::string& window_name, const int& gl_profile, const int& major_version,
|
||||||
const int& minor_version, const bool& resizeable, const int& forward_compat) : window_resizeable(resizeable),
|
const int& minor_version, const bool& resizeable, const int& forward_compat) : window_resizeable(resizeable),
|
||||||
enable_vsync(true), fps_limit(-1) {
|
tps_accumulator(0.f) {
|
||||||
initialize(gl_profile, major_version, minor_version, window_resizeable, forward_compat);
|
initialize(gl_profile, major_version, minor_version, window_resizeable, forward_compat);
|
||||||
|
|
||||||
// Create a window
|
// Create a window
|
||||||
|
@ -44,18 +42,9 @@ simpleengine::Game::Game(int w, int h, const std::string& window_name, const int
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
enable_default_gl_options();
|
|
||||||
}
|
|
||||||
|
|
||||||
void simpleengine::Game::enable_default_gl_options() const {
|
|
||||||
|
|
||||||
//glFrontFace(GL_CW);
|
|
||||||
|
|
||||||
update_enabled_vsync();
|
update_enabled_vsync();
|
||||||
}
|
|
||||||
|
|
||||||
void simpleengine::Game::enable_gl_option(GLenum option) const {
|
last_frame_time = std::chrono::high_resolution_clock::now();
|
||||||
glEnable(option);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void simpleengine::Game::initialize(const int& gl_profile, const int& major_version, const int& minor_version,
|
void simpleengine::Game::initialize(const int& gl_profile, const int& major_version, const int& minor_version,
|
||||||
|
@ -105,28 +94,30 @@ void simpleengine::Game::update_enabled_vsync() const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void simpleengine::Game::update(const float& delta_time) {
|
void simpleengine::Game::input_update(const float& delta_time) {
|
||||||
handle_input(delta_time);
|
// TODO
|
||||||
|
|
||||||
|
for (const std::shared_ptr<Event>& event : events) {
|
||||||
|
event->input_update(delta_time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void simpleengine::Game::update(const float& 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void simpleengine::Game::handle_input(const float& delta_time) {
|
void simpleengine::Game::render_window(const float& interpolate_alpha, const float& delta_time) {
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
void simpleengine::Game::render_window(const float& delta_time) {
|
|
||||||
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
|
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||||
render_items(delta_time);
|
render_items(interpolate_alpha, delta_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
void simpleengine::Game::render_items(const float& delta_time) {
|
void simpleengine::Game::render_items(const float& interpolate_alpha, const float& delta_time) {
|
||||||
for (const std::shared_ptr<Renderable>& renderable : renderable_events) {
|
for (const std::shared_ptr<Renderable>& renderable : renderable_events) {
|
||||||
renderable->render();
|
renderable->render(interpolate_alpha, delta_time);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,19 +145,32 @@ void simpleengine::Game::limit_framerate(const float& delta_time) const {
|
||||||
int simpleengine::Game::run() {
|
int simpleengine::Game::run() {
|
||||||
while (!glfwWindowShouldClose(window)) {
|
while (!glfwWindowShouldClose(window)) {
|
||||||
// Get delta time first thing
|
// Get delta time first thing
|
||||||
float delta_time = get_delta_time();
|
float frame_time = get_delta_time();
|
||||||
|
|
||||||
// Poll input events
|
// Poll input events
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
|
|
||||||
|
input_update(frame_time);
|
||||||
|
|
||||||
update(delta_time);
|
tps_accumulator += frame_time;
|
||||||
render_window(delta_time);
|
|
||||||
|
// https://gafferongames.com/post/fix_your_timestep/
|
||||||
|
while (tps_accumulator >= fixed_delta_time) {
|
||||||
|
update(fixed_delta_time);
|
||||||
|
|
||||||
|
tps_accumulator -= fixed_delta_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Alpha used for interpolating objects in rendering
|
||||||
|
float interpolate_alpha = tps_accumulator / fixed_delta_time;
|
||||||
|
|
||||||
|
render_window(interpolate_alpha, frame_time);
|
||||||
|
|
||||||
// End draw
|
// End draw
|
||||||
glfwSwapBuffers(window);
|
glfwSwapBuffers(window);
|
||||||
glFlush();
|
glFlush();
|
||||||
|
|
||||||
limit_framerate(delta_time);
|
limit_framerate(frame_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -13,11 +13,14 @@
|
||||||
#include <glm/geometric.hpp>
|
#include <glm/geometric.hpp>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
|
#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);
|
||||||
|
|
||||||
RenderingJob::RenderingJob(RenderingType rendering_type, gfx::Mesh &mesh, glm::mat4 position)
|
RenderingJob::RenderingJob(RenderingType rendering_type, gfx::Mesh &mesh, glm::mat4 last_pos, glm::mat4 position)
|
||||||
: rendering_type(rendering_type), rendering_mesh(&mesh), transform_mat(position) {}
|
: rendering_type(rendering_type), rendering_mesh(&mesh), last_transform_mat(last_pos), transform_mat(position) {}
|
||||||
|
|
||||||
Renderer::Renderer(GLFWwindow *window, gfx::Shader shader, std::shared_ptr<Camera> camera)
|
Renderer::Renderer(GLFWwindow *window, gfx::Shader shader, std::shared_ptr<Camera> camera)
|
||||||
: window(window), shader(shader), camera(camera)/* , transparent_render_queue(CameraDistanceComparator(camera)) */ {}
|
: window(window), shader(shader), camera(camera)/* , transparent_render_queue(CameraDistanceComparator(camera)) */ {}
|
||||||
|
@ -44,14 +47,16 @@ namespace simpleengine::gfx {
|
||||||
glDebugMessageCallback(debug_message_callback, 0);
|
glDebugMessageCallback(debug_message_callback, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::sort_jobs() {
|
void Renderer::enable_gl_option(GLenum option) const {
|
||||||
// Sort transparents
|
glEnable(option);
|
||||||
|
|
||||||
// std::sort()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::queue_job(RenderingType rendering_type, gfx::Mesh &mesh, glm::mat4 position) {
|
void Renderer::sort_jobs() {
|
||||||
RenderingJob job(rendering_type, mesh, position);
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::queue_job(RenderingType rendering_type, gfx::Mesh &mesh, glm::mat4 last_position, glm::mat4 position) {
|
||||||
|
RenderingJob job(rendering_type, mesh, last_position, position);
|
||||||
|
|
||||||
this->queue_job(job);
|
this->queue_job(job);
|
||||||
}
|
}
|
||||||
|
@ -61,8 +66,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;
|
||||||
}
|
}
|
||||||
|
@ -113,9 +116,10 @@ namespace simpleengine::gfx {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::initialize() {
|
void Renderer::initialize() {
|
||||||
glEnable(GL_DEPTH_TEST);
|
enable_gl_option(GL_DEPTH_TEST);
|
||||||
glEnable(GL_BLEND);
|
enable_gl_option(GL_BLEND);
|
||||||
glEnable(GL_CULL_FACE);
|
enable_gl_option(GL_CULL_FACE);
|
||||||
|
|
||||||
glCullFace(GL_BACK);
|
glCullFace(GL_BACK);
|
||||||
|
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
@ -129,16 +133,30 @@ 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();
|
|
||||||
} */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Renderer::render_job(const RenderingJob &job) {
|
glm::mat4 lerp(glm::mat4 to, glm::mat4 from, float alpha) {
|
||||||
|
//return a * (1.f - alpha) + b * alpha;
|
||||||
|
glm::quat rot0 = glm::quat_cast(to);
|
||||||
|
glm::quat rot1 = glm::quat_cast(from);
|
||||||
|
|
||||||
|
glm::quat final_rot = glm::slerp(rot0, rot1, alpha);
|
||||||
|
|
||||||
|
glm::mat4 final_mat = glm::mat4_cast(final_rot);
|
||||||
|
|
||||||
|
// Interpolate position
|
||||||
|
final_mat[3] = glm::mix(to[3], from[3], alpha);
|
||||||
|
|
||||||
|
return final_mat;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Renderer::render_job(const float& interpolate_alpha, const RenderingJob &job) {
|
||||||
Mesh *mesh = job.rendering_mesh;
|
Mesh *mesh = job.rendering_mesh;
|
||||||
|
|
||||||
shader.set_uniform_matrix_4f("u_transform_matrix", job.transform_mat);
|
// Iterpolate between transforms
|
||||||
|
glm::mat4 transform_mat = lerp(job.last_transform_mat, job.transform_mat, interpolate_alpha);
|
||||||
|
|
||||||
|
shader.set_uniform_matrix_4f("u_transform_matrix", transform_mat);
|
||||||
|
|
||||||
std::optional<Material> &material = mesh->material;
|
std::optional<Material> &material = mesh->material;
|
||||||
|
|
||||||
|
@ -196,12 +214,12 @@ namespace simpleengine::gfx {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::render_job_queue(std::queue<RenderingJob> &rendering_queue) {
|
void Renderer::render_job_queue(const float& interpolate_alpha, std::queue<RenderingJob> &rendering_queue) {
|
||||||
while (!rendering_queue.empty()) {
|
while (!rendering_queue.empty()) {
|
||||||
// Get the job from the queue, we'll remove it after we render.
|
// Get the job from the queue, we'll remove it after we render.
|
||||||
RenderingJob &job = rendering_queue.front();
|
RenderingJob &job = rendering_queue.front();
|
||||||
|
|
||||||
bool res = this->render_job(job);
|
bool res = this->render_job(interpolate_alpha, job);
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
// Now we'll remove the job from the queue.
|
// Now we'll remove the job from the queue.
|
||||||
|
@ -210,19 +228,24 @@ namespace simpleengine::gfx {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::render_job_queue(std::map<float, RenderingJob, std::greater<>>& rendering_queue) {
|
void Renderer::render_job_queue(const float& interpolate_alpha, std::map<float, RenderingJob, std::greater<>>& rendering_queue) {
|
||||||
// Render each job then clear the queue
|
// Render each job then clear the queue
|
||||||
for (const auto& it : rendering_queue) {
|
for (const auto& it : rendering_queue) {
|
||||||
this->render_job(it.second);
|
this->render_job(interpolate_alpha, it.second);
|
||||||
}
|
}
|
||||||
rendering_queue.clear();
|
rendering_queue.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::render() {
|
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(other_render_queue);
|
render_job_queue(interpolate_alpha, other_render_queue);
|
||||||
|
|
||||||
// Render transparent objects
|
// Render transparent objects
|
||||||
std::map<float, RenderingJob, std::greater<>> transparent_jobs;
|
std::map<float, RenderingJob, std::greater<>> transparent_jobs;
|
||||||
|
@ -235,6 +258,6 @@ namespace simpleengine::gfx {
|
||||||
|
|
||||||
transparent_render_queue.pop();
|
transparent_render_queue.pop();
|
||||||
}
|
}
|
||||||
render_job_queue(transparent_jobs);
|
render_job_queue(interpolate_alpha, transparent_jobs);
|
||||||
}
|
}
|
||||||
} // namespace simpleengine::gfx
|
} // namespace simpleengine::gfx
|
|
@ -6,8 +6,11 @@
|
||||||
#include "ecs/entity.h"
|
#include "ecs/entity.h"
|
||||||
#include "gfx/renderer.h"
|
#include "gfx/renderer.h"
|
||||||
|
|
||||||
|
#include <glm/gtx/string_cast.hpp>
|
||||||
|
#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) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,31 +18,45 @@ 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
|
||||||
|
registry.view<TransformComponent>().each([this, &delta_time](TransformComponent& transform) {
|
||||||
|
transform.last_transform_matrix = transform.transform_matrix;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Rotate the model
|
||||||
|
registry.view<TransformComponent, RotatingComponent>().each([this, &delta_time](TransformComponent& transform, RotatingComponent& rotating) {
|
||||||
|
transform.rotate(rotating.rate * delta_time, rotating.rotation_axis);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene::render(const float& interpolate_alpha, const float& frame_time) {
|
||||||
// Is there a way these can be grouped?
|
// Is there a way these can be grouped?
|
||||||
registry.view<const TransformComponent, ModelComponent>().each([this](const TransformComponent& transform, ModelComponent& model_component) {
|
registry.view<TransformComponent, ModelComponent>().each([this](TransformComponent& transform, ModelComponent& model_component) {
|
||||||
for (auto& mesh : model_component.model.meshes) {
|
for (auto& mesh : model_component.model.meshes) {
|
||||||
auto rendering_type = gfx::RenderingType::RendType_OPAQUE;
|
auto rendering_type = gfx::RenderingType::RendType_OPAQUE;
|
||||||
if (mesh.material) {
|
if (mesh.material) {
|
||||||
rendering_type = mesh.material->rendering_type;
|
rendering_type = mesh.material->rendering_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer->queue_job(gfx::RenderingJob(rendering_type, mesh, transform.transform_matrix));
|
renderer->queue_job(gfx::RenderingJob(rendering_type, mesh, transform.last_transform_matrix, transform.transform_matrix));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
registry.view<const TransformComponent, MeshComponent>().each([this](const TransformComponent& transform, MeshComponent& mesh_component) {
|
registry.view<TransformComponent, MeshComponent>().each([this](TransformComponent& transform, MeshComponent& mesh_component) {
|
||||||
auto rendering_type = gfx::RenderingType::RendType_OPAQUE;
|
auto rendering_type = gfx::RenderingType::RendType_OPAQUE;
|
||||||
if (mesh_component.mesh.material) {
|
if (mesh_component.mesh.material) {
|
||||||
rendering_type = mesh_component.mesh.material->rendering_type;
|
rendering_type = mesh_component.mesh.material->rendering_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer->queue_job(gfx::RenderingJob(rendering_type, mesh_component.mesh, transform.transform_matrix));
|
renderer->queue_job(gfx::RenderingJob(rendering_type, mesh_component.mesh, transform.last_transform_matrix, transform.transform_matrix));
|
||||||
});
|
});
|
||||||
|
|
||||||
registry.view<TransformComponent, RotatingComponent>().each([this, &delta_time](TransformComponent& transform, RotatingComponent& rotating) {
|
renderer->render(interpolate_alpha, frame_time);
|
||||||
transform.rotate(rotating.rate * delta_time, rotating.rotation_axis);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::destroy() {
|
void Scene::destroy() {
|
||||||
|
|
Loading…
Reference in New Issue