Fix rendering entities

This commit is contained in:
SeanOMik 2022-09-16 11:14:38 -04:00
parent c9dd65900b
commit 04cf19d7bd
Signed by: SeanOMik
GPG Key ID: 568F326C7EB33ACB
12 changed files with 165 additions and 31 deletions

View File

@ -48,11 +48,7 @@ cmrc_add_resource_library(
# Link dependencies # Link dependencies
target_link_libraries(simpleengine PUBLIC GLEW::GLEW) target_link_libraries(simpleengine PUBLIC GLEW::GLEW)
target_link_libraries(simpleengine PUBLIC glfw) target_link_libraries(simpleengine PUBLIC glfw)
if (WIN32) target_link_libraries(simpleengine PUBLIC ${GLM_LIBRARIES})
target_link_libraries(simpleengine PUBLIC glm::glm)
else()
target_link_libraries(simpleengine PUBLIC glm)
endif()
target_link_libraries(simpleengine PUBLIC soil2) target_link_libraries(simpleengine PUBLIC soil2)
target_link_libraries(simpleengine PUBLIC ${OPENGL_LIBRARIES}) target_link_libraries(simpleengine PUBLIC ${OPENGL_LIBRARIES})
target_link_libraries(simpleengine PRIVATE simpleengine_resources) target_link_libraries(simpleengine PRIVATE simpleengine_resources)

2
cmrc

@ -1 +1 @@
Subproject commit a64bea50c05594c8e7cf1f08e441bb9507742e2e Subproject commit e386a629eb537d384811e598a3c96b9ca928f65e

View File

@ -7,6 +7,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/gfx/shader.h> #include <simpleengine/gfx/shader.h>
#include <simpleengine/renderable.h> #include <simpleengine/renderable.h>
#include <simpleengine/event/event.h> #include <simpleengine/event/event.h>
@ -37,6 +38,31 @@ CMRC_DECLARE(resource_shaders);
namespace se = simpleengine; namespace se = simpleengine;
class FPSCounterEvent : public se::Event {
public:
double last_frame_time;
int frame_count;
FPSCounterEvent() : se::Event() {
this->last_frame_time = glfwGetTime();
frame_count = 0;
}
virtual void update(const float& delta_time) {
double current_time = glfwGetTime();
frame_count++;
// Check if the last print was 1 second ago.
if (current_time - last_frame_time >= 1.0) {
double ms_per_frame = 1000 / (double) frame_count;
printf("%d fps, %f ms/frame\n", frame_count, ms_per_frame);
frame_count = 0;
last_frame_time += 1.0;
}
}
};
std::string read_resource_shader(const std::string& path) { std::string read_resource_shader(const std::string& path) {
auto fs = cmrc::resource_shaders::get_filesystem(); auto fs = cmrc::resource_shaders::get_filesystem();
cmrc::file vertex_file = fs.open(path); cmrc::file vertex_file = fs.open(path);
@ -161,7 +187,7 @@ int main(int argc, char *argv[]) {
auto renderer = std::make_shared<se::gfx::Renderer>(game.get_window(), core_shader); auto renderer = std::make_shared<se::gfx::Renderer>(game.get_window(), core_shader);
renderer->enable_debug(); renderer->enable_debug();
renderer->submit_entity(entity); renderer->submit_entity(entity);
game.add_event(renderer); game.add_renderable(renderer);
/* renderer->add_model(white_texture, cube); /* renderer->add_model(white_texture, cube);
game.add_event(renderer); */ game.add_event(renderer); */
@ -171,6 +197,11 @@ int main(int argc, char *argv[]) {
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);
auto fps_counter = std::make_shared<FPSCounterEvent>();
game.add_event(fps_counter);
game.set_enable_vsync(true);
//game.set_fps_limit(120);
int res = game.run(); int res = game.run();
renderer->destroy(); renderer->destroy();

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include <chrono>
#include <string> #include <string>
#include <memory> #include <memory>
#include <vector> #include <vector>
@ -13,6 +14,7 @@
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#include "event/event.h" #include "event/event.h"
#include "simpleengine/renderable.h"
namespace simpleengine { namespace simpleengine {
class Game { class Game {
@ -34,6 +36,9 @@ namespace simpleengine {
void enable_gl_option(GLenum option) 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 set_fps_limit(const int& fps_limit);
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 handle_input(const float& delta_time);
@ -52,12 +57,17 @@ namespace simpleengine {
GLFWwindow* window; GLFWwindow* window;
std::vector<std::shared_ptr<simpleengine::Event>> events; std::vector<std::shared_ptr<simpleengine::Event>> events;
std::vector<std::shared_ptr<simpleengine::Renderable>> renderable_events;
const bool& window_resizeable; const bool& window_resizeable;
// FPS related stuff
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`.
int fps_limit;
bool enable_vsync;
float get_delta_time(); float get_delta_time();
float last_frame_time; std::chrono::high_resolution_clock::time_point last_frame_time;
/* float currentFrameTime;
float deltaTime; */
}; };
} }

View File

@ -23,7 +23,7 @@ namespace simpleengine::gfx {
shader.unuse(); shader.unuse();
} }
virtual void render(GLFWwindow* target) override { virtual void render() override {
} }
}; };

View File

@ -54,6 +54,6 @@ namespace simpleengine::gfx {
virtual void update(const float& delta_time) override; virtual void update(const float& delta_time) override;
virtual void render(GLFWwindow* target) override; virtual void render() override;
}; };
} }

View File

@ -2,10 +2,10 @@
#include "event/event.h" #include "event/event.h"
#include <memory>
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#include <memory>
namespace simpleengine { namespace simpleengine {
class Renderable : public simpleengine::Event { class Renderable : public simpleengine::Event {
private: private:
@ -14,6 +14,6 @@ namespace simpleengine {
Renderable() = default; Renderable() = default;
virtual ~Renderable() = default; virtual ~Renderable() = default;
virtual void render(GLFWwindow* target) = 0; virtual void render() = 0;
}; };
} }

View File

@ -111,9 +111,5 @@ namespace simpleengine {
virtual void update(const float& delta_time) { virtual void update(const float& delta_time) {
} }
virtual void render(GLFWwindow* target) {
glUseProgram(program);
}
}; };
} }

16
shell.nix Normal file
View File

@ -0,0 +1,16 @@
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
# nativeBuildInputs is usually what you want -- tools you need to run
nativeBuildInputs = with pkgs; [
gdb
lldb
cmake
pkg-config
ninja
glew
glfw
glm
(callPackage ./soil2.nix { })
];
}

37
soil2.nix Normal file
View File

@ -0,0 +1,37 @@
{ lib
, stdenv
, fetchFromGitHub
, cmake
, libGL
, libX11
}:
stdenv.mkDerivation rec {
version = "39028e64921c03cabbc53b937da4a85aba264e00";
pname = "soil2";
src = fetchFromGitHub {
owner = "SpartanJ";
repo = pname;
rev = version;
sha256 = "sha256-zQQ8lwOkMCxdlf6zfnIOYVUTGVqnJuHL/LL8fbzxwHY=";
};
nativeBuildInputs = [ cmake libGL libX11 ];
installPhase = ''
runHook preInstall
cmake --build . --target install --config Release
runHook postInstall
'';
meta = with lib; {
description = "SOIL2 is a tiny C library used primarily for uploading textures into OpenGL.";
homepage = "https://github.com/SpartanJ/SOIL2";
license = licenses.mit0;
platforms = platforms.unix;
maintainers = with maintainers; [ seanomik ];
};
}

View File

@ -1,7 +1,11 @@
#include "game.h" #include "game.h"
#include "event/event.h" #include "event/event.h"
#include "renderable.h"
#include <chrono>
#include <iostream> #include <iostream>
#include <ratio>
#include <thread>
#ifdef __linux__ #ifdef __linux__
#include <GL/glew.h> #include <GL/glew.h>
@ -14,7 +18,8 @@
#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) {
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
@ -47,6 +52,8 @@ void simpleengine::Game::enable_default_gl_options() const {
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
glCullFace(GL_BACK); glCullFace(GL_BACK);
//glFrontFace(GL_CW); //glFrontFace(GL_CW);
update_enabled_vsync();
} }
void simpleengine::Game::enable_gl_option(GLenum option) const { void simpleengine::Game::enable_gl_option(GLenum option) const {
@ -73,6 +80,33 @@ void simpleengine::Game::add_event(std::shared_ptr<simpleengine::Event> event) {
events.push_back(event); events.push_back(event);
} }
void simpleengine::Game::add_renderable(std::shared_ptr<simpleengine::Renderable> renderable_event) {
renderable_events.push_back(renderable_event);
// Also push to normal events to trigger updates.
// Instead of this, we could instead loop renderable_events in the update function,
// but that would cause multiple loops.
events.push_back(renderable_event);
}
void simpleengine::Game::set_fps_limit(const int& fps_limit) {
this->fps_limit = fps_limit;
}
void simpleengine::Game::set_enable_vsync(const bool& enabled) {
this->enable_vsync = enabled;
this->update_enabled_vsync();
}
void simpleengine::Game::update_enabled_vsync() const {
if (enable_vsync) {
//glfwSwapInterval(1);
} else {
glfwSwapInterval(0);
}
}
void simpleengine::Game::update(const float& delta_time) { void simpleengine::Game::update(const float& delta_time) {
handle_input(delta_time); handle_input(delta_time);
@ -83,7 +117,7 @@ void simpleengine::Game::update(const float& delta_time) {
} }
void simpleengine::Game::handle_input(const float& delta_time) { void simpleengine::Game::handle_input(const float& delta_time) {
// TODO
} }
void simpleengine::Game::render_window(const float& delta_time) { void simpleengine::Game::render_window(const float& delta_time) {
@ -93,17 +127,30 @@ void simpleengine::Game::render_window(const float& delta_time) {
} }
void simpleengine::Game::render_items(const float& delta_time) { void simpleengine::Game::render_items(const float& delta_time) {
for (const std::shared_ptr<Event>& event : events) { for (const std::shared_ptr<Renderable>& renderable : renderable_events) {
//event->render(window); renderable->render();
} }
} }
float simpleengine::Game::get_delta_time() { float simpleengine::Game::get_delta_time() {
float current_frame_time = glfwGetTime(); auto current_frame_time = std::chrono::high_resolution_clock::now();
float delta_time = current_frame_time - last_frame_time; std::chrono::duration delta_dur = current_frame_time - last_frame_time;
last_frame_time = current_frame_time; last_frame_time = current_frame_time;
return delta_time; return std::chrono::duration_cast<std::chrono::duration<float>>(delta_dur).count();
}
void simpleengine::Game::limit_framerate(const float& delta_time) const {
if (!enable_vsync && fps_limit >= 15) {
auto delta_time_duration = std::chrono::duration<float>(delta_time);
auto limit_duration = std::chrono::duration<float>(1 / ( (float) fps_limit / 2));
if (delta_time_duration < limit_duration) {
auto sleep_duration = limit_duration - delta_time_duration;
std::this_thread::sleep_for(sleep_duration);
}
}
} }
int simpleengine::Game::run() { int simpleengine::Game::run() {
@ -111,16 +158,17 @@ int simpleengine::Game::run() {
// Get delta time first thing // Get delta time first thing
float delta_time = get_delta_time(); float delta_time = get_delta_time();
// Update input // Poll input events
glfwPollEvents(); glfwPollEvents();
update(delta_time); update(delta_time);
render_window(delta_time); render_window(delta_time);
// End draw // End draw
glfwSwapBuffers(window); glfwSwapBuffers(window);
glFlush(); glFlush();
limit_framerate(delta_time);
} }
return 0; return 0;

View File

@ -100,7 +100,7 @@ namespace simpleengine::gfx {
} }
void Renderer::update(const float& delta_time) { void Renderer::update(const float& delta_time) {
this->render(nullptr);
} }
void Renderer::initialize() { void Renderer::initialize() {
@ -115,7 +115,7 @@ namespace simpleengine::gfx {
} }
} }
void Renderer::render(GLFWwindow* target) { void Renderer::render() {
shader.use(); shader.use();
for (auto& [handle, rendering] : rendering_models) { for (auto& [handle, rendering] : rendering_models) {