✨ add simple scene declaration (push and pop state functions)
parent
21ca282619
commit
cd0d7bfea0
|
@ -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',
|
||||||
|
|
38
src/Game.cpp
38
src/Game.cpp
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
13
src/Game.hpp
13
src/Game.hpp
|
@ -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
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
#include "Scene.hpp"
|
||||||
|
|
||||||
|
namespace d2
|
||||||
|
{
|
||||||
|
/*explicit*/ Scene::Scene()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*virtual*/ Scene::~Scene()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue