add simple scene declaration (push and pop state functions)

main
bog 2023-10-29 21:19:09 +01:00
parent 21ca282619
commit cd0d7bfea0
10 changed files with 156 additions and 17 deletions

View File

@ -23,9 +23,12 @@ configure_file(
executable('d2d', executable('d2d',
sources: [ sources: [
'src/main.cpp', 'src/main.cpp',
'src/Game.cpp',
'src/Script.cpp', 'src/Script.cpp',
# game
'src/Game.cpp',
'src/Scene.cpp',
# graphics # graphics
'src/Shader.cpp', 'src/Shader.cpp',
'src/Shape.cpp', 'src/Shape.cpp',

View File

@ -37,8 +37,8 @@ namespace d2
/*virtual*/ Game::~Game() /*virtual*/ Game::~Game()
{ {
SDL_GL_DeleteContext(m_context); m_context = nullptr; SDL_DestroyWindow(m_window);
SDL_DestroyWindow(m_window); m_window = nullptr; SDL_GL_DeleteContext(m_context);
SDL_Quit(); SDL_Quit();
} }
@ -46,28 +46,50 @@ namespace d2
{ {
SDL_Event event; SDL_Event event;
bool m_running = true; bool m_running = true;
float dt = 0.0f;
while (m_running) while (m_running)
{ {
auto now = std::chrono::steady_clock::now();
while (SDL_PollEvent(&event)) while (SDL_PollEvent(&event))
{ {
if (event.type == SDL_QUIT) if (event.type == SDL_QUIT)
{ {
m_running = false; m_running = false;
break;
} }
} }
if (m_running == false)
{
break;
}
glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT); 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_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); SDL_GL_SwapWindow(m_window);
dt = std::chrono::duration_cast<std::chrono::microseconds>
(std::chrono::steady_clock::now() - now).count()/1000000.0f;
} }
} }
@ -75,4 +97,12 @@ namespace d2
{ {
m_draw_queue.push_back(std::move(obj)); m_draw_queue.push_back(std::move(obj));
} }
void Game::pop()
{
if (m_scenes.size() > 0)
{
m_scenes.pop_back();
}
}
} }

View File

@ -4,6 +4,7 @@
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include "commons.hpp" #include "commons.hpp"
#include "Renderer.hpp" #include "Renderer.hpp"
#include "Scene.hpp"
namespace d2 namespace d2
{ {
@ -20,12 +21,24 @@ namespace d2
void run(); void run();
void queue_draw(std::unique_ptr<Object> obj); void queue_draw(std::unique_ptr<Object> obj);
template <typename T, typename... Args>
void push(Args... args);
void pop();
private: private:
SDL_Window* m_window = nullptr; SDL_Window* m_window = nullptr;
SDL_GLContext m_context; SDL_GLContext m_context;
std::unique_ptr<Renderer> m_renderer; std::unique_ptr<Renderer> m_renderer;
std::vector<std::unique_ptr<Object>> m_draw_queue; std::vector<std::unique_ptr<Object>> m_draw_queue;
std::vector<std::unique_ptr<Scene>> m_scenes;
}; };
template <typename T, typename... Args>
void Game::push(Args... args)
{
auto scene = std::make_unique<T>(args...);
m_scenes.push_back(std::move(scene));
}
} }
#endif #endif

12
src/Scene.cpp Normal file
View File

@ -0,0 +1,12 @@
#include "Scene.hpp"
namespace d2
{
/*explicit*/ Scene::Scene()
{
}
/*virtual*/ Scene::~Scene()
{
}
}

21
src/Scene.hpp Normal file
View File

@ -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

View File

@ -3,17 +3,32 @@
namespace d2 namespace d2
{ {
/*static*/ std::unique_ptr<Game> Script::game = nullptr; /*static*/ std::unique_ptr<Game> 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() /*static*/ void Script::init()
{ {
scm_init_guile(); scm_init_guile();
scm_c_define_gsubr("winconf", 3, 0, 0, (void*) &fn_winconf); scm_c_define_gsubr("winconf", 3, 0, 0,
reinterpret_cast<void*>(&fn_winconf));
// Scenes
// ------
scm_c_define_gsubr("scene:push", 1, 1, 0,
reinterpret_cast<void*>(&fn_scene__push));
scm_c_define_gsubr("scene:pop", 0, 0, 0,
reinterpret_cast<void*>(&fn_scene__pop));
// Drawing // Drawing
// ------- // -------
scm_c_define_gsubr("rect", 4, 0, 0, (void*) &fn_rect); scm_c_define_gsubr("rect", 4, 0, 0, reinterpret_cast<void*>(&fn_rect));
scm_c_define_gsubr("color!", 4, 0, 0, (void*) &fn_set_color); scm_c_define_gsubr("color!", 4, 0, 0,
reinterpret_cast<void*>(&fn_set_color));
}
/*static*/ void Script::terminate()
{
Script::game.reset();
} }
/*static*/ void Script::run(std::filesystem::path conf_file) /*static*/ void Script::run(std::filesystem::path conf_file)
@ -41,6 +56,26 @@ namespace d2
return SCM_BOOL_T; 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<ScriptScene>(scm_function);
}
else
{
Script::game->push<ScriptScene>(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) /*static*/ SCM Script::fn_rect(SCM scm_x, SCM scm_y, SCM scm_w, SCM scm_h)
{ {
float x = scm_to_double(scm_x); float x = scm_to_double(scm_x);
@ -81,5 +116,4 @@ namespace d2
return SCM_BOOL_T; return SCM_BOOL_T;
} }
} }

View File

@ -4,22 +4,48 @@
#include "commons.hpp" #include "commons.hpp"
#include "Game.hpp" #include "Game.hpp"
#include "libguile/numbers.h"
namespace d2 namespace d2
{ {
struct Script struct Script
{ {
static void init(); static void init();
static void terminate();
static void run(std::filesystem::path conf_file); static void run(std::filesystem::path conf_file);
static SCM fn_winconf(SCM scm_title, SCM scm_width, SCM scm_height); 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_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_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: private:
static std::unique_ptr<Game> game; static std::unique_ptr<Game> game;
static glm::vec4 color; 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 #endif

View File

@ -4,8 +4,6 @@ namespace d2
{ {
/*explicit*/ Shader::Shader() /*explicit*/ Shader::Shader()
{ {
m_program = glCreateProgram();
load_shader(GL_VERTEX_SHADER, load_shader(GL_VERTEX_SHADER,
DUCK_ASSETS / "shaders" / "vertex.glsl"); DUCK_ASSETS / "shaders" / "vertex.glsl");
@ -98,13 +96,13 @@ namespace d2
char msg[SZ]; char msg[SZ];
glGetShaderInfoLog(shader, SZ, nullptr, msg); glGetShaderInfoLog(shader, SZ, nullptr, msg);
std::stringstream ss; std::stringstream ss2;
ss << "Cannot compile shader '" ss2 << "Cannot compile shader '"
<< source_path.string() << "'" << std::endl; << 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); glAttachShader(m_program, shader);

View File

@ -22,7 +22,7 @@ namespace d2
void set_matrix(std::string const& name, glm::mat4 matrix) const; void set_matrix(std::string const& name, glm::mat4 matrix) const;
private: private:
GLuint m_program; GLuint m_program = glCreateProgram();
GLuint load_shader(GLenum type, std::filesystem::path source_path); GLuint load_shader(GLenum type, std::filesystem::path source_path);
}; };

View File

@ -16,5 +16,7 @@ int main(int argc, char** argv)
d2::Script::run("main.scm"); d2::Script::run("main.scm");
} }
d2::Script::terminate();
return 0; return 0;
} }