summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/assets.cc17
-rw-r--r--src/assets.h23
-rw-r--r--src/context.h2
-rw-r--r--src/context_glfw.cc2
-rw-r--r--src/context_glfw.h2
-rw-r--r--src/context_null.h52
-rw-r--r--src/context_x11.cc2
-rw-r--r--src/context_x11.h3
-rw-r--r--src/engine.cc40
-rw-r--r--src/engine.h25
-rw-r--r--src/gl.cc59
-rw-r--r--src/gl.h10
-rw-r--r--src/json.cc61
-rw-r--r--src/json.h113
-rw-r--r--src/mauri.cc60
-rw-r--r--src/objects/effect.cc45
-rw-r--r--src/objects/effect.h9
-rw-r--r--src/objects/material.cc4
-rw-r--r--src/objects/material.h2
-rw-r--r--src/objects/model.cc16
-rw-r--r--src/objects/model.h11
-rw-r--r--src/objects/object.cc104
-rw-r--r--src/objects/object.h30
-rw-r--r--src/objects/pass.cc217
-rw-r--r--src/objects/pass.h29
-rw-r--r--src/objects/scene.cc33
-rw-r--r--src/objects/scene.h27
-rw-r--r--src/shader.cc151
-rw-r--r--src/shader.h27
-rw-r--r--src/texture.cc11
-rw-r--r--src/texture.h17
31 files changed, 751 insertions, 453 deletions
diff --git a/src/assets.cc b/src/assets.cc
index 71a9f26..cbc2e9e 100644
--- a/src/assets.cc
+++ b/src/assets.cc
@@ -19,7 +19,7 @@ Asset::Asset()
static Asset asset_void = Asset();
-Asset::Asset(std::string path, byte *begin, byte *end)
+Asset::Asset(const std::string &path, byte *begin, byte *end)
{
type = ASSET_SLICE;
size = end - begin;
@@ -28,7 +28,7 @@ Asset::Asset(std::string path, byte *begin, byte *end)
hash = std::hash<std::string>{}(path);
}
-Asset::Asset(std::string path)
+Asset::Asset(const std::string &path)
{
std::ifstream file(path, std::ios::binary | std::ios::ate);
@@ -66,7 +66,7 @@ Asset::~Asset()
}
}
-bool AssetManager::load_package(std::string path)
+bool AssetManager::load_package(const std::string &path)
{
pkg = new Asset(path);
@@ -103,16 +103,19 @@ bool AssetManager::load_package(std::string path)
files.push_back(
new Asset(std::string(file.path),
pkg->ptr() + file.offset,
- pkg->ptr() + file.offset + file.length));
-
+ pkg->ptr() + file.offset + file.length
+ )
+ );
log_debug("loaded file (%s)", std::string(file.path).c_str());
}
return true;
}
-Asset *AssetManager::get_file(std::string path, FileTypeHint hint)
+Asset *AssetManager::get_file(const std::string &part, FileTypeHint hint)
{
+ std::string path = part;
+
switch (hint)
{
case FileTypeHint::TEXTURE:
@@ -171,10 +174,12 @@ AssetManager::~AssetManager()
namespace Mauri
{
+
static AssetManager manager;
AssetManager *asset_manager()
{
return &manager;
}
+
} // namespace Mauri
diff --git a/src/assets.h b/src/assets.h
index 0c88a1a..14a76de 100644
--- a/src/assets.h
+++ b/src/assets.h
@@ -31,8 +31,8 @@ class Asset
{
public:
Asset();
- Asset(std::string path, byte *begin, byte *end);
- Asset(std::string path);
+ Asset(const std::string &path, byte *begin, byte *end);
+ Asset(const std::string &path);
~Asset();
@@ -43,14 +43,14 @@ class Asset
u32 size;
u64 hash;
- void seek(s32 n)
+ byte *ptr() const
{
- this->pos += n;
+ return &this->data[this->pos];
}
- byte *ptr() const
+ void seek(s32 n)
{
- return &this->data[this->pos];
+ this->pos += n;
}
void reset()
@@ -73,14 +73,17 @@ class Asset
return s;
}
- std::string as_string()
+ const std::string &as_string()
{
- return std::string((char *)this->ptr(), this->size);
+ if (_str.empty())
+ _str = std::string((char *)this->ptr(), this->size);
+ return _str;
}
private:
u32 pos;
byte *data;
+ std::string _str;
};
struct PkgFile
@@ -96,9 +99,9 @@ class AssetManager
AssetManager() {};
~AssetManager();
- bool load_package(std::string path);
+ bool load_package(const std::string &path);
- Asset *get_file(std::string path, FileTypeHint hint);
+ Asset *get_file(const std::string &part, FileTypeHint hint);
private:
Asset *pkg;
diff --git a/src/context.h b/src/context.h
index 09ba01e..8732631 100644
--- a/src/context.h
+++ b/src/context.h
@@ -13,7 +13,7 @@ namespace Mauri
class Context
{
public:
- Context(int width, int height, std::string name, bool wallpaper)
+ Context(int width, int height, const std::string &name, bool wallpaper)
: width(width), height(height) {}
virtual ~Context() {}
diff --git a/src/context_glfw.cc b/src/context_glfw.cc
index eca597e..136d124 100644
--- a/src/context_glfw.cc
+++ b/src/context_glfw.cc
@@ -46,7 +46,7 @@ double ContextGLFW::current_time()
return glfwGetTime();
}
-ContextGLFW::ContextGLFW(int width, int height, std::string name, bool wallpaper)
+ContextGLFW::ContextGLFW(int width, int height, const std::string &name, bool wallpaper)
: Context(width, height, name, wallpaper)
{
if (!glfwInit())
diff --git a/src/context_glfw.h b/src/context_glfw.h
index 30a60f2..de9f1d5 100644
--- a/src/context_glfw.h
+++ b/src/context_glfw.h
@@ -13,7 +13,7 @@ namespace Mauri
class ContextGLFW : public Context
{
public:
- ContextGLFW(int width, int height, std::string name, bool wallpaper);
+ ContextGLFW(int width, int height, const std::string &name, bool wallpaper);
~ContextGLFW();
void close_window();
diff --git a/src/context_null.h b/src/context_null.h
new file mode 100644
index 0000000..71c40cc
--- /dev/null
+++ b/src/context_null.h
@@ -0,0 +1,52 @@
+#ifndef _CONTEXT_NULL
+#define _CONTEXT_NULL
+
+#include "context.h"
+#include <stop_token>
+
+namespace Mauri
+{
+class ContextNull : public Context
+{
+public:
+ ContextNull(int width, int height, const std::string &name, bool wallpaper)
+ : Context(width, height, name, wallpaper) {}
+
+ ~ContextNull() {}
+
+ int width, height;
+
+ void resize_window(int width, int height) {}
+
+ void close_window()
+ {
+ _should_close = true;
+ }
+
+ bool should_close() const
+ {
+ return _should_close;
+ }
+
+ void swap_buffers() {}
+
+ void process_input() {}
+
+ void cursor_pos(float *x, float *y)
+ {
+ *y = 0.f;
+ *x = 0.f;
+ }
+
+ double current_time()
+ {
+ return 0.f;
+ }
+
+ private:
+ bool _should_close = true;
+};
+
+} // namespace Mauri
+
+#endif // _CONTEXT_NULL
diff --git a/src/context_x11.cc b/src/context_x11.cc
index b24eefb..b1e36ea 100644
--- a/src/context_x11.cc
+++ b/src/context_x11.cc
@@ -21,7 +21,7 @@ void ContextX11::disable_input()
0, NULL, &wmHint, NULL);
}
-ContextX11::ContextX11(int width, int height, std::string name, bool wallpaper)
+ContextX11::ContextX11(int width, int height, const std::string &name, bool wallpaper)
: Context(width, height, name, wallpaper)
{
x11_d = XOpenDisplay(NULL);
diff --git a/src/context_x11.h b/src/context_x11.h
index a90bdc1..a1a45a5 100644
--- a/src/context_x11.h
+++ b/src/context_x11.h
@@ -34,10 +34,9 @@ namespace Mauri {
class ContextX11 : public Context {
public:
- ContextX11(int width, int height, std::string name, bool wallpaper);
+ ContextX11(int width, int height, const std::string &name, bool wallpaper);
~ContextX11();
- bool create_window(int width, int height, std::string name, bool wallpaper);
void close_window();
void resize_window(int width, int height);
diff --git a/src/engine.cc b/src/engine.cc
index 2bca247..c956ba9 100644
--- a/src/engine.cc
+++ b/src/engine.cc
@@ -1,5 +1,6 @@
#include "engine.h"
#include "context.h"
+#include "json.h"
#include "shader.h"
#include "src/gl.h"
#include "texture.h"
@@ -46,11 +47,11 @@ void View::center(f32 w1, f32 h1)
camera_pos[1] = (scaled_height - h1) / -2.f;
}
-Engine::Engine(Scene *scene, Context *context)
- : context(context), scene(scene)
+Engine::Engine(Scene *scene, Context *context, Parser *parser)
+ : scene(scene), parser(parser), context(context)
{
- view.width = scene->width.value;
- view.height = scene->height.value;
+ view.width = scene->width;
+ view.height = scene->height;
view.texel_size[0] = 1.f / view.width;
view.texel_size[1] = 1.f / view.height;
@@ -60,9 +61,11 @@ Engine::Engine(Scene *scene, Context *context)
view.center(context->width, context->height);
- minimal_shader = new Shader("minimal");
+ minimal_shader = new Shader(parser, "minimal");
minimal_shader->compile();
+ texture_cache.reserve(100);
+
create_framebuffer(COMBINE_BUFFER, view.width, view.height, 1.f);
combine_buffer = get_framebuffer(COMBINE_BUFFER);
@@ -74,32 +77,32 @@ Engine::Engine(Scene *scene, Context *context)
scene->load(this);
}
-Texture *Engine::create_texture(Asset *asset)
+Texture *Engine::get_texture(Asset *asset)
{
for (auto &texture : texture_cache)
{
- if (texture->hash == asset->hash)
- return texture;
+ if (texture.hash == asset->hash)
+ return &texture;
}
- texture_cache.emplace_back(new Texture(asset));
+ texture_cache.emplace_back(Texture(asset));
- return texture_cache.back();
+ return &texture_cache.back();
}
-Framebuffer *Engine::get_framebuffer(std::string name)
+Framebuffer *Engine::get_framebuffer(const std::string &name)
{
return framebuffers[name];
}
-Texture *Engine::get_framebuffer_texture(std::string name)
+Texture *Engine::get_framebuffer_texture(const std::string &name)
{
return framebuffers[name]->texture;
}
void Engine::create_framebuffer(std::string name, f32 width, f32 height, f32 scale)
{
- framebuffers[name] = new Framebuffer(width, height, scale);
+ framebuffers[name] = new Framebuffer(name, width, height, scale);
}
void Engine::update()
@@ -135,9 +138,9 @@ void Engine::draw()
buffer.second->buffer->clear((vec4){0.f, 0.f, 0.f, 0.f});
}
- if (scene->clear_enabled.value)
+ if (scene->clear_enabled)
{
- combine_buffer->buffer->clear(scene->clear_color.value);
+ combine_buffer->buffer->clear(scene->clear_color);
}
scene->draw(this);
@@ -183,8 +186,15 @@ Engine::~Engine()
{
for (auto &buffer : framebuffers)
{
+ buffer.second->unload();
delete buffer.second;
}
+
+ for (auto &texture : texture_cache)
+ {
+ texture.unload();
+ }
+
delete default_object;
delete minimal_shader;
}
diff --git a/src/engine.h b/src/engine.h
index 5ecdd22..30d8d3a 100644
--- a/src/engine.h
+++ b/src/engine.h
@@ -41,14 +41,18 @@ struct View
class Engine
{
public:
- Engine(Scene *scene, Context *context);
+ Engine(Scene *scene, Context *context, Parser *parser);
~Engine();
- f32 time;
+ Scene *scene;
- View view;
+ Parser *parser;
Context *context;
+ View view;
+
+ f32 time;
+
RenderObject *default_object;
mat4x4 default_model;
@@ -56,9 +60,13 @@ class Engine
Shader *minimal_shader;
- std::vector<Texture *> texture_cache;
+ // Maximum textures that would be loaded by a wallpaper,
+ // bassed on information from the parsing stage.
+ u32 max_texture_count = 0;
+
+ std::vector<Texture> texture_cache;
- Texture *create_texture(Asset *asset);
+ Texture *get_texture(Asset *asset);
Framebuffer *combine_buffer;
@@ -66,15 +74,12 @@ class Engine
void create_framebuffer(std::string name, f32 width, f32 height, f32 scale);
- Framebuffer *get_framebuffer(std::string name);
- Texture *get_framebuffer_texture(std::string name);
+ Framebuffer *get_framebuffer(const std::string &name);
+ Texture *get_framebuffer_texture(const std::string &name);
void run();
void draw();
void update();
-
- private:
- Scene *scene;
};
} // namespace Mauri
diff --git a/src/gl.cc b/src/gl.cc
index c5988a7..f7291e6 100644
--- a/src/gl.cc
+++ b/src/gl.cc
@@ -9,9 +9,11 @@
using namespace Mauri;
+static bool gl_initialized = true;
+
void RenderObject::set_data(f32 *vertices, s32 vertex_count)
{
-#ifdef __DEBUG__
+#ifdef _DEBUG_
if (!gl_initialized) return;
#endif
@@ -32,7 +34,7 @@ void RenderObject::set_data(f32 *vertices, s32 vertex_count)
void RenderObject::bind()
{
-#ifdef __DEBUG__
+#ifdef _DEBUG_
if (!gl_initialized) return;
#endif
@@ -42,7 +44,7 @@ void RenderObject::bind()
RenderObject::RenderObject(RenderObjType type, f32 width, f32 height)
{
-#ifdef __DEBUG__
+#ifdef _DEBUG_
if (!gl_initialized) return;
#endif
@@ -94,7 +96,7 @@ RenderObject::RenderObject(RenderObjType type, f32 width, f32 height)
RenderObject::~RenderObject()
{
-#ifdef __DEBUG__
+#ifdef _DEBUG_
if (!gl_initialized) return;
#endif
@@ -104,8 +106,8 @@ RenderObject::~RenderObject()
bool RenderShader::compile(u32 program, const char *source, char *error)
{
-#ifdef __DEBUG__
- if (!gl_initialized) return;
+#ifdef _DEBUG_
+ if (!gl_initialized) return true;
#endif
glShaderSource(program, 1, &source, 0);
@@ -118,16 +120,15 @@ bool RenderShader::compile(u32 program, const char *source, char *error)
if (status == GL_FALSE)
{
glGetShaderInfoLog(program, 256, NULL, error);
- glDeleteShader(program);
return false;
}
return true;
}
-RenderShader::RenderShader(std::string vs_source, std::string fs_source)
+RenderShader::RenderShader(const std::string &vs_source, const std::string &fs_source)
{
-#ifdef __DEBUG__
+#ifdef _DEBUG_
if (!gl_initialized) return;
#endif
@@ -140,6 +141,7 @@ RenderShader::RenderShader(std::string vs_source, std::string fs_source)
if (!compile(vs_shader, vs_source.c_str(), error))
{
log_error("failed to compile vertex shader (%s)", error);
+ std::cout << vs_source << "\n";
return;
}
@@ -158,7 +160,7 @@ RenderShader::RenderShader(std::string vs_source, std::string fs_source)
void RenderShader::bind()
{
-#ifdef __DEBUG__
+#ifdef _DEBUG_
if (!gl_initialized) return;
#endif
@@ -167,17 +169,18 @@ void RenderShader::bind()
RenderShader::~RenderShader()
{
-#ifdef __DEBUG__
+#ifdef _DEBUG_
if (!gl_initialized) return;
#endif
- glDeleteShader(program);
+ if (program != 0)
+ glDeleteShader(program);
}
-s32 RenderShader::uniform_loc(std::string &name)
+s32 RenderShader::uniform_loc(const std::string &name)
{
-#ifdef __DEBUG__
- if (!gl_initialized) return;
+#ifdef _DEBUG_
+ if (!gl_initialized) return 0;
#endif
auto loc = uniform_locations.find(name);
@@ -191,9 +194,9 @@ s32 RenderShader::uniform_loc(std::string &name)
return loc->second;
}
-void RenderShader::set_uniform(std::string name, UniformType type, f32 *value)
+void RenderShader::set_uniform(const std::string &name, UniformType type, f32 *value)
{
-#ifdef __DEBUG__
+#ifdef _DEBUG_
if (!gl_initialized) return;
#endif
@@ -226,7 +229,7 @@ void RenderShader::set_uniform(std::string name, UniformType type, f32 *value)
void RenderTexture::bind(s32 index)
{
-#ifdef __DEBUG__
+#ifdef _DEBUG_
if (!gl_initialized) return;
#endif
@@ -236,7 +239,7 @@ void RenderTexture::bind(s32 index)
RenderTexture::RenderTexture(bool interp, bool clamp_uv, s32 mm_count)
{
-#ifdef __DEBUG__
+#ifdef _DEBUG_
if (!gl_initialized) return;
#endif
@@ -270,7 +273,7 @@ RenderTexture::RenderTexture(bool interp, bool clamp_uv, s32 mm_count)
void RenderTexture::upload(byte *data, s32 width, s32 height, s32 level, u32 format, bool scale, bool dxt)
{
-#ifdef __DEBUG__
+#ifdef _DEBUG_
if (!gl_initialized) return;
#endif
@@ -304,7 +307,7 @@ void RenderTexture::upload(byte *data, s32 width, s32 height, s32 level, u32 for
RenderTexture::~RenderTexture()
{
-#ifdef __DEBUG__
+#ifdef _DEBUG_
if (!gl_initialized) return;
#endif
@@ -314,7 +317,7 @@ RenderTexture::~RenderTexture()
RenderFramebuffer::RenderFramebuffer(f32 width0, f32 height0, f32 scale)
: width(width0 / scale), height(height0 / scale)
{
-#ifdef __DEBUG__
+#ifdef _DEBUG_
if (!gl_initialized) return;
#endif
@@ -332,7 +335,7 @@ RenderFramebuffer::RenderFramebuffer(f32 width0, f32 height0, f32 scale)
void RenderFramebuffer::bind()
{
-#ifdef __DEBUG__
+#ifdef _DEBUG_
if (!gl_initialized) return;
#endif
@@ -341,6 +344,10 @@ void RenderFramebuffer::bind()
void RenderFramebuffer::blit(u32 dest, f32 w0, f32 h0)
{
+#ifdef _DEBUG_
+ if (!gl_initialized) return;
+#endif
+
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dest);
glBindFramebuffer(GL_READ_FRAMEBUFFER, id);
glBlitFramebuffer(0, h0, w0, 0, 0, 0, w0, h0, GL_COLOR_BUFFER_BIT, GL_NEAREST);
@@ -348,13 +355,17 @@ void RenderFramebuffer::blit(u32 dest, f32 w0, f32 h0)
void RenderFramebuffer::clear(vec4 color)
{
+#ifdef _DEBUG_
+ if (!gl_initialized) return;
+#endif
+
glBindFramebuffer(GL_FRAMEBUFFER, id);
glClearBufferfv(GL_COLOR, 0, glm::value_ptr(color));
}
RenderFramebuffer::~RenderFramebuffer()
{
-#ifdef __DEBUG__
+#ifdef _DEBUG_
if (!gl_initialized) return;
#endif
diff --git a/src/gl.h b/src/gl.h
index f781b11..9bbeef9 100644
--- a/src/gl.h
+++ b/src/gl.h
@@ -13,10 +13,6 @@ using namespace glm;
namespace Mauri
{
-#ifdef __DEBUG__
-static bool gl_initialized = false;
-#endif
-
enum RenderObjType
{
DEFAULT,
@@ -52,13 +48,13 @@ class RenderObject
class RenderShader
{
public:
- RenderShader(std::string vs_source, std::string fs_source);
+ RenderShader(const std::string &vs_source, const std::string &fs_source);
~RenderShader();
bool compile(u32 program, const char *source, char *error);
- void set_uniform(std::string name, UniformType type, f32 *value);
- s32 uniform_loc(std::string &name);
+ void set_uniform(const std::string &name, UniformType type, f32 *value);
+ s32 uniform_loc(const std::string &name);
void bind();
diff --git a/src/json.cc b/src/json.cc
deleted file mode 100644
index 59c9a22..0000000
--- a/src/json.cc
+++ /dev/null
@@ -1,61 +0,0 @@
-#include "json.h"
-#include "util.h"
-
-namespace Mauri
-{
-
-template<typename T>
-JsonValue<T> get_value(json jvalue, JsonValueType type)
-{
- JsonValue<T> value;
-
- if (jvalue.is_object())
- {
- value.user = jvalue["user"];
- jvalue = value["value"];
- }
- else
- {
- value.user = "root";
- }
-
- switch (type)
- {
- case INT:
- if (jvalue.is_number())
- value.value = jvalue.get<u32>();
- break;
- case FLOAT:
- if (jvalue.is_number())
- value.value = jvalue.get<f32>();
- break;
- case STRING:
- if (jvalue.is_string())
- value.value = jvalue.get<std::string>();
- break;
- case VEC2:
- if (jvalue.is_string())
- str_vec2(jvalue.get<std::string>(), value.value);
- break;
- case VEC3:
- if (jvalue.is_string())
- str_vec3(jvalue.get<std::string>(), value.value);
- break;
- case VEC4:
- // special case for because VEC4 is used for all
- // uniform values and some can be a single float
- if (jvalue.is_number())
- value.value[0] = jvalue.get<f32>();
- else if (jvalue.is_string())
- str_vec4(jvalue.get<std::string>(), value.value);
- break;
- case BOOL:
- if (jvalue.is_boolean())
- value.value = jvalue.get<bool>();
- break;
- }
-
- return value;
-}
-
-}
diff --git a/src/json.h b/src/json.h
index 9ed44c9..78556c7 100644
--- a/src/json.h
+++ b/src/json.h
@@ -2,8 +2,14 @@
#define _JSON_H
#include <cstdio>
+#include <iostream>
#include <nlohmann/json.hpp>
+#include <glm/glm.hpp>
+#include <unordered_map>
+#include "util.h"
+
+using namespace glm;
using namespace nlohmann;
#define str_vec4(s, v) sscanf(s, "%f %f %f %f", &(v)[0], &(v)[1], &(v)[2], &(v)[3])
@@ -23,21 +29,110 @@ enum JsonValueType
STRING
};
-template <typename T>
struct JsonValue
{
- JsonValue() {}
- JsonValue(T value)
- : user("root"), value(value)
+ JsonValueType type;
+ void *v;
+ std::string name;
+};
+
+class Parser
+{
+ public:
+ template<typename T>
+ void get_value(json &root, const std::string &name, void *res, const T &_default)
{
+ json jvalue;
+
+ if (name.empty())
+ jvalue = root;
+ else
+ jvalue = root[name];
+
+ std::string user;
+
+ if (jvalue.is_object())
+ {
+ auto _user = jvalue["user"];
+ if (_user.is_string())
+ user = _user;
+ jvalue = jvalue["value"];
+ }
+ else
+ user = "root";
+
+ *((T *)res) = _default;
+
+ JsonValueType type;
+
+ if (std::is_same<T, u32>::value)
+ {
+ if (jvalue.is_number())
+ {
+ *((u32 *)res) = jvalue.get<u32>();
+ }
+ type = INT;
+ }
+ else if (std::is_same<T, f32>::value)
+ {
+ if (jvalue.is_number())
+ {
+ *((f32 *)res) = jvalue.get<f32>();
+ }
+ type = FLOAT;
+ }
+ else if (std::is_same<T, std::string>::value)
+ {
+ if (jvalue.is_string())
+ {
+ *((std::string *)res) = jvalue.get<std::string>();
+ }
+ type = STRING;
+ }
+ else if (std::is_same<T, vec2>::value)
+ {
+ if (jvalue.is_string())
+ {
+ str_vec2(jvalue.get<std::string>().c_str(), *((vec2 *)res));
+ }
+ type = VEC2;
+ }
+ else if (std::is_same<T, vec3>::value)
+ {
+ if (jvalue.is_string())
+ {
+ str_vec3(jvalue.get<std::string>().c_str(), *((vec3 *)res));
+ }
+ type = VEC3;
+ }
+ else if (std::is_same<T, vec4>::value)
+ {
+ // Special case for because VEC4 is used for all
+ // uniform values and some are written as a single number, not a string.
+ if (jvalue.is_number())
+ {
+ (*((vec4 *)res))[0] = jvalue.get<f32>();
+ }
+ else if (jvalue.is_string())
+ {
+ str_vec4(jvalue.get<std::string>().c_str(), *((vec4 *)res));
+ }
+ type = VEC4;
+ }
+ else if (std::is_same<T, bool>::value)
+ {
+ if (jvalue.is_boolean())
+ {
+ *((bool *)res) = jvalue.get<bool>();
+ }
+ type = BOOL;
+ }
+
+ values[user].push_back(JsonValue { type, res, name });
}
- std::string user;
- T value;
+ std::unordered_map<std::string, std::vector<JsonValue>> values;
};
-
-template <typename T>
-extern JsonValue<T> get_value(json jvalue, JsonValueType type);
} // namespace Mauri
diff --git a/src/mauri.cc b/src/mauri.cc
index e8a509e..f4c910d 100644
--- a/src/mauri.cc
+++ b/src/mauri.cc
@@ -1,11 +1,13 @@
#include "assets.h"
#include "engine.h"
#include "gl.h"
+#include "json.h"
#include "util.h"
#include "context.h"
#include "context_glfw.h"
#include "context_x11.h"
+#include "context_null.h"
#include "objects/scene.h"
@@ -13,20 +15,17 @@
using namespace Mauri;
-static std::string scene_path = std::string("scene.json");
+static std::string scene_path = "scene.json";
s32 main(s32 argc, char *argv[])
{
srand(time(NULL));
-#ifdef __DEBUG__
- gl_initialized = true;
-#endif
-
//Context *context = new ContextX11(2560, 1440, "mauri", true);
//Context *context = new ContextGLFW(720, 1280, "mauri", false);
- //Context *context = new ContextGLFW(810, 1440, "mauri", false);
- Context *context = new ContextX11(2560, 1440, "mauri", true);
+ //Context *context = new ContextGLFW(1920, 1080, "mauri", false);
+ Context *context = new ContextX11(1920, 1080, "mauri", false);
+ //Context *context = new ContextNull(1920, 1080, "mauri", false);
if (argc == 2)
{
@@ -36,11 +35,52 @@ s32 main(s32 argc, char *argv[])
return 1;
}
- Scene *scene = new Scene(scene_path);
+ Parser parser;
- //context->resize_window(scene->width, scene->height);
+ Scene *scene = new Scene(parser, scene_path);
+
+ Engine engine(scene, context, &parser);
+
+ bool *visible;
+
+ for (auto &user : parser.values)
+ {
+ std::cout << user.first << ":\n";
+ for (auto &value : user.second)
+ {
+ std::cout << "\t" << value.name << ": ";
+ switch (value.type)
+ {
+ case INT:
+ std::cout << *((u32 *)value.v);
+ break;
+ case FLOAT:
+ std::cout << *((f32 *)value.v);
+ break;
+ case VEC2:
+ std::cout << (*((vec2 *)value.v))[0];
+ break;
+ case VEC3:
+ std::cout << (*((vec3 *)value.v))[0];
+ break;
+ case VEC4:
+ std::cout << (*((vec4 *)value.v))[0];
+ break;
+ case BOOL:
+ std::cout << *((bool *)value.v);
+ break;
+ case STRING:
+ std::cout << *((std::string *)value.v);
+ break;
+ }
+
+ std::cout << "\n";
+ }
+ }
- Engine engine(scene, context);
+ *visible = false;
+
+ //context->resize_window(scene->width, scene->height);
engine.run();
diff --git a/src/objects/effect.cc b/src/objects/effect.cc
index bc94c17..fb1f4e3 100644
--- a/src/objects/effect.cc
+++ b/src/objects/effect.cc
@@ -16,15 +16,15 @@
using namespace Mauri;
-Effect::Effect(json root)
+Effect::Effect(Parser &p, json &root)
{
- id = get_value<u32>(root["id"], INT);
+ p.get_value<u32>(root, "id", &id, 0);
- visible = get_value<bool>(root["visible"], BOOL);
+ p.get_value<bool>(root, "visible", &visible, true);
for (auto &pass0 : root["passes"])
{
- passes0.emplace_back(new Pass(pass0, EFFECT0_PASS));
+ passes0.emplace_back(new Pass(p, pass0, EFFECT0_PASS));
}
auto asset = asset_manager()->get_file(root["file"], NONE);
@@ -34,11 +34,11 @@ Effect::Effect(json root)
auto file = json::parse(asset->as_string());
- name = get_value<std::string>(file["name"], STRING);
+ p.get_value<std::string>(file, "name", &name, "");
for (auto &pass1 : file["passes"])
{
- passes1.emplace_back(new Pass(pass1, EFFECT1_PASS));
+ passes1.emplace_back(new Pass(p, pass1, EFFECT1_PASS));
}
for (auto &fbo : file["fbos"])
@@ -49,14 +49,15 @@ Effect::Effect(json root)
void Effect::load(Engine *engine, Object *object, bool last_effect)
{
- buffer_id = fmt::format("{}_{}", id.value, object->id.value);
+ buffer_id = fmt::format("_{}_{}", object->id, id);
for (auto &fbo : fbos)
{
- engine->create_framebuffer(fbo.name + buffer_id, object->size.value[0],
- object->size.value[1], fbo.scale);
+ engine->create_framebuffer(fbo.name + buffer_id, object->size[0],
+ object->size[1], fbo.scale);
}
+ /*
for (u32 i = 0; i < passes0.size(); i++)
{
Pass *pass = new Pass();
@@ -71,11 +72,35 @@ void Effect::load(Engine *engine, Object *object, bool last_effect)
this->passes.push_back(new RenderPass(engine, pass));
}
+ */
+
+ u32 index = 0;
+
+ for (u32 i = 0; i < passes1.size(); i++)
+ {
+ Pass *pass = new Pass();
+
+ pass->combine = (i == (passes1.size() - 1)) && last_effect;
+
+ pass->object = object;
+ pass->effect = this;
+
+ if (passes1[i]->command == COPY)
+ passes1[i]->load(engine, EFFECT1_PASS, pass);
+ else
+ {
+ passes0[index]->load(engine, EFFECT0_PASS, pass);
+ passes1[i]->load(engine, EFFECT1_PASS, pass);
+ index++;
+ }
+
+ this->passes.push_back(new RenderPass(engine, pass));
+ }
}
void Effect::draw(Engine *engine)
{
- if (!visible.value)
+ if (!visible)
return;
for (auto &pass : passes)
diff --git a/src/objects/effect.h b/src/objects/effect.h
index 29b4bb7..713c36f 100644
--- a/src/objects/effect.h
+++ b/src/objects/effect.h
@@ -4,6 +4,7 @@
#include <vector>
#include "engine.h"
+#include "texture.h"
namespace Mauri
{
@@ -20,11 +21,11 @@ struct EffectBuffer
class Effect
{
public:
- Effect(json root);
+ Effect(Parser &p, json &root);
~Effect();
- JsonValue<u32> id;
- JsonValue<std::string> name;
+ u32 id;
+ std::string name;
std::string buffer_id;
@@ -32,7 +33,7 @@ class Effect
void draw(Engine *engine);
private:
- JsonValue<bool> visible;
+ bool visible;
std::vector<Pass *> passes0;
std::vector<Pass *> passes1;
diff --git a/src/objects/material.cc b/src/objects/material.cc
index 699c603..ae25cee 100644
--- a/src/objects/material.cc
+++ b/src/objects/material.cc
@@ -11,7 +11,7 @@
using namespace Mauri;
-Material::Material(std::string path)
+Material::Material(Parser &p, const std::string &path)
{
auto asset = asset_manager()->get_file(path, NONE);
@@ -25,7 +25,7 @@ Material::Material(std::string path)
for (auto &pass : root["passes"])
{
- passes0.push_back(new Pass(pass, MATERIAL_PASS));
+ passes0.push_back(new Pass(p, pass, MATERIAL_PASS));
}
}
diff --git a/src/objects/material.h b/src/objects/material.h
index c27c720..0e46f7f 100644
--- a/src/objects/material.h
+++ b/src/objects/material.h
@@ -20,7 +20,7 @@ enum MaterialType
class Material
{
public:
- Material(std::string path);
+ Material(Parser &p, const std::string &path);
~Material();
void load(Engine *engine, Object *object, MaterialType type, Pass *pass, bool no_effects);
diff --git a/src/objects/model.cc b/src/objects/model.cc
index 0574a92..f450d34 100644
--- a/src/objects/model.cc
+++ b/src/objects/model.cc
@@ -9,7 +9,7 @@
using namespace Mauri;
-Model::Model(std::string path)
+Model::Model(Parser &p, const std::string &path)
{
auto asset = asset_manager()->get_file(path, NONE);
@@ -21,11 +21,17 @@ Model::Model(std::string path)
auto root = json::parse(asset->as_string());
- autosize = get_value<bool>(root["autosize"], BOOL);
- fullscreen = get_value<bool>(root["fullscreen"], BOOL);
- passthrough = get_value<bool>(root["passthrough"], BOOL);
+ p.get_value<bool>(root, "autosize", &autosize, false);
+ p.get_value<bool>(root, "fullscreen", &fullscreen, false);
+ p.get_value<bool>(root, "passthrough", &passthrough, false);
- material = new Material(root["material"]);
+ p.get_value<f32>(root, "width", &width, 0.f);
+ p.get_value<f32>(root, "height", &height, 0.f);
+
+ auto _material = root["material"];
+
+ if (_material.is_string())
+ material = new Material(p, _material);
}
void Model::load(Engine *engine, Object *object, bool no_effects)
diff --git a/src/objects/model.h b/src/objects/model.h
index 9e67f07..e4a55ea 100644
--- a/src/objects/model.h
+++ b/src/objects/model.h
@@ -14,12 +14,15 @@ namespace Mauri
class Model
{
public:
- Model(std::string path);
+ Model(Parser &p, const std::string &path);
~Model();
- JsonValue<bool> autosize;
- JsonValue<bool> fullscreen;
- JsonValue<bool> passthrough;
+ bool autosize = true;
+ bool fullscreen = false;
+ bool passthrough = false;
+
+ f32 width;
+ f32 height;
void load(Engine *engine, Object *object, bool no_effects);
diff --git a/src/objects/object.cc b/src/objects/object.cc
index a41cfaa..efd3155 100644
--- a/src/objects/object.cc
+++ b/src/objects/object.cc
@@ -12,6 +12,7 @@
#include "../json.h"
#include "../log.h"
+#include "fmt/format.h"
#include "objects/effect.h"
#include "objects/model.h"
#include "objects/object.h"
@@ -20,34 +21,37 @@
using namespace Mauri;
-Object::Object(json root)
+Object::Object(Parser &p, json &root)
{
- id = get_value<u32>(root["id"], INT);
- name = get_value<std::string>(root["id"], STRING);
+ p.get_value<u32>(root, "id", &id, 0);
+ p.get_value<std::string>(root, "name", &name, "");
for (auto &id : root["dependencies"])
deps.push_back(id);
- angles = get_value<vec3>(root["angles"], VEC3);
- color = get_value<vec3>(root["colors"], VEC3);
- size = get_value<vec2>(root["size"], VEC2);
- scale = get_value<vec3>(root["size"], VEC3);
- origin = get_value<vec3>(root["origin"], VEC3);
+ p.get_value<vec3>(root, "angles", &angles, vec3(0.f));
+ p.get_value<vec3>(root, "color", &color, vec3(0.f));
+ p.get_value<vec2>(root, "size", &size, vec2(0.f));
+ p.get_value<vec3>(root, "scale", &scale, vec3(0.f));
+ p.get_value<vec3>(root, "origin", &origin, vec3(0.f));
- color_blend_mode = (BlendMode)root["colorblendmode"];
+ p.get_value<u32>(root, "colorblendmode", &color_blend_mode, 0);
- visible = get_value<bool>(root["visible"], BOOL);
+ p.get_value<bool>(root, "visible", &visible, true);
- image = new Model(root["image"]);
+ auto _image = root["image"];
+
+ if (_image.is_string())
+ image = new Model(p, _image);
auto config = root["config"];
if (!config.is_null())
- passthrough = get_value<bool>(config["passthrough"], BOOL);
+ p.get_value<bool>(config, "passthrough", &passthrough, false);
for (auto &effect : root["effects"])
{
- effects.emplace_back(new Effect(effect));
+ effects.emplace_back(new Effect(p, effect));
}
}
@@ -57,13 +61,13 @@ void Object::get_model(f32 width, f32 height, bool flip)
model = glm::translate(model, (vec3){-width, -height, 0.f});
- model = glm::translate(model, origin.value * 2.f);
+ model = glm::translate(model, origin * 2.f);
- model = glm::scale(model, scale.value);
+ model = glm::scale(model, scale);
- model = glm::rotate(model, angles.value[0], (vec3){1.f, 0.f, 0.f});
- model = glm::rotate(model, angles.value[1], (vec3){0.f, 1.f, 0.f});
- model = glm::rotate(model, angles.value[2], (vec3){0.f, 0.f, 1.f});
+ model = glm::rotate(model, angles[0], (vec3){1.f, 0.f, 0.f});
+ model = glm::rotate(model, angles[1], (vec3){0.f, 1.f, 0.f});
+ model = glm::rotate(model, angles[2], (vec3){0.f, 0.f, 1.f});
mat4x4 _ortho = glm::ortho(-width, width, height, -height, 0.f, 1.f);
@@ -80,32 +84,47 @@ void Object::load(Engine *engine)
if (loaded)
return;
+ for (auto &dep : deps)
+ {
+ if (dep == id)
+ continue;
+ auto dep_object = engine->scene->get_object_by_id(dep);
+ if (dep_object != nullptr)
+ dep_object->load(engine);
+ }
+
+
if (image != nullptr)
{
- if (image->passthrough.value)
+ if (image->passthrough)
passthrough = true;
- if (image->fullscreen.value || passthrough.value)
- {
- if (size.value[0] == 0 && size.value[1] == 0)
- {
- size.value[0] = engine->view.width;
- size.value[1] = engine->view.height;
- origin.value[0] = size.value[0] / 2.f;
- origin.value[1] = size.value[1] / 2.f;
- }
+ if (image->fullscreen)
fullscreen = true;
+
+ if (image->width != 0.f && image->height != 0.f)
+ {
+ size[0] = image->width;
+ size[1] = image->height;
}
}
- auto width = size.value[0];
- auto height = size.value[1];
+ if (size[0] == 0 && size[1] == 0)
+ {
+ size[0] = engine->view.width;
+ size[1] = engine->view.height;
+ origin[0] = size[0] / 2.f;
+ origin[1] = size[1] / 2.f;
+ }
- abuffer = fmt::format("_rt_imageLayerComposite_{}_a", this->id.value);
- bbuffer = fmt::format("_rt_imageLayerComposite_{}_b", this->id.value);
+ auto width = size[0];
+ auto height = size[1];
- engine->create_framebuffer(abuffer, width, height, 1.f);
- engine->create_framebuffer(bbuffer, width, height, 1.f);
+ buffer_a = fmt::format("_rt_imageLayerComposite_{}_a", id);
+ buffer_b = fmt::format("_rt_imageLayerComposite_{}_b", id);
+
+ engine->create_framebuffer(buffer_a, width, height, 1.f);
+ engine->create_framebuffer(buffer_b, width, height, 1.f);
get_model(engine->view.width, engine->view.height, effects.size() == 0);
@@ -114,7 +133,8 @@ void Object::load(Engine *engine)
gl_object = new RenderObject(OBJECT, width, height);
gl_uv_object = new RenderObject(UV_SCALE, width, height);
- image->load(engine, this, effects.size() == 0);
+ if (image != nullptr)
+ image->load(engine, this, effects.size() == 0);
for (u32 i = 0; i < effects.size(); i++)
{
@@ -133,8 +153,14 @@ void Object::update(Engine *engine)
void Object::draw(Engine *engine)
{
- if (!visible.value)
- return;
+ //for (auto &dep : deps)
+ //{
+ // if (dep == id)
+ // continue;
+ // auto dep_object = engine->scene->get_object_by_id(dep);
+ // if (dep_object != nullptr)
+ // dep_object->draw(engine);
+ //}
for (auto &pass : passes)
{
@@ -149,12 +175,12 @@ void Object::draw(Engine *engine)
std::string Object::get_target_buffer() const
{
- return (buffer_switch) ? abuffer : bbuffer;
+ return (buffer_switch) ? buffer_a : buffer_b;
}
std::string Object::get_texture_buffer() const
{
- return (buffer_switch) ? bbuffer : abuffer;
+ return (buffer_switch) ? buffer_b : buffer_a;
}
Object::~Object()
diff --git a/src/objects/object.h b/src/objects/object.h
index 14b6615..37dd2df 100644
--- a/src/objects/object.h
+++ b/src/objects/object.h
@@ -28,18 +28,20 @@ enum BlendMode
class Object
{
public:
- Object(json root);
+ Object(Parser &p, json &root);
~Object();
- JsonValue<u32> id;
- JsonValue<std::string> name;
+ u32 id;
+ std::string name;
+
+ bool visible;
std::vector<int> deps;
- JsonValue<bool> passthrough;
- JsonValue<bool> fullscreen;
+ bool passthrough = false;
+ bool fullscreen = false;
- JsonValue<vec2> size;
+ vec2 size;
void get_model(f32 width, f32 height, bool flip);
@@ -49,7 +51,7 @@ class Object
RenderObject *gl_uv_object = nullptr;
RenderObject *gl_object = nullptr;
- BlendMode color_blend_mode;
+ u32 color_blend_mode;
std::string get_target_buffer() const;
std::string get_texture_buffer() const;
@@ -66,18 +68,16 @@ class Object
void draw(Engine *engine);
private:
- JsonValue<bool> visible;
-
Model *image = nullptr;
- JsonValue<vec3> angles;
- JsonValue<vec3> color;
+ vec3 angles;
+ vec3 color;
- JsonValue<vec3> origin;
- JsonValue<vec3> scale;
+ vec3 origin;
+ vec3 scale;
- std::string abuffer;
- std::string bbuffer;
+ std::string buffer_a;
+ std::string buffer_b;
bool buffer_switch = false;
diff --git a/src/objects/pass.cc b/src/objects/pass.cc
index 333694a..24fc868 100644
--- a/src/objects/pass.cc
+++ b/src/objects/pass.cc
@@ -1,6 +1,8 @@
+#include <cstdio>
#include <fmt/core.h>
#include <glm/fwd.hpp>
#include <glm/gtc/type_ptr.hpp>
+#include <stdint.h>
#include <thread>
#include <type_traits>
@@ -20,28 +22,48 @@
using namespace Mauri;
-Pass::Pass(json root, PassStage stage)
+Pass::Pass(Parser &p, json &root, PassStage stage)
{
switch (stage)
{
case EFFECT0_PASS: {
- for (auto &value : root["constantshadervalues"].items())
+ auto _uniforms = root["constantshadervalues"];
+
+ for (auto &value : _uniforms.items())
{
- // In this case type and uname are irrelevant because this is only used to
- // override the value stored on the shader which contains the type and uname.
- uniforms.push_back(Uniform(value.key(), get_value<vec4>(value.value(), VEC4)));
+ // Type and uname don't matter because they are stored on the shader.
+ uniforms.emplace_back(
+ new UniformOverride({ vec4(0.f), value.key() })
+ );
+ p.get_value<vec4>(_uniforms, value.key(), &uniforms.back()->value, vec4(0.f));
}
break;
}
case EFFECT1_PASS: {
- material = new Material(root["material"]);
+ auto _material = root["material"];
+
+ if (_material.is_string())
+ material = new Material(p, _material);
+
+ auto _command = root["command"];
+
+ if (_command.is_string())
+ {
+ if (_command == "copy")
+ command = COPY;
+ }
auto _target = root["target"];
if (_target.is_string())
target = _target;
+ auto _source = root["source"];
+
+ if (_source.is_string())
+ source = _source;
+
for (auto &bind : root["bind"])
{
u32 index = bind["index"];
@@ -53,36 +75,20 @@ Pass::Pass(json root, PassStage stage)
case MATERIAL_ONLY_PASS:
target = "previous";
[[fallthrough]];
- case MATERIAL_PASS: {
+ case MATERIAL_PASS:
shader = root["shader"];
-
- //auto blending = root.get("blending", "normal").asString();
-
- //if (blending == "normal")
- // blend = NORMAL;
- //else if (blending == "translucent")
- // blend = TRANSLUCENT;
-
break;
}
- }
- for (int i = 0; i < 8; i++)
+ auto _textures = root["textures"];
+
+ for (int i = 0; i < _textures.size(); i++)
{
- auto texture = root["textures"][i];
- if (texture.is_string())
- textures[i] = texture;
+ auto _texture = _textures[i];
+ if (_texture.is_string())
+ textures[i] = _texture;
}
- //auto _textures = root["textures"];
-
- //for (int i = 0; i < _textures.size(); i++)
- //{
- // auto texture = _textures[i];
- // if (texture.is_string())
- // textures[i] = texture;
- //}
-
for (auto &combo : root["combos"].items())
{
combos.emplace_back((Combo) { combo.key(), combo.value() });
@@ -97,6 +103,8 @@ void Pass::load(Engine *engine, PassStage stage, Pass *pass)
continue;
pass->textures[i] = textures[i];
+
+ //engine->max_texture_count++;
}
for (auto &combo : combos)
@@ -113,6 +121,9 @@ void Pass::load(Engine *engine, PassStage stage, Pass *pass)
}
break;
case EFFECT1_PASS:
+ pass->command = command;
+
+ pass->source = source + pass->effect->buffer_id;
pass->target = target;
if (pass->target == "previous")
@@ -168,10 +179,22 @@ Pass::~Pass()
RenderPass::RenderPass(Engine *engine, Pass *pass)
{
+ command = pass->command;
+
+ if (command == COPY)
+ {
+ target = engine->get_framebuffer(pass->target);
+ source = engine->get_framebuffer(pass->source);
+
+ return;
+ }
+
+ object = pass->object;
+
combine = pass->combine;
- combine_blend = pass->object->color_blend_mode;
+ combine_blend = (BlendMode)pass->object->color_blend_mode;
- shader = new Shader(pass->shader);
+ shader = new Shader(engine->parser, pass->shader);
for (int i = 0; i < 8; i++)
{
@@ -184,36 +207,62 @@ RenderPass::RenderPass(Engine *engine, Pass *pass)
auto asset = asset_manager()->get_file(pass->textures[i], TEXTURE);
if (asset->type != ASSET_VOID)
- textures[i] = engine->create_texture(asset);
+ textures[i] = engine->get_texture(asset);
else
textures[i] = engine->get_framebuffer_texture(pass->textures[i]);
}
- for (auto &uniform : shader->uniforms)
+ for (auto &shader_uniform : shader->uniforms)
{
- // ex: g_Texture2Resolution (vec4)
- // ^ index
- if (uniform.uname.compare(0, 9, "g_Texture") == 0 &&
- uniform.uname.compare(10, 10, "Resolution") == 0)
+ auto default_value = true;
+ for (auto &uniform_override : pass->uniforms)
{
- auto index = uniform.uname[9] - '0';
- if (textures[index] != nullptr)
- uniform.value = textures[index]->texture_resolution;
+ if (shader_uniform->name.empty())
+ continue;
+ if (shader_uniform->name == uniform_override->name)
+ {
+ shader_uniform->value = &uniform_override->value;
+ default_value = false;
+ break;
+ }
}
+ if (default_value)
+ shader_uniform->value = &shader_uniform->default_value;
}
- for (auto &pass_uniform : pass->uniforms)
+ /*
+ for (auto &shader_uniform : shader->uniforms)
{
- for (auto &shader_uniform : shader->uniforms)
+ auto add = true;
+ for (auto &pass_uniform : pass->uniforms)
{
- if (shader_uniform.name.empty())
+ if (shader_uniform->name.empty())
continue;
- if (pass_uniform.name == shader_uniform.name)
+ if (pass_uniform->name == shader_uniform->name)
{
- shader_uniform.value = pass_uniform.value;
+ pass_uniform->uname = shader_uniform->uname;
+ pass_uniform->type = shader_uniform->type;
+ add = false;
+ delete shader_uniform;
break;
}
}
+ if (add)
+ pass->uniforms.push_back(shader_uniform);
+ }
+ */
+
+ for (auto &uniform : shader->uniforms)
+ {
+ // ex: g_Texture2Resolution (vec4)
+ // ^ index
+ if (uniform->uname.compare(0, 9, "g_Texture") == 0 &&
+ uniform->uname.compare(10, 10, "Resolution") == 0)
+ {
+ auto index = uniform->uname[9] - '0';
+ if (textures[index] != nullptr)
+ uniform->value = &textures[index]->texture_resolution;
+ }
}
for (auto &combo : shader->combos)
@@ -247,19 +296,23 @@ RenderPass::RenderPass(Engine *engine, Pass *pass)
if (pass->effect == nullptr)
{
- if (pass->object->passthrough.value || combine)
+ if (pass->object->fullscreen)
+ model = &engine->default_model;
+ else if (pass->object->passthrough || combine)
model = &pass->object->model;
else
model = &pass->object->ortho;
- if (pass->object->passthrough.value)
+ if (pass->object->fullscreen)
+ robject = engine->default_object;
+ else if (pass->object->passthrough)
robject = pass->object->gl_object;
else
robject = pass->object->gl_uv_object;
}
else
{
- if (combine)
+ if (combine && !pass->object->fullscreen)
{
robject = pass->object->gl_object;
model = &pass->object->model;
@@ -274,45 +327,55 @@ RenderPass::RenderPass(Engine *engine, Pass *pass)
void RenderPass::draw(Engine *engine)
{
- target->buffer->bind();
- shader->bind(engine, model);
+ switch (command) {
+ case DRAW: {
+ target->buffer->bind();
- robject->bind();
+ shader->bind(engine, model);
+ robject->bind();
- for (int i = 0; i < shader->texture_count; i++)
- {
- if (textures[i] != nullptr)
- textures[i]->bind(i);
- }
+ for (int i = 0; i < shader->texture_count; i++)
+ {
+ if (textures[i] != nullptr)
+ textures[i]->bind(i);
+ }
- BlendMode blend;
+ BlendMode blend;
- if (combine)
- blend = combine_blend;
- else
- blend = NORMAL;
+ if (combine)
+ blend = combine_blend;
+ else
+ blend = NORMAL;
- switch (blend)
- {
- case NORMAL:
- glBlendFunc(GL_ONE, GL_ZERO);
- glColorMask(1.f, 1.f, 1.f, 1.f);
- break;
- case TRANSLUCENT:
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glColorMask(1.f, 1.f, 1.f, 0.f);
- break;
- }
+ switch (blend)
+ {
+ case NORMAL:
+ glBlendFunc(GL_ONE, GL_ZERO);
+ glColorMask(1.f, 1.f, 1.f, 1.f);
+ break;
+ case TRANSLUCENT:
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glColorMask(1.f, 1.f, 1.f, 0.f);
+ break;
+ }
- engine->view.default_viewport(target->buffer->width, target->buffer->height);
+ engine->view.default_viewport(target->buffer->width, target->buffer->height);
- glDrawArrays(GL_TRIANGLES, 0, 6);
+ glDrawArrays(GL_TRIANGLES, 0, 6);
#if 0
- target->buffer->blit(0, engine->context->width, engine->context->height);
- engine->context->swap_buffers();
- std::this_thread::sleep_for(std::chrono::seconds(1));
+ target->buffer->blit(0, engine->context->width, engine->context->height);
+
+ engine->context->swap_buffers();
+ std::this_thread::sleep_for(std::chrono::seconds(1));
#endif
+
+ break;
+ }
+ case COPY:
+ source->buffer->blit(target->buffer->id, source->buffer->width, source->buffer->height);
+ break;
+ }
}
RenderPass::~RenderPass()
diff --git a/src/objects/pass.h b/src/objects/pass.h
index 78de015..ff03a05 100644
--- a/src/objects/pass.h
+++ b/src/objects/pass.h
@@ -24,17 +24,32 @@ enum PassStage
MATERIAL_ONLY_PASS
};
+enum PassCommand
+{
+ DRAW,
+ COPY
+};
+
+struct UniformOverride
+{
+ vec4 value;
+ std::string name;
+};
+
class RenderPass;
class Pass
{
public:
Pass() {}
- Pass(json root, PassStage stage);
+ Pass(Parser &p, json &root, PassStage stage);
~Pass();
- std::string target;
+ PassCommand command = DRAW;
+
+ std::string target = "previous";
+ std::string source;
Object *object;
Effect *effect;
@@ -46,7 +61,7 @@ class Pass
bool combine;
- std::vector<Uniform> uniforms;
+ std::vector<UniformOverride *> uniforms;
std::vector<Combo> combos;
void load(Engine *engine, PassStage stage, Pass *pass);
@@ -64,8 +79,14 @@ class RenderPass
void draw(Engine *engine);
private:
- Shader *shader;
+ PassCommand command;
+
+ Object *object;
+
+ Shader *shader = nullptr;
+
Framebuffer *target;
+ Framebuffer *source;
mat4x4 *model;
RenderObject *robject;
diff --git a/src/objects/scene.cc b/src/objects/scene.cc
index 1e95f4b..afb1e69 100644
--- a/src/objects/scene.cc
+++ b/src/objects/scene.cc
@@ -11,7 +11,7 @@
using namespace Mauri;
-Scene::Scene(std::string path)
+Scene::Scene(Parser &p, const std::string &path)
{
auto asset = asset_manager()->get_file(path, NONE);
@@ -25,25 +25,23 @@ Scene::Scene(std::string path)
auto camera = root["camera"];
- cam.center = get_value<vec3>(camera["center"], VEC3);
- cam.eye = get_value<vec3>(camera["eye"], VEC3);
- cam.up = get_value<vec3>(camera["up"], VEC3);
+ p.get_value<vec3>(camera, "center", &cam.center, vec3(0.f));
+ p.get_value<vec3>(camera, "eye", &cam.eye, vec3(0.f));
+ p.get_value<vec3>(camera, "up", &cam.up, vec3(0.f));
auto general = root["general"];
- clear_enabled = get_value<bool>(general["clearenabled"], BOOL);
-
- clear_color = get_value<vec4>(general["clearcolor"], VEC3);
- clear_color.value[3] = 1.f;
+ p.get_value<bool>(general, "clearenabled", &clear_enabled, true);
+ p.get_value<vec4>(general, "clearcolor", &clear_color, vec4(1.f));
auto ortho = general["orthogonalprojection"];
- width = get_value<float>(ortho["width"], FLOAT);
- height = get_value<float>(ortho["height"], FLOAT);
+ p.get_value<f32>(ortho, "width", &width, 0.f);
+ p.get_value<f32>(ortho, "height", &height, 0.f);
for (auto &object : root["objects"])
{
- objects.emplace_back(new Object(object));
+ objects.emplace_back(new Object(p, object));
}
}
@@ -51,7 +49,7 @@ Object *Scene::get_object_by_id(u32 id)
{
for (auto &object : objects)
{
- if (object->id.value == id)
+ if (object->id == id)
{
return object;
}
@@ -62,18 +60,11 @@ Object *Scene::get_object_by_id(u32 id)
void Scene::load(Engine *engine)
{
- engine->view.width = width.value;
- engine->view.height = height.value;
+ engine->view.width = width;
+ engine->view.height = height;
for (auto &object : objects)
{
- for (auto &dep : object->deps)
- {
- auto dep_object = get_object_by_id(dep);
- if (dep_object != nullptr)
- dep_object->load(engine);
- }
-
object->load(engine);
}
}
diff --git a/src/objects/scene.h b/src/objects/scene.h
index 43a4442..bd8d1b1 100644
--- a/src/objects/scene.h
+++ b/src/objects/scene.h
@@ -17,26 +17,27 @@ namespace Mauri
{
struct Camera {
- JsonValue<vec3> center;
- JsonValue<vec3> eye;
- JsonValue<vec3> up;
-
- JsonValue<float> farz;
- JsonValue<float> nearz;
- JsonValue<float> fov;
+ vec3 center;
+ vec3 eye;
+ vec3 up;
+ float farz;
+ float nearz;
+ float fov;
};
class Scene
{
public:
- Scene(std::string path);
+ Scene(Parser &p, const std::string &path);
~Scene();
- JsonValue<f32> width;
- JsonValue<f32> height;
+ Camera cam;
+
+ f32 width;
+ f32 height;
- JsonValue<bool> clear_enabled;
- JsonValue<vec4> clear_color;
+ bool clear_enabled;
+ vec4 clear_color;
void load(Engine *engine);
void draw(Engine *engine);
@@ -48,7 +49,7 @@ class Scene
std::vector<Object *> objects;
private:
- Camera cam;
+ std::vector<RenderPass *> passes;
};
} // namespace Mauri
diff --git a/src/shader.cc b/src/shader.cc
index eae4820..bd66c16 100644
--- a/src/shader.cc
+++ b/src/shader.cc
@@ -13,33 +13,34 @@
#include "objects/object.h"
-static const char *gl_compat = "#define highp\n"
- "#define mediump\n"
- "#define lowp\n"
- "#define mul(x, y) (y * x)\n"
- "#define frac fract\n"
- "#define CAST2(x) (vec2(x))\n"
- "#define CAST3(x) (vec3(x))\n"
- "#define CAST4(x) (vec4(x))\n"
- "#define CAST3X3(x) (mat3(x))\n"
- "#define saturate(x) (clamp(x, 0.0, 1.0))\n"
- "#define texSample2D texture2D\n"
- "#define texSample2DLod texture2DLod\n"
- "#define texture2DLod texture2D\n"
- "#define atan2 atan\n"
- "#define ddx dFdx\n"
- "#define ddy(x) dFdy(-(x))\n"
- "#define GLSL 1\n";
+static const char *gl_compat = \
+ "#define highp\n"
+ "#define mediump\n"
+ "#define lowp\n"
+ "#define mul(x, y) (y * x)\n"
+ "#define frac fract\n"
+ "#define CAST2(x) (vec2(x))\n"
+ "#define CAST3(x) (vec3(x))\n"
+ "#define CAST4(x) (vec4(x))\n"
+ "#define CAST3X3(x) (mat3(x))\n"
+ "#define saturate(x) (clamp(x, 0.0, 1.0))\n"
+ "#define texSample2D texture2D\n"
+ "#define texSample2DLod texture2DLod\n"
+ "#define texture2DLod texture2D\n"
+ "#define atan2 atan\n"
+ "#define ddx dFdx\n"
+ "#define ddy(x) dFdy(-(x))\n"
+ "#define GLSL 1\n";
static const char *version = "#version 120\n";
using namespace Mauri;
-std::string Shader::build_shader_source(std::string isource, bool root)
+void Shader::build_shader_source(Parser *p, const std::string &isource, std::string &res, bool root)
{
- std::stringstream stream(isource), source;
-
- if (root) source << gl_compat;
+ auto stream = std::istringstream(isource);
+
+ if (root) res += gl_compat;
for (std::string line; std::getline(stream, line);)
{
@@ -51,9 +52,11 @@ std::string Shader::build_shader_source(std::string isource, bool root)
auto include_name = line.substr(open, line.rfind('"') - open);
auto asset = asset_manager()->get_file(include_name, SHADER);
- auto include_source = this->build_shader_source(asset->as_string(), false);
- source << include_source;
+ std::string include_source;
+ build_shader_source(p, asset->as_string(), include_source, false);
+
+ res += include_source;
cut_line = true;
}
@@ -61,30 +64,27 @@ std::string Shader::build_shader_source(std::string isource, bool root)
{
auto type_string = line.substr(line.find(' ') + 1);
- auto type = TYPE_INVALID;
-
- JsonValue<vec4> value;
+ auto uniform = new Uniform();
if (type_string.compare(0, 5, "float") == 0)
- type = TYPE_FLOAT;
+ uniform->type = TYPE_FLOAT;
else if (type_string.compare(0, 4, "vec4") == 0)
- type = TYPE_VEC4;
+ uniform->type = TYPE_VEC4;
else if (type_string.compare(0, 4, "vec3") == 0)
- type = TYPE_VEC3;
+ uniform->type = TYPE_VEC3;
else if (type_string.compare(0, 4, "vec2") == 0)
- type = TYPE_VEC2;
+ uniform->type = TYPE_VEC2;
else if (type_string.compare(0, 4, "mat4") == 0)
- type = TYPE_MAT4;
+ uniform->type = TYPE_MAT4;
else if (type_string.compare(0, 9, "sampler2D") == 0)
{
- type = TYPE_SAMPLER2D;
- value.value[0] = this->texture_count++;
+ uniform->type = TYPE_SAMPLER2D;
+ uniform->default_value[0] = texture_count++;
}
auto open = type_string.find(' ') + 1;
- auto uname = type_string.substr(open, type_string.find(';') - open);
- auto name = std::string("");
+ uniform->uname = type_string.substr(open, type_string.find(';') - open);
auto combo_start = line.find("// ");
@@ -101,22 +101,22 @@ std::string Shader::build_shader_source(std::string isource, bool root)
auto material = root["material"];
if (!material.is_null())
- name = material;
+ uniform->name = material;
else if (!label.is_null())
- name = label;
+ uniform->name = label;
- switch (type)
+ switch (uniform->type)
{
case TYPE_SAMPLER2D: {
auto _default = root["default"];
if (!_default.is_null())
- this->textures[(int)(value.value[0])] = _default;
+ textures[(int)uniform->default_value[0]] = _default;
auto combo = root["combo"];
if (!combo.is_null())
- this->combos.emplace_back((Combo) { .name = combo, .value = 1 });
+ combos.emplace_back((Combo) { .name = combo, .value = 1 });
break;
}
@@ -124,16 +124,16 @@ std::string Shader::build_shader_source(std::string isource, bool root)
case TYPE_VEC4:
case TYPE_VEC3:
case TYPE_VEC2:
- value = get_value<vec4>(root["default"], VEC4);
+ p->get_value<vec4>(root, "default", &uniform->default_value, vec4(0.f));
break;
case TYPE_MAT4:
case TYPE_INVALID:
- value.value = glm::vec4(0.f);
+ uniform->default_value = vec4(0.f);
break;
}
}
-
- this->uniforms.emplace_back(Uniform(name, uname, type, value));
+
+ uniforms.emplace_back(uniform);
}
else if (line.compare(0, 10, "// [COMBO]") == 0)
{
@@ -142,71 +142,71 @@ std::string Shader::build_shader_source(std::string isource, bool root)
auto root = json::parse(combo);
- this->combos.emplace_back((Combo) { root["combo"], root["default"] });
+ combos.emplace_back((Combo) { root["combo"], root["default"] });
}
- if (!cut_line) source << line << "\n";
+ if (!cut_line) res += line + "\n";
}
-
- return source.str();
}
std::string Combo::to_string()
{
- return fmt::format("#define {} {}\n", this->name, this->value);
+ return fmt::format("#define {} {}\n", name, value);
}
void Shader::compile()
{
- auto vs_source = this->vs_source;
- auto fs_source = this->fs_source;
+ auto _vs_source = vs_source;
+ auto _fs_source = fs_source;
- for (auto &combo : this->combos)
+ for (auto &combo : combos)
{
- vs_source.insert(0, combo.to_string());
- fs_source.insert(0, combo.to_string());
+ _vs_source.insert(0, combo.to_string());
+ _fs_source.insert(0, combo.to_string());
}
- vs_source.insert(0, version);
- fs_source.insert(0, version);
+ _vs_source.insert(0, version);
+ _fs_source.insert(0, version);
- this->rshader = new RenderShader(vs_source, fs_source);
+ rshader = new RenderShader(_vs_source, _fs_source);
}
-Shader::Shader(std::string name)
+Shader::Shader(Parser *p, const std::string &name)
+ : name(name)
{
auto vs_asset = asset_manager()->get_file(name, VERTEX_SHADER);
auto fs_asset = asset_manager()->get_file(name, FRAGMENT_SHADER);
if (vs_asset->type != ASSET_VOID)
- this->vs_source = this->build_shader_source(vs_asset->as_string(), true);
+ build_shader_source(p, vs_asset->as_string(), vs_source, true);
else
log_error("failed to load shader file (%s)", name.c_str());
if (fs_asset->type != ASSET_VOID)
- this->fs_source = this->build_shader_source(fs_asset->as_string(), true);
+ build_shader_source(p, fs_asset->as_string(), fs_source, true);
else
log_error("failed to load shader file (%s)", name.c_str());
}
void Shader::bind(Engine *engine, mat4x4 *model)
{
- this->rshader->bind();
+ rshader->bind();
- for (auto &uniform : this->uniforms)
+ for (auto &uniform : uniforms)
{
- if (uniform.uname.find('[') != std::string::npos)
+ if (uniform->uname.find('[') != std::string::npos)
continue;
- //std::cout << uniform.uname << " " << uniform.value[0] << "\n";
- this->rshader->set_uniform(uniform.uname, uniform.type, glm::value_ptr(uniform.value.value));
+ //std::cout << uniform->uname << " " << uniform->value[0] << "\n";
+ if (uniform->value != nullptr)
+ rshader->set_uniform(uniform->uname, uniform->type, glm::value_ptr(*uniform->value));
}
- this->rshader->set_uniform("g_Time", TYPE_FLOAT, &engine->time);
+ rshader->set_uniform("g_Time", TYPE_FLOAT, &engine->time);
- this->rshader->set_uniform("g_TexelSize", TYPE_VEC2, glm::value_ptr(engine->view.texel_size));
- this->rshader->set_uniform("g_TexelSizeHalf", TYPE_VEC2, glm::value_ptr(engine->view.texel_half_size));
+ rshader->set_uniform("g_TexelSize", TYPE_VEC2, glm::value_ptr(engine->view.texel_size));
+ rshader->set_uniform("g_TexelSizeHalf", TYPE_VEC2, glm::value_ptr(engine->view.texel_half_size));
- this->rshader->set_uniform("g_PointerPosition", TYPE_VEC2, glm::value_ptr(engine->view.cursor_pos));
+ rshader->set_uniform("g_PointerPosition", TYPE_VEC2, glm::value_ptr(engine->view.cursor_pos));
mat4x4 _model, _inverse;
@@ -217,14 +217,19 @@ void Shader::bind(Engine *engine, mat4x4 *model)
_inverse = glm::inverse(_model);
- this->rshader->set_uniform("g_ModelViewProjectionMatrix", TYPE_MAT4, glm::value_ptr(_model));
- this->rshader->set_uniform("g_ModelViewProjectionMatrixInverse", TYPE_MAT4, glm::value_ptr(_inverse));
+ rshader->set_uniform("g_ModelViewProjectionMatrix", TYPE_MAT4, glm::value_ptr(_model));
+ rshader->set_uniform("g_ModelViewProjectionMatrixInverse", TYPE_MAT4, glm::value_ptr(_inverse));
}
Shader::~Shader()
{
- if (this->rshader)
+ if (rshader != nullptr)
+ {
+ delete rshader;
+ }
+
+ for (auto &uniform : uniforms)
{
- delete this->rshader;
+ delete uniform;
}
}
diff --git a/src/shader.h b/src/shader.h
index a878d4f..eed4f80 100644
--- a/src/shader.h
+++ b/src/shader.h
@@ -14,28 +14,17 @@ namespace Mauri
struct Uniform
{
- Uniform(std::string name, JsonValue<vec4> value)
- : name(name), value(value)
- {
- }
-
- Uniform(std::string name, std::string uname, UniformType type, JsonValue<vec4> value)
- : name(name), uname(uname), type(type), value(value)
- {
- }
-
std::string name;
std::string uname;
-
UniformType type;
-
- JsonValue<vec4> value;
+ vec4 *value = nullptr;
+ vec4 default_value;
};
struct Combo
{
std::string name;
- int value;
+ s32 value;
std::string to_string();
};
@@ -44,15 +33,17 @@ class Engine;
class Shader
{
public:
- Shader(std::string name);
+ Shader(Parser *p, const std::string &name);
~Shader();
- std::vector<Uniform> uniforms;
+ std::string name;
+
+ std::vector<Uniform *> uniforms;
std::vector<Combo> combos;
std::array<std::string, 8> textures;
- int texture_count = 0;
+ u32 texture_count = 0;
void bind(Engine *engine, mat4x4 *model);
void compile();
@@ -63,7 +54,7 @@ class Shader
RenderShader *rshader = nullptr;
- std::string build_shader_source(std::string isource, bool root);
+ void build_shader_source(Parser *p, const std::string &isource, std::string &res, bool root);
};
} // namespace Mauri
diff --git a/src/texture.cc b/src/texture.cc
index bd8996f..5367933 100644
--- a/src/texture.cc
+++ b/src/texture.cc
@@ -162,7 +162,7 @@ Texture::Texture(Asset *asset)
asset->reset();
}
-Texture::~Texture()
+void Texture::unload()
{
if (!wrapped)
delete texture;
@@ -173,7 +173,8 @@ void Texture::bind(s32 index)
texture->bind(index);
}
-Framebuffer::Framebuffer(f32 width, f32 height, f32 scale)
+Framebuffer::Framebuffer(std::string name, f32 width, f32 height, f32 scale)
+ : name(name)
{
buffer = new RenderFramebuffer(width, height, scale);
@@ -188,10 +189,14 @@ Framebuffer::Framebuffer(f32 width, f32 height, f32 scale)
texture->texture_resolution[3] = buffer->height;
}
-Framebuffer::~Framebuffer()
+void Framebuffer::unload()
{
if (texture != nullptr)
+ {
+ texture->unload();
delete texture;
+ }
+
if (buffer != nullptr)
delete buffer;
}
diff --git a/src/texture.h b/src/texture.h
index 52bf197..e12ad18 100644
--- a/src/texture.h
+++ b/src/texture.h
@@ -40,11 +40,9 @@ class Texture
{
public:
Texture(Asset *asset);
- Texture()
- {
- }
+ Texture() {}
- ~Texture();
+ ~Texture() {};
s32 width;
s32 height;
@@ -62,6 +60,8 @@ class Texture
void load(Asset *asset);
void bind(s32 index);
+ void unload();
+
private:
s32 texture_width;
s32 texture_height;
@@ -77,11 +77,16 @@ class Texture
class Framebuffer
{
public:
- Framebuffer(f32 width, f32 height, f32 scale);
- ~Framebuffer();
+ Framebuffer(std::string name, f32 width, f32 height, f32 scale);
+
+ ~Framebuffer() {};
+
+ std::string name;
Texture *texture;
RenderFramebuffer *buffer;
+
+ void unload();
};
} // namespace Mauri