diff --git a/meson.build b/meson.build index 3cfd25d..49d9e8e 100644 --- a/meson.build +++ b/meson.build @@ -23,9 +23,12 @@ configure_file( executable('d2d', sources: [ 'src/main.cpp', - 'src/Game.cpp', 'src/Script.cpp', + # game + 'src/Game.cpp', + 'src/Scene.cpp', + # graphics 'src/Shader.cpp', 'src/Shape.cpp', diff --git a/src/Game.cpp b/src/Game.cpp index a82c77a..ae4d4b4 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -37,8 +37,8 @@ namespace d2 /*virtual*/ Game::~Game() { - SDL_GL_DeleteContext(m_context); m_context = nullptr; - SDL_DestroyWindow(m_window); m_window = nullptr; + SDL_DestroyWindow(m_window); + SDL_GL_DeleteContext(m_context); SDL_Quit(); } @@ -46,28 +46,50 @@ namespace d2 { SDL_Event event; bool m_running = true; + float dt = 0.0f; while (m_running) { + auto now = std::chrono::steady_clock::now(); + while (SDL_PollEvent(&event)) { if (event.type == SDL_QUIT) { m_running = false; + break; } } + if (m_running == false) + { + break; + } + glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); - for (auto& obj: m_draw_queue) + if (m_scenes.size() > 0) + { + m_scenes.back()->update(dt); + } + + for (auto const& obj: m_draw_queue) { m_renderer->draw(*obj); } - //m_draw_queue.clear(); + m_draw_queue.clear(); + + if (m_scenes.size() > 0) + { + m_scenes.back()->draw(); + } SDL_GL_SwapWindow(m_window); + + dt = std::chrono::duration_cast + (std::chrono::steady_clock::now() - now).count()/1000000.0f; } } @@ -75,4 +97,12 @@ namespace d2 { m_draw_queue.push_back(std::move(obj)); } + + void Game::pop() + { + if (m_scenes.size() > 0) + { + m_scenes.pop_back(); + } + } } diff --git a/src/Game.hpp b/src/Game.hpp index 83958e6..4aee529 100644 --- a/src/Game.hpp +++ b/src/Game.hpp @@ -4,6 +4,7 @@ #include #include "commons.hpp" #include "Renderer.hpp" +#include "Scene.hpp" namespace d2 { @@ -20,12 +21,24 @@ namespace d2 void run(); void queue_draw(std::unique_ptr obj); + template + void push(Args... args); + void pop(); + private: SDL_Window* m_window = nullptr; SDL_GLContext m_context; std::unique_ptr m_renderer; std::vector> m_draw_queue; + std::vector> m_scenes; }; + + template + void Game::push(Args... args) + { + auto scene = std::make_unique(args...); + m_scenes.push_back(std::move(scene)); + } } #endif diff --git a/src/Scene.cpp b/src/Scene.cpp new file mode 100644 index 0000000..7823801 --- /dev/null +++ b/src/Scene.cpp @@ -0,0 +1,12 @@ +#include "Scene.hpp" + +namespace d2 +{ + /*explicit*/ Scene::Scene() + { + } + + /*virtual*/ Scene::~Scene() + { + } +} diff --git a/src/Scene.hpp b/src/Scene.hpp new file mode 100644 index 0000000..4275291 --- /dev/null +++ b/src/Scene.hpp @@ -0,0 +1,21 @@ +#ifndef d2_SCENE_HPP +#define d2_SCENE_HPP + +#include "commons.hpp" + +namespace d2 +{ + class Scene + { + public: + explicit Scene(); + virtual ~Scene(); + + virtual void update(float dt) = 0; + virtual void draw() = 0; + + private: + }; +} + +#endif diff --git a/src/Script.cpp b/src/Script.cpp index 68b75dc..ef3d17e 100644 --- a/src/Script.cpp +++ b/src/Script.cpp @@ -3,17 +3,32 @@ namespace d2 { /*static*/ std::unique_ptr Script::game = nullptr; - /*static*/ glm::vec4 Script::color = {0.0f, 0.0f, 0.0f, 0.0f}; + /*static*/ glm::vec4 Script::color = {0.0f, 0.0f, 0.0f, 255.0f}; /*static*/ void Script::init() { scm_init_guile(); - scm_c_define_gsubr("winconf", 3, 0, 0, (void*) &fn_winconf); + scm_c_define_gsubr("winconf", 3, 0, 0, + reinterpret_cast(&fn_winconf)); + + // Scenes + // ------ + scm_c_define_gsubr("scene:push", 1, 1, 0, + reinterpret_cast(&fn_scene__push)); + + scm_c_define_gsubr("scene:pop", 0, 0, 0, + reinterpret_cast(&fn_scene__pop)); // Drawing // ------- - scm_c_define_gsubr("rect", 4, 0, 0, (void*) &fn_rect); - scm_c_define_gsubr("color!", 4, 0, 0, (void*) &fn_set_color); + scm_c_define_gsubr("rect", 4, 0, 0, reinterpret_cast(&fn_rect)); + scm_c_define_gsubr("color!", 4, 0, 0, + reinterpret_cast(&fn_set_color)); + } + + /*static*/ void Script::terminate() + { + Script::game.reset(); } /*static*/ void Script::run(std::filesystem::path conf_file) @@ -41,6 +56,26 @@ namespace d2 return SCM_BOOL_T; } + /*static*/ SCM Script::fn_scene__push(SCM scm_function, SCM scm_ctx) + { + if (scm_is_null(scm_ctx)) + { + Script::game->push(scm_function); + } + else + { + Script::game->push(scm_function, scm_ctx); + } + + return SCM_BOOL_T; + } + + /*static*/ SCM Script::fn_scene__pop() + { + Script::game->pop(); + return SCM_BOOL_T; + } + /*static*/ SCM Script::fn_rect(SCM scm_x, SCM scm_y, SCM scm_w, SCM scm_h) { float x = scm_to_double(scm_x); @@ -81,5 +116,4 @@ namespace d2 return SCM_BOOL_T; } - } diff --git a/src/Script.hpp b/src/Script.hpp index 9908a48..5b34222 100644 --- a/src/Script.hpp +++ b/src/Script.hpp @@ -4,22 +4,48 @@ #include "commons.hpp" #include "Game.hpp" +#include "libguile/numbers.h" namespace d2 { struct Script { static void init(); + static void terminate(); static void run(std::filesystem::path conf_file); static SCM fn_winconf(SCM scm_title, SCM scm_width, SCM scm_height); static SCM fn_rect(SCM scm_x, SCM scm_y, SCM scm_w, SCM scm_h); static SCM fn_set_color(SCM scm_r, SCM scm_g, SCM scm_b, SCM scm_a); + static SCM fn_scene__push(SCM scm_function, SCM scm_ctx); + static SCM fn_scene__pop(); + private: static std::unique_ptr game; static glm::vec4 color; }; + + struct ScriptScene: public Scene + { + SCM function; + SCM ctx; + + explicit ScriptScene(SCM p_function, SCM p_ctx = 0) + : function { p_function } + , ctx { p_ctx } + { + } + + void update(float dt) override + { + ctx = scm_call_2(function, scm_from_double(dt), ctx); + } + + void draw() override + { + } + }; } #endif diff --git a/src/Shader.cpp b/src/Shader.cpp index b3677a1..df3feaf 100644 --- a/src/Shader.cpp +++ b/src/Shader.cpp @@ -4,8 +4,6 @@ namespace d2 { /*explicit*/ Shader::Shader() { - m_program = glCreateProgram(); - load_shader(GL_VERTEX_SHADER, DUCK_ASSETS / "shaders" / "vertex.glsl"); @@ -98,13 +96,13 @@ namespace d2 char msg[SZ]; glGetShaderInfoLog(shader, SZ, nullptr, msg); - std::stringstream ss; - ss << "Cannot compile shader '" + std::stringstream ss2; + ss2 << "Cannot compile shader '" << source_path.string() << "'" << std::endl; - ss << msg << std::endl; + ss2 << msg << std::endl; - throw shader_error {ss.str()}; + throw shader_error {ss2.str()}; } glAttachShader(m_program, shader); diff --git a/src/Shader.hpp b/src/Shader.hpp index 77d8f67..a41010f 100644 --- a/src/Shader.hpp +++ b/src/Shader.hpp @@ -22,7 +22,7 @@ namespace d2 void set_matrix(std::string const& name, glm::mat4 matrix) const; private: - GLuint m_program; + GLuint m_program = glCreateProgram(); GLuint load_shader(GLenum type, std::filesystem::path source_path); }; diff --git a/src/main.cpp b/src/main.cpp index 5dde966..4991189 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -16,5 +16,7 @@ int main(int argc, char** argv) d2::Script::run("main.scm"); } + d2::Script::terminate(); + return 0; }