summaryrefslogtreecommitdiff
path: root/src/objects
diff options
context:
space:
mode:
Diffstat (limited to 'src/objects')
-rw-r--r--src/objects/effect.c133
-rw-r--r--src/objects/effect.cc90
-rw-r--r--src/objects/effect.h49
-rw-r--r--src/objects/material.c87
-rw-r--r--src/objects/material.cc64
-rw-r--r--src/objects/material.h37
-rw-r--r--src/objects/model.c43
-rw-r--r--src/objects/model.cc40
-rw-r--r--src/objects/model.h35
-rw-r--r--src/objects/object.c175
-rw-r--r--src/objects/object.cc174
-rw-r--r--src/objects/object.h110
-rw-r--r--src/objects/pass.c405
-rw-r--r--src/objects/pass.cc346
-rw-r--r--src/objects/pass.h111
-rw-r--r--src/objects/scene.c104
-rw-r--r--src/objects/scene.cc120
-rw-r--r--src/objects/scene.h67
-rw-r--r--src/objects/types.h15
19 files changed, 1067 insertions, 1138 deletions
diff --git a/src/objects/effect.c b/src/objects/effect.c
deleted file mode 100644
index d5fb747..0000000
--- a/src/objects/effect.c
+++ /dev/null
@@ -1,133 +0,0 @@
-#include "effect.h"
-
-#include "../engine.h"
-#include "../json.h"
-#include "../log.h"
-
-#include "cglm/mat4.h"
-#include "moro_str.h"
-#include "moro_vec.h"
-#include "src/objects/pass.h"
-#include "src/objects/types.h"
-#include <jansson.h>
-
-void mri_effect_parse(mri_effect *effect, json_t *root) {
- mvec_init(effect->passes);
- mvec_init(effect->passes0);
- mvec_init(effect->passes1);
-
- json_get_int(&effect->id, root, "id");
-
- json_get_bool(&effect->visible, root, "visible");
-
- json_t *pass0;
- json_t *passes0 = json_object_get(root, "passes");
- json_array(pass0, passes0) {
- mri_pass_parse(mvec_next(effect->passes0), pass0, EFFECT0_PASS);
- }
-
- json_t *file = json_object_get(root, "file");
- if (json_is_string(file)) {
- mri_asset *effect_asset = mri_asset_manager_get(mstr_c(json_string_value(file)), NONE);
-
- if (effect_asset->type == ASSET_VOID)
- return;
-
- json_t *_root = json_load_mstr(mri_asset_as_str(effect_asset));
-
- effect->name = mstr_from(json_string_value(json_object_get(_root, "name")));
-
- json_t *pass1;
- json_t *passes1 = json_object_get(_root, "passes");
- json_array(pass1, passes1) {
- mri_pass_parse(mvec_next(effect->passes1), pass1, EFFECT1_PASS);
- }
-
- mvec_init(effect->fbos);
-
- json_t *fbo;
- json_t *fbos = json_object_get(_root, "fbos");
- json_array(fbo, fbos) {
- mri_effect_buffer buffer = {
- .name = mstr_from(json_string_value(json_object_get(fbo, "name"))),
- .scale = json_number_value(json_object_get(fbo, "scale"))
- };
- mvec_push(effect->fbos, buffer);
- }
- }
-}
-
-mri_render_pass *mri_effect_next_pass(mri_effect *effect) {
- mri_render_pass *pass = mvec_next(effect->passes);
- mvec_init(pass->uniforms);
- mvec_init(pass->combos);
- return pass;
-}
-
-void mri_effect_load(mri_engine *engine, mri_effect *effect, bool last_effect) {
- mri_effect_buffer *buffer;
- mvec_loop_ptr(effect->fbos, buffer, i) {
- mri_object *object = engine->current_object;
-
- mstr *effect_buffer_id = mstr_sprintf("%i_%i", effect->id, object->id);
- mstr_cat(buffer->name, effect_buffer_id);
- mstr_free(effect_buffer_id);
-
- mri_engine_get_or_new_framebuffer(engine, buffer->name,
- object->size[0], object->size[1], buffer->scale);
- }
-
- for (unsigned int i = 0; i < mvec_size(effect->passes0); i++) {
- mri_render_pass *pass = mri_effect_next_pass(effect);
-
- pass->object = engine->current_object;
- pass->effect = effect;
-
- pass->combine = (i == mvec_size(effect->passes0) - 1) && last_effect;
-
- if (pass->combine) {
- pass->gl_object = &engine->current_object->gl_object;
- glm_mat4_copy(engine->current_object->model, pass->model);
- } else {
- pass->gl_object = &engine->default_gl_object;
- glm_mat4_identity(pass->model);
- }
-
- mri_pass_load(engine, mvec_at(effect->passes0, i), EFFECT0_PASS, pass);
- mri_pass_load(engine, mvec_at(effect->passes1, i), EFFECT1_PASS, pass);
- }
-}
-
-void mri_effect_draw(mri_engine *engine, mri_effect *effect) {
- mri_render_pass *pass;
- mvec_loop_ptr(effect->passes, pass, i) {
- //log_debug("effect (%.*s): %.*s %i", pass->object->name->len, pass->object->name->ptr,
- // effect->name->len, effect->name->ptr, i + 1);
- mri_render_pass_draw(engine, pass);
- }
-}
-
-void mri_effect_unload(mri_effect *effect) {
- mstr_free(effect->name);
-
- mri_pass *pass;
-
- mvec_loop_ptr(effect->passes0, pass, i) {
- mri_pass_unload(pass);
- }
-
- mvec_loop_ptr(effect->passes1, pass, i) {
- mri_pass_unload(pass);
- }
-
- mvec_free(effect->passes0);
- mvec_free(effect->passes1);
-
- mri_effect_buffer *buffer;
- mvec_loop_ptr(effect->fbos, buffer, i) {
- if (buffer->name)
- mstr_free(buffer->name);
- }
-
- mvec_free(effect->fbos);
-}
diff --git a/src/objects/effect.cc b/src/objects/effect.cc
new file mode 100644
index 0000000..7f22ef0
--- /dev/null
+++ b/src/objects/effect.cc
@@ -0,0 +1,90 @@
+#include "../assets.h"
+#include "../engine.h"
+#include "../json.h"
+#include "../log.h"
+
+#include "effect.h"
+#include "fmt/core.h"
+#include "object.h"
+
+#include "objects/pass.h"
+
+#include <jsoncpp/json/reader.h>
+
+#include <fmt/format.h>
+#include <glm/fwd.hpp>
+
+using namespace Mauri;
+
+Effect::Effect(Json::Value root)
+{
+ this->id = root["id"].asInt();
+
+ this->visible = json_user_value(root.get("visible", true)).asBool();
+
+ for (auto &pass0 : root["passes"])
+ {
+ this->passes0.emplace_back(new Pass(pass0, EFFECT0_PASS));
+ }
+
+ auto asset = asset_manager()->get_file(root["file"].asString(), NONE);
+
+ if (asset->type == ASSET_VOID)
+ return;
+
+ Json::Value file = asset->as_json();
+
+ this->name = file["name"].asString();
+
+ for (auto &pass1 : file["passes"])
+ {
+ this->passes1.emplace_back(new Pass(pass1, EFFECT1_PASS));
+ }
+
+ for (auto &fbo : file["fbos"])
+ {
+ this->fbos.emplace_back((EffectBuffer) { fbo["name"].asString(), fbo["scale"].asFloat() });
+ }
+}
+
+void Effect::load(Engine *engine, Object *object, bool last_effect)
+{
+ if (!this->visible)
+ return;
+
+ this->buffer_id = fmt::format("{}_{}", this->id, object->id);
+
+ for (auto &fbo : this->fbos)
+ {
+ fbo.name.append(this->buffer_id);
+ engine->new_framebuffer(fbo.name, object->size[0], object->size[1], fbo.scale);
+ }
+
+ for (int i = 0; i < this->passes0.size(); i++)
+ {
+ Pass *pass = new Pass();
+
+ pass->combine = (i == (this->passes0.size() - 1)) && last_effect;
+
+ pass->object = object;
+ pass->effect = this;
+
+ this->passes0[i]->load(EFFECT0_PASS, pass);
+ this->passes1[i]->load(EFFECT1_PASS, pass);
+
+ object->passes.push_back(pass);
+ }
+}
+
+Effect::~Effect()
+{
+ for (auto &pass0 : this->passes0)
+ {
+ delete pass0;
+ }
+
+ for (auto &pass1 : this->passes1)
+ {
+ delete pass1;
+ }
+}
diff --git a/src/objects/effect.h b/src/objects/effect.h
index 4d31081..9edeea7 100644
--- a/src/objects/effect.h
+++ b/src/objects/effect.h
@@ -1,32 +1,43 @@
#ifndef _EFFECT_H
#define _EFFECT_H
-#include <moro.h>
+#include <vector>
-#include "types.h"
-#include "pass.h"
+#include "engine.h"
-typedef struct {
- mstr *name;
- float scale;
-} mri_effect_buffer;
+namespace Mauri
+{
-struct mri_effect {
- mstr *name;
- int id;
+class Pass;
+
+struct EffectBuffer
+{
+ std::string name;
+ float scale;
+};
+
+class Effect
+{
+ public:
+ Effect(Json::Value root);
+ ~Effect();
+
+ u32 id;
+ std::string name;
+
+ std::string buffer_id;
+
+ void load(Engine *engine, Object *object, bool last_effect);
- bool visible;
+ private:
+ bool visible;
- mvec(mri_pass) passes0;
- mvec(mri_pass) passes1;
- mvec(mri_render_pass) passes;
+ std::vector<Pass *> passes0;
+ std::vector<Pass *> passes1;
- mvec(mri_effect_buffer) fbos;
+ std::vector<EffectBuffer> fbos;
};
-void mri_effect_parse(mri_effect *effect, json_t *root);
-void mri_effect_load(mri_engine *engine, mri_effect *effect, bool last_effect);
-void mri_effect_draw(mri_engine *engine, mri_effect *effect);
-void mri_effect_unload(mri_effect *effect);
+} // namespace Mauri
#endif // _EFFECT_H
diff --git a/src/objects/material.c b/src/objects/material.c
deleted file mode 100644
index 75422d1..0000000
--- a/src/objects/material.c
+++ /dev/null
@@ -1,87 +0,0 @@
-#include "material.h"
-#include "cglm/mat4.h"
-#include "pass.h"
-
-#include <moro_str.h>
-
-#include "../log.h"
-#include "../json.h"
-#include "../engine.h"
-#include "src/objects/types.h"
-
-void mri_material_parse(mri_material *material, json_t *value) {
- mvec_init(material->passes);
- mvec_init(material->passes0);
-
- if (json_is_string(value)) {
- mri_asset *material_asset = mri_asset_manager_get(mstr_c(json_string_value(value)), NONE);
-
- if (material_asset->type == ASSET_VOID)
- return;
-
- json_t *root = json_load_mstr(mri_asset_as_str(material_asset));
-
- json_t *pass;
- json_t *passes = json_object_get(root, "passes");
- json_array(pass, passes) {
- mri_pass_parse(mvec_next(material->passes0), pass, MATERIAL_PASS);
- }
-
- json_decref(root);
- }
-}
-
-mri_render_pass *mri_material_next_pass(mri_material *material) {
- mri_render_pass *pass = mvec_next(material->passes);
- mvec_init(pass->uniforms);
- mvec_init(pass->combos);
- return pass;
-}
-
-void mri_material_load(mri_engine *engine, mri_material *material, mri_material_type t,
- mri_render_pass *pass, bool no_effects) {
- mri_pass *pass0;
- mvec_loop_ptr(material->passes0, pass0, i) {
- switch (t) {
- case MATERIAL_EFFECT:
- mri_pass_load(engine, pass0, MATERIAL_PASS, pass);
- break;
- case MATERIAL_MODEL:
- pass = mri_material_next_pass(material);
-
- pass->object = engine->current_object;
- pass->combine = no_effects;
-
- if (engine->current_object->passthrough || no_effects) {
- glm_mat4_copy(engine->current_object->model, pass->model);
- } else {
- glm_mat4_copy(engine->current_object->ortho, pass->model);
- }
-
- if (engine->current_object->passthrough) {
- pass->gl_object = &engine->current_object->gl_object;
- } else {
- pass->gl_object = &engine->current_object->gl_uv_object;
- }
-
- mri_pass_load(engine, pass0, MATERIAL_ONLY_PASS, pass);
- break;
- }
- }
-}
-
-void mri_material_draw(mri_engine *engine, mri_material *material) {
- mri_render_pass *pass;
- mvec_loop_ptr(material->passes, pass, i) {
- //log_debug("background (%.*s): %i", pass->object->name->len, pass->object->name->ptr, i);
- mri_render_pass_draw(engine, pass);
- }
-}
-
-void mri_material_unload(mri_material *material) {
- mri_pass *pass0;
- mvec_loop_ptr(material->passes0, pass0, i) {
- mri_pass_unload(pass0);
- }
- mvec_free(material->passes);
-}
diff --git a/src/objects/material.cc b/src/objects/material.cc
new file mode 100644
index 0000000..4c61cbc
--- /dev/null
+++ b/src/objects/material.cc
@@ -0,0 +1,64 @@
+#include <jsoncpp/json/json.h>
+
+#include "assets.h"
+#include "engine.h"
+#include "json.h"
+#include "log.h"
+
+#include "objects/material.h"
+#include "objects/object.h"
+#include "objects/pass.h"
+
+using namespace Mauri;
+
+Material::Material(std::string path)
+{
+ auto asset = asset_manager()->get_file(path, NONE);
+
+ if (asset->type == ASSET_VOID)
+ {
+ log_error("failed to load material.json (%s)", path.c_str());
+ return;
+ }
+
+ Json::Value root = asset->as_json();
+
+ for (auto &pass : root["passes"])
+ {
+ this->passes0.push_back(new Pass(pass, MATERIAL_PASS));
+ }
+}
+
+void Material::load(Object *object, MaterialType type, Pass *pass, bool no_effects)
+{
+ for (auto &pass0 : this->passes0)
+ {
+ switch (type)
+ {
+ case MATERIAL_EFFECT:
+ pass0->load(MATERIAL_PASS, pass);
+ break;
+ case MATERIAL_MODEL:
+ Pass *pass = new Pass();
+
+ pass->combine = no_effects;
+
+ pass->object = object;
+ pass->effect = nullptr;
+
+ pass0->load(MATERIAL_ONLY_PASS, pass);
+
+ object->passes.push_back(pass);
+
+ break;
+ }
+ }
+}
+
+Material::~Material()
+{
+ for (auto &pass0 : this->passes0)
+ {
+ delete pass0;
+ }
+}
diff --git a/src/objects/material.h b/src/objects/material.h
index e8bc13d..31b3be0 100644
--- a/src/objects/material.h
+++ b/src/objects/material.h
@@ -1,25 +1,32 @@
#ifndef _MATERIAL_H
#define _MATERIAL_H
-#include <jansson.h>
+#include <iostream>
-#include "types.h"
-#include "pass.h"
+#include "engine.h"
-typedef enum {
- MATERIAL_MODEL,
- MATERIAL_EFFECT
-} mri_material_type;
+namespace Mauri
+{
-struct mri_material {
- mvec(mri_pass) passes0;
- mvec(mri_render_pass) passes;
+class Pass;
+
+enum MaterialType
+{
+ MATERIAL_MODEL,
+ MATERIAL_EFFECT
+};
+
+class Material
+{
+ public:
+ Material(std::string path);
+ ~Material();
+
+ void load(Object *object, MaterialType type, Pass *pass, bool no_effects);
+
+ std::vector<Pass *> passes0;
};
-void mri_material_parse(mri_material *material, json_t *value);
-void mri_material_load(mri_engine *engine, mri_material *material, mri_material_type t, mri_render_pass *pass,
- bool no_effects);
-void mri_material_draw(mri_engine *engine, mri_material *material);
-void mri_material_unload(mri_material *material);
+} // namespace Mauri
#endif // MATERIAL_H
diff --git a/src/objects/model.c b/src/objects/model.c
deleted file mode 100644
index 45317f2..0000000
--- a/src/objects/model.c
+++ /dev/null
@@ -1,43 +0,0 @@
-#include <jansson.h>
-#include <moro_str.h>
-
-#include "../json.h"
-#include "../assets.h"
-#include "../log.h"
-#include "../engine.h"
-
-#include "model.h"
-#include "src/objects/types.h"
-
-void mri_model_parse(mri_model *model, json_t *value) {
- if (json_is_string(value)) {
- mri_asset *model_asset = mri_asset_manager_get(mstr_c(json_string_value(value)), NONE);
-
- if (model_asset->type == ASSET_VOID)
- return;
-
- json_t *root = json_load_mstr(mri_asset_as_str(model_asset));
-
- json_get_bool(&model->autosize, root, "autosize");
- json_get_bool(&model->fullscreen, root, "fullscreen");
- json_get_bool(&model->passthrough, root, "passthrough");
-
- mri_material_parse(&model->material, json_object_get(root, "material"));
-
- json_decref(root);
- } else {
- memset(model, 0, sizeof(mri_model));
- }
-}
-
-void mri_model_load(mri_engine *engine, mri_model *model, bool no_effects) {
- mri_material_load(engine, &model->material, MATERIAL_MODEL, NULL, no_effects);
-}
-
-void mri_model_draw(mri_engine *engine, mri_model *model) {
- mri_material_draw(engine, &model->material);
-}
-
-void mri_model_unload(mri_model *model) {
- mri_material_unload(&model->material);
-}
diff --git a/src/objects/model.cc b/src/objects/model.cc
new file mode 100644
index 0000000..59c1cb3
--- /dev/null
+++ b/src/objects/model.cc
@@ -0,0 +1,40 @@
+#include <jsoncpp/json/json.h>
+
+#include "assets.h"
+#include "json.h"
+#include "log.h"
+
+#include "objects/material.h"
+#include "objects/model.h"
+
+using namespace Mauri;
+
+Model::Model(std::string path)
+{
+ auto asset = asset_manager()->get_file(path, NONE);
+
+ if (asset->type == ASSET_VOID)
+ {
+ log_error("failed to load model.json (%s)", path.c_str());
+ return;
+ }
+
+ Json::Value root = asset->as_json();
+
+ this->autosize = root.get("autosize", true).asBool();
+ this->fullscreen = root.get("fullscreen", false).asBool();
+ this->passthrough = root.get("passthrough", false).asBool();
+
+ this->material = new Material(root["material"].asString());
+}
+
+void Model::load(Object *object, bool no_effects)
+{
+ this->material->load(object, MATERIAL_MODEL, NULL, no_effects);
+}
+
+Model::~Model()
+{
+ if (this->material != nullptr)
+ delete this->material;
+}
diff --git a/src/objects/model.h b/src/objects/model.h
index 9daed21..e25a592 100644
--- a/src/objects/model.h
+++ b/src/objects/model.h
@@ -1,22 +1,31 @@
#ifndef _MODEL_H
#define _MODEL_H
-#include <jansson.h>
+#include <iostream>
-#include "types.h"
-#include "pass.h"
-#include "material.h"
+#include "engine.h"
-struct mri_model {
- bool autosize;
- bool fullscreen;
- bool passthrough;
- mri_material material;
+#include "objects/material.h"
+
+namespace Mauri
+{
+
+class Model
+{
+ public:
+ Model(std::string path);
+ ~Model();
+
+ bool autosize;
+ bool fullscreen;
+ bool passthrough;
+
+ void load(Object *object, bool no_effects);
+
+ private:
+ Material *material = nullptr;
};
-void mri_model_parse(mri_model *model, json_t *value);
-void mri_model_load(mri_engine *engine, mri_model *model, bool no_effects);
-void mri_model_draw(mri_engine *engine, mri_model *model);
-void mri_model_unload(mri_model *model);
+} // namespace Mauri
#endif // _MODEL_H
diff --git a/src/objects/object.c b/src/objects/object.c
index 431852e..69c5411 100644
--- a/src/objects/object.c
+++ b/src/objects/object.c
@@ -1,174 +1 @@
-#include <jansson.h>
-#include <cglm/cglm.h>
-
-#include "moro_str.h"
-#include "src/shader.h"
-#include "src/texture.h"
-
-#include "types.h"
-#include "object.h"
-#include "model.h"
-#include "scene.h"
-
-#include "../log.h"
-#include "../gl.h"
-#include "../engine.h"
-#include "../json.h"
-
-void mri_object_parse(mri_object *object, json_t *root) {
- json_get_int(&object->id, root, "id");
-
- object->name = mstr_from(json_string_value(json_object_get(root, "name")));
-
- mvec_init(object->deps);
-
- json_t *dep;
- json_t *deps = json_object_get(root, "dependencies");
- json_array(dep, deps) {
- int value = json_integer_value(dep);
- mvec_push(object->deps, value);
- }
-
- json_get_float(&object->alpha, root, "alpha");
- json_get_vec3(&object->angles, root, "angles");
- json_get_vec3(&object->color, root, "color");
- json_get_vec2(&object->size, root, "size");
- json_get_vec3(&object->scale, root, "scale");
- json_get_vec3(&object->origin, root, "origin");
- object->origin[2] = 0.f;
-
- json_get_int(&object->color_blend_mode, root, "colorblendmode");
- json_get_bool(&object->copy_background, root, "copybackground");
-
- json_get_bool(&object->visible, root, "visible");
-
- json_t *config = json_object_get(root, "config");
- if (json_is_object(config)) {
- json_get_bool(&object->passthrough, config, "passthrough");
- }
-
- mri_model_parse(&object->image, json_object_get(root, "image"));
-
- mvec_init(object->effects);
-
- json_t *effect;
- json_t *effects = json_object_get(root, "effects");
- json_array(effect, effects) {
- mri_effect_parse(mvec_next(object->effects), effect);
- }
-}
-
-void mri_object_get_model(mri_object *object, mat4 model, float width, float height) {
- glm_mat4_identity(model);
-
- glm_translate_to(model, (vec3){-width, -height, 0.f}, model);
-
- vec3 origin;
- glm_vec3_scale(object->origin, 2.f, origin);
- glm_translate_to(model, origin, model);
-
- glm_rotate(model, object->angles[0], (vec3){1.f, 0.f, 0.f});
- glm_rotate(model, object->angles[1], (vec3){0.f, 1.f, 0.f});
- glm_rotate(model, object->angles[2], (vec3){0.f, 0.f, 1.f});
-
- glm_scale(model, object->scale);
-
- mat4 ortho;
- glm_ortho(-width, width, height, -height, 0.f, 1.f, ortho);
- glm_mat4_mul(ortho, model, model);
-}
-
-void mri_object_load(mri_engine *engine, mri_object *object) {
- if (object->loaded) return;
-
- engine->current_object = object;
-
- float width = object->size[0];
- float height = object->size[1];
-
- mstr *abuffer = mstr_sprintf("_rt_imageLayerComposite_%i_a", object->id);
- mstr *bbuffer = mstr_sprintf("_rt_imageLayerComposite_%i_b", object->id);
-
- object->abuffer = mri_engine_get_or_new_framebuffer(engine,
- abuffer, width, height, 1.f);
-
- object->bbuffer = mri_engine_get_or_new_framebuffer(engine,
- bbuffer, width, height, 1.f);
-
- mstr_free(abuffer);
- mstr_free(bbuffer);
-
- object->buffer_switch = false;
-
- mri_object_get_model(object, engine->current_object->model,
- engine->width, engine->height);
-
- glm_ortho(-width, width, -height, height, 0.f, 1.f,
- engine->current_object->ortho);
-
- create_gl_object(&engine->current_object->gl_uv_object,
- UV_SCALE, width, height);
-
- create_gl_object(&engine->current_object->gl_object,
- OBJECT, width, height);
-
- mri_model_load(engine, &object->image, mvec_size(object->effects) == 0);
-
- if (object->image.fullscreen) {
- object->fullscreen = true;
- object->size[0] = engine->width;
- object->size[1] = engine->height;
- object->origin[0] = object->size[0] / 2.f;
- object->origin[1] = object->size[1] / 2.f;
- }
-
- if (object->image.passthrough) {
- object->passthrough = true;
- }
-
- mri_effect *effect;
- mvec_loop_ptr(object->effects, effect, i) {
- mri_effect_load(engine, effect, i == (mvec_size(object->effects) - 1));
- }
-
- object->loaded = true;
-}
-
-void mri_object_switch_buffer(mri_object *object) {
- object->buffer_switch = !object->buffer_switch;
-}
-
-mri_framebuffer *mri_object_get_target_buffer(mri_object *object) {
- return (object->buffer_switch) ? object->abuffer : object->bbuffer;
-}
-
-mri_texture *mri_object_get_texture_buffer(mri_object *object) {
- return &((object->buffer_switch) ? object->bbuffer : object->abuffer)->texture;
-}
-
-void mri_object_draw(mri_engine *engine, mri_object *object) {
- mri_model_draw(engine, &object->image);
-
- mri_effect *effect;
- mvec_loop_ptr(object->effects, effect, i) {
- mri_effect_draw(engine, effect);
- }
-}
-
-void mri_object_unload(mri_object *object) {
- mstr_free(object->name);
-
- mri_effect *effect;
- mvec_loop_ptr(object->effects, effect, i) {
- mri_effect_unload(effect);
- }
-
- mvec_free(object->effects);
- mvec_free(object->deps);
-
- mri_framebuffer_unload(object->abuffer);
- mri_framebuffer_unload(object->bbuffer);
-
- mri_model_unload(&object->image);
-}
-
+//#include "../engine.h"
diff --git a/src/objects/object.cc b/src/objects/object.cc
new file mode 100644
index 0000000..a356637
--- /dev/null
+++ b/src/objects/object.cc
@@ -0,0 +1,174 @@
+#include <glm/fwd.hpp>
+#include <glm/trigonometric.hpp>
+#include <jsoncpp/json/json.h>
+
+#include <glm/ext/matrix_transform.hpp>
+#include <glm/glm.hpp>
+#include <glm/gtc/type_ptr.hpp>
+
+#include <fmt/core.h>
+
+#include "../gl.h"
+#include "../json.h"
+#include "../log.h"
+
+#include "objects/effect.h"
+#include "objects/object.h"
+#include "objects/scene.h"
+#include "objects/pass.h"
+
+using namespace Mauri;
+
+Object::Object(Json::Value root)
+{
+ this->id = root["id"].asInt();
+ this->name = root["name"].asString();
+
+ for (auto &id : root["dependencies"])
+ this->deps.push_back(id.asInt());
+
+ sscanf_vec3(json_user_value(root.get("angles", "")).asCString(), this->angles);
+ sscanf_vec3(json_user_value(root.get("colors", "")).asCString(), this->color);
+ sscanf_vec2(json_user_value(root.get("size", "")).asCString(), this->size);
+ sscanf_vec3(json_user_value(root.get("scale", "")).asCString(), this->scale);
+ sscanf_vec3(json_user_value(root.get("origin", "")).asCString(), this->origin);
+
+ this->color_blend_mode = (BlendMode)root.get("colorblendmode", 0).asInt();
+
+ this->visible = json_user_value(root.get("visible", true)).asBool();
+
+ auto _image = root["image"];
+
+ if (!_image.isNull())
+ this->image = new Model(_image.asString());
+
+ auto config = root["config"];
+
+ if (!config.isNull())
+ this->passthrough = config.get("passthrough", false).asBool();
+
+ for (auto &effect : root["effects"])
+ {
+ this->effects.emplace_back(new Effect(effect));
+ }
+}
+
+void Object::get_model(f32 width, f32 height, bool flip)
+{
+ this->model = mat4x4(1.f);
+
+ this->model = glm::translate(this->model, (vec3){-width, -height, 0.f});
+ this->model = glm::translate(this->model, this->origin * 2.f);
+
+ this->model = glm::rotate(this->model, this->angles[0], (vec3){1.f, 0.f, 0.f});
+ this->model = glm::rotate(this->model, this->angles[1], (vec3){0.f, 1.f, 0.f});
+ this->model = glm::rotate(this->model, this->angles[2], (vec3){0.f, 0.f, 1.f});
+
+ this->model = glm::scale(this->model, this->scale);
+
+ mat4x4 _ortho = glm::ortho(-width, width, height, -height, 0.f, 1.f);
+
+ if (flip)
+ {
+ this->model = glm::scale(this->model, (vec3){1.f, -1.f, 1.f});
+ }
+
+ this->model = _ortho * this->model;
+}
+
+void Object::load(Engine *engine)
+{
+ if (this->loaded || !this->visible)
+ return;
+
+ f32 width = this->size[0];
+ f32 height = this->size[1];
+
+ this->abuffer = fmt::format("_rt_imageLayerComposite_{}_a", this->id);
+ this->bbuffer = fmt::format("_rt_imageLayerComposite_{}_b", this->id);
+
+ engine->new_framebuffer(this->abuffer, width, height, 1.f);
+ engine->new_framebuffer(this->bbuffer, width, height, 1.f);
+
+ this->get_model(engine->view.width, engine->view.height, this->effects.size() == 0);
+
+ this->ortho = glm::ortho(-width, width, -height, height, 0.f, 1.f);
+
+ this->gl_object = new RenderObject(OBJECT, width, height);
+ this->gl_uv_object = new RenderObject(UV_SCALE, width, height);
+
+ if (this->image)
+ {
+ this->image->load(this, this->effects.size() == 0);
+
+ if (this->image->fullscreen)
+ {
+ this->fullscreen = true;
+ this->size[0] = engine->view.width;
+ this->size[1] = engine->view.height;
+ this->origin[0] = this->size[0] / 2.f;
+ this->origin[1] = this->size[1] / 2.f;
+ }
+
+ if (this->image->passthrough)
+ this->passthrough = true;
+ }
+
+ for (int i = 0; i < this->effects.size(); i++)
+ {
+ this->effects[i]->load(engine, this, i == (this->effects.size() - 1));
+ }
+
+ this->loaded = true;
+}
+
+void Object::update(Engine *engine)
+{
+ //if (engine->time > this->shake_tick)
+ //{
+ //}
+}
+
+void Object::draw(Engine *engine)
+{
+ if (!this->visible)
+ return;
+
+ for (auto &pass : this->passes)
+ {
+ pass->draw(engine);
+ }
+}
+
+std::string Object::get_target_buffer() const
+{
+ if (this->buffer_switch)
+ return this->abuffer;
+ else
+ return this->bbuffer;
+}
+
+std::string Object::get_texture_buffer() const
+{
+ if (this->buffer_switch)
+ return this->bbuffer;
+ else
+ return this->abuffer;
+}
+
+Object::~Object()
+{
+ if (this->image != nullptr)
+ delete this->image;
+
+ if (this->gl_object != nullptr)
+ delete this->gl_object;
+
+ if (this->gl_uv_object != nullptr)
+ delete this->gl_uv_object;
+
+ for (auto &effect : this->effects)
+ {
+ delete effect;
+ }
+}
diff --git a/src/objects/object.h b/src/objects/object.h
index fbaae60..fe44e03 100644
--- a/src/objects/object.h
+++ b/src/objects/object.h
@@ -1,76 +1,90 @@
#ifndef _OBJECT_H
#define _OBJECT_H
-#include <moro.h>
-#include <jansson.h>
-#include <stdbool.h>
-#include <cglm/cglm.h>
+#include <glm/glm.hpp>
+#include <jsoncpp/json/json.h>
+
+#include "../engine.h"
-#include "src/texture.h"
-#include "types.h"
-#include "model.h"
-#include "pass.h"
#include "effect.h"
+#include "model.h"
-#include "../gl.h"
+using namespace glm;
-typedef enum {
- CENTER,
-} mri_object_alignment;
+namespace Mauri
+{
-struct mri_object {
- int id;
- mstr *name;
+enum ObjectAlignment
+{
+ CENTER,
+};
- mvec(int) deps;
+enum BlendMode
+{
+ TRANSLUCENT = 0,
+ NORMAL = 1
+};
- mri_object_alignment alignment;
+class Object
+{
+ public:
+ Object(Json::Value root);
+ ~Object();
- float alpha;
+ u32 id;
+ std::string name;
- vec3 angles;
- vec3 color;
+ std::vector<int> deps;
- int color_blend_mode;
+ bool passthrough = false;
+ bool fullscreen = false;
- bool copy_background;
+ vec2 size;
- mri_model image;
+ void get_model(f32 width, f32 height, bool flip);
- vec2 size;
- vec3 origin;
- vec3 scale;
+ mat4x4 ortho;
+ mat4x4 model;
- bool visible;
+ RenderObject *gl_uv_object = nullptr;
+ RenderObject *gl_object = nullptr;
- bool passthrough;
- bool fullscreen;
+ BlendMode color_blend_mode;
- gl_object gl_uv_object;
- gl_object gl_object;
-
- mat4 ortho;
- mat4 model;
+ std::string get_target_buffer() const;
+ std::string get_texture_buffer() const;
- mri_framebuffer *abuffer;
- mri_framebuffer *bbuffer;
+ void swap_buffer() {
+ this->buffer_switch = !this->buffer_switch;
+ }
- bool buffer_switch;
+ std::vector<Pass *> passes;
- bool loaded;
+ void load(Engine *engine);
+ void update(Engine *engine);
+ void draw(Engine *engine);
- mvec(mri_effect) effects;
-};
+ private:
+ bool visible;
-void mri_object_get_model(mri_object *object, mat4 model, float width, float height);
+ Model *image = nullptr;
-void mri_object_switch_buffer(mri_object *object);
-mri_framebuffer *mri_object_get_target_buffer(mri_object *object);
-mri_texture *mri_object_get_texture_buffer(mri_object *object);
+ vec3 angles;
+ vec3 color;
+
+ vec3 origin;
+ vec3 scale;
+
+ std::string abuffer;
+ std::string bbuffer;
+
+ bool buffer_switch = false;
+
+ bool loaded = false;
+
+ std::vector<Effect *> effects;
+};
-void mri_object_parse(mri_object *object, json_t *root);
-void mri_object_load(mri_engine *engine, mri_object *object);
-void mri_object_draw(mri_engine *engine, mri_object *object);
-void mri_object_unload(mri_object *object);
+} // namespace Mauri
#endif // _OBJECT_H
diff --git a/src/objects/pass.c b/src/objects/pass.c
deleted file mode 100644
index df3b70d..0000000
--- a/src/objects/pass.c
+++ /dev/null
@@ -1,405 +0,0 @@
-#include <jansson.h>
-#include <unistd.h>
-
-#include "moro_str.h"
-#include "moro_vec.h"
-#include "pass.h"
-#include "material.h"
-#include "model.h"
-#include "object.h"
-#include "scene.h"
-
-#include "../json.h"
-#include "../texture.h"
-#include "../engine.h"
-#include "../assets.h"
-#include "../gl.h"
-#include "../objects/types.h"
-#include "../shader.h"
-
-void mri_pass_parse(mri_pass *pass, json_t *root, mri_pass_stage stage) {
- memset(pass, 0, sizeof(mri_pass));
-
- switch (stage) {
- case EFFECT0_PASS: {
- mvec_init(pass->uniforms);
-
- json_t *uniform;
- json_t *uniforms = json_object_get(root, "constantshadervalues");
-
- void *iter = json_object_iter(uniforms);
-
- while (iter) {
- uniform = json_object_iter_value(iter);
-
- mri_uniform u = {
- .name = mstr_from(json_object_iter_key(iter))
- };
-
- if (json_is_object(uniform)) {
- uniform = json_object_get(uniform, "value");
- }
-
- if (json_is_number(uniform)) {
- u.value[0] = json_number_value(uniform);
- } else if (json_is_string(uniform)) {
- sscanf_vec4(json_string_value(uniform), u.value);
- }
-
- mvec_push(pass->uniforms, u);
-
- iter = json_object_iter_next(uniforms, iter);
- }
-
- break;
- }
- case EFFECT1_PASS: {
- json_t *material = json_object_get(root, "material");
- if (json_is_string(material)) {
- pass->material = (mri_material *)calloc(1, sizeof(mri_material));
- mri_material_parse(pass->material, material);
- }
-
- json_t *target = json_object_get(root, "target");
- if (json_is_string(target)) {
- pass->target = mstr_from(json_string_value(target));
- }
-
- json_t *bind;
- json_t *binds = json_object_get(root, "bind");
- json_array(bind, binds) {
- int index = json_integer_value(json_object_get(bind, "index"));
- pass->binds[index] = mstr_from(json_string_value(json_object_get(bind, "name")));
- }
-
- break;
- }
- case MATERIAL_ONLY_PASS:
- case MATERIAL_PASS: {
- json_t *shader = json_object_get(root, "shader");
- if (json_is_string(shader)) {
- pass->shader = (mri_shader *)calloc(1, sizeof(mri_shader));
- mri_shader_load(pass->shader, mstr_c(json_string_value(shader)));
- }
-
- json_t *blend = json_object_get(root, "blending");
- if (json_is_string(blend)) {
- if (mstr_eq(mstr_c(json_string_value(blend)), mstr_c("normal"))) {
- pass->blend = NORMAL;
- } else if (mstr_eq(mstr_c(json_string_value(blend)), mstr_c("translucent"))) {
- pass->blend = TRANSLUCENT;
- }
- }
-
- break;
- }
- }
-
- json_t *texture;
- json_t *textures = json_object_get(root, "textures");
- json_array(texture, textures) {
- if (json_is_string(texture)) {
- pass->textures[i] = mstr_from(json_string_value(texture));
- }
- }
-
- mvec_init(pass->combos);
-
- json_t *combo;
- json_t *combos = json_object_get(root, "combos");
-
- void *iter = json_object_iter(combos);
-
- while (iter) {
- combo = json_object_iter_value(iter);
-
- mri_combo c = {
- .name = mstr_from(json_object_iter_key(iter))
- };
-
- if (json_is_integer(combo)) {
- c.value = json_integer_value(combo);
- }
-
- mvec_push(pass->combos, c);
-
- iter = json_object_iter_next(combo, iter);
- }
-}
-
-void mri_pass_load(mri_engine *engine, mri_pass *pass, mri_pass_stage stage, mri_render_pass *rpass) {
- mri_object *object = engine->current_object;
-
- for (int i = 0; i < 7; i++) {
- if (pass->textures[i]) {
- mri_asset *texture_asset = mri_asset_manager_get(
- pass->textures[i], TEXTURE);
- if (texture_asset->type != ASSET_VOID) {
- rpass->textures[i] = mri_texture_load(engine, texture_asset);
- } else {
- mri_framebuffer *buffer = mri_engine_get_framebuffer(
- engine, pass->textures[i]);
- if (buffer) {
- rpass->textures[i] = &buffer->texture;
- }
- }
- }
- }
-
- mri_combo *combo;
- mvec_loop_ptr(pass->combos, combo, i) {
- mvec_push(rpass->combos, *combo);
- }
-
- switch (stage) {
- case EFFECT0_PASS: {
- mri_uniform *uniform;
- mvec_loop_ptr(pass->uniforms, uniform, i) {
- mvec_push(rpass->uniforms, *uniform);
- }
- break;
- }
- case EFFECT1_PASS:
- // If there is an explicit target framebuffer, set it.
- if (!pass->target) {
- if (rpass->combine) {
- rpass->target = engine->combine_buffer;
- } else {
- // If no target was specified pick the next buffer in the
- // alternating AB buffers.
- rpass->target = mri_object_get_target_buffer(object);
- }
- rpass->textures[0] = mri_object_get_texture_buffer(object);
- } else {
- mstr *effect_buffer_id = mstr_sprintf("%i_%i", rpass->effect->id, rpass->object->id);
-
- mstr_cat(pass->target, effect_buffer_id);
- mstr_free(effect_buffer_id);
-
- rpass->target = mri_engine_get_framebuffer(engine, pass->target);
- }
-
- for (int i = 0; i < 7; i++) {
- if (!pass->binds[i]) continue;
- // If there are explicit binds given for this pass, set them.
- if (mstr_eq(pass->binds[i], mstr_c("previous"))) {
- rpass->textures[i] = mri_object_get_texture_buffer(object);
- } else {
- mstr *effect_buffer_id = mstr_sprintf("%i_%i", rpass->effect->id, rpass->object->id);
-
- mstr_cat(pass->binds[i], effect_buffer_id);
- mstr_free(effect_buffer_id);
-
- rpass->textures[i] = &mri_engine_get_framebuffer(engine, pass->binds[i])->texture;
- }
- }
-
- // If we selected one of the AB buffers, switch the flag _after_
- // setting binds to keep the ordering correct.
- if (!pass->target) mri_object_switch_buffer(object);
-
- // EFFECT1 passes has the material with the final draw passes.
- mri_material_load(engine, pass->material, MATERIAL_EFFECT, rpass, false);
- break;
- case MATERIAL_ONLY_PASS:
- // There is no EFFECT1 pass before this to set the target, so set it here.
- if (rpass->combine) {
- rpass->target = engine->combine_buffer;
- } else {
- rpass->target = mri_object_get_target_buffer(object);
- mri_object_switch_buffer(object);
- }
- rpass->combine_blend = pass->blend;
- __attribute__ ((fallthrough));
- case MATERIAL_PASS: {
- rpass->shader = *pass->shader;
-
- mvec_clone(rpass->shader.uniforms, pass->shader->uniforms);
- mvec_clone(rpass->shader.combos, pass->shader->combos);
-
- for (int i = 0; i < 7; i++) {
- // As the last step for shaders, set any unset texture slots
- // with the default textures from the shader is there is any.
- if (!rpass->textures[i] && rpass->shader.textures[i]) {
- mri_asset *texture_asset = mri_asset_manager_get(
- rpass->shader.textures[i], TEXTURE);
- if (texture_asset->type != ASSET_VOID) {
- rpass->textures[i] = mri_texture_load(engine, texture_asset);
- }
- }
-
- // Set TEX0FORMAT in-case extra steps are needed when sampling,
- // see "common_fragment.h".
- if (rpass->textures[i] && i == 0) {
- mri_combo c = {
- .name = mstr_from("TEX0FORMAT"),
- .value = rpass->textures[i]->format
- };
- mvec_push(rpass->shader.combos, c);
- }
- }
-
- mri_uniform *pass_uniform, *shader_uniform;
- mvec_loop_ptr(rpass->shader.uniforms, shader_uniform, i) {
- // ex: g_Texture2Resolution (vec4)
- // ^ index
- if (mstr_eqn(shader_uniform->uname, mstr_c("g_Texture"), 9) &&
- mstr_cmp(shader_uniform->uname, mstr_c("Resolution"), 10, 10) == 0) {
- int index = shader_uniform->uname->ptr[9] - '0';
- if (rpass->textures[index]) {
- memcpy(shader_uniform->value,
- rpass->textures[index]->texture_resolution, sizeof(vec4));
- }
- }
- }
-
- // Handle uniform value overrides.
- mvec_loop_ptr(rpass->uniforms, pass_uniform, i)
- mvec_loop_ptr(rpass->shader.uniforms, shader_uniform, s) {
- if (!shader_uniform->name) continue;
- if (mstr_eq(pass_uniform->name, shader_uniform->name)) {
- memcpy(shader_uniform->value, pass_uniform->value, sizeof(vec4));
- break;
- }
- }
-
- mri_combo *pass_combo, *shader_combo;
- mvec_loop_ptr(rpass->shader.combos, shader_combo, s) {
- if (mstr_eq(shader_combo->name, mstr_c("AUDIOPROCESSING"))) {
- shader_combo->value = 0;
- break;
- }
- }
-
- // Handle combo value overrides.
- mvec_loop_ptr(rpass->combos, pass_combo, i) {
- bool override = false;
- mvec_loop_ptr(rpass->shader.combos, shader_combo, s) {
- if (mstr_eq(pass_combo->name, shader_combo->name)) {
- shader_combo->value = pass_combo->value;
- override = true;
- break;
- }
- }
- if (!override) {
- mvec_push(rpass->shader.combos, *pass_combo);
- }
- }
-
- // compile the shader with the new combo values.
- mri_shader_compile(&rpass->shader);
-
- break;
- }
- }
-}
-
-static void viewport_center_scale(float w0, float h0, float w1, float h1) {
- float w_scale = w1 / w0;
- float h_scale = h1 / h0;
-
- float scale = (w_scale > h_scale) ? w_scale : h_scale;
-
- float width = w0 * scale;
- float height = h0 * scale;
-
- float wpad = (width - w1) / -2.f;
- float hpad = (height - h1) / -2.f;
-
- glViewport(wpad, hpad, width, height);
-}
-
-static void viewport_default(float w0, float h0) {
- glViewport(0, 0, w0, h0);
-}
-
-void mri_render_pass_draw(mri_engine *engine, mri_render_pass *pass) {
- mri_framebuffer_bind(pass->target);
- mri_shader_bind(engine, &pass->shader, pass->model);
-
- bind_gl_object(pass->gl_object);
-
- for (int i = 0; i < pass->shader.texture_count; i++) {
- if (pass->textures[i]) mri_texture_bind(pass->textures[i], i);
- }
-
- mri_pass_blend_mode blend;
-
- if (pass->combine) {
- blend = pass->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;
- }
-
- if (pass->combine) {
- viewport_center_scale(engine->width, engine->height, engine->context->width, engine->context->height);
- } else {
- viewport_default(pass->target->width, pass->target->height);
- }
-
- if (pass->object->visible)
- glDrawArrays(GL_TRIANGLES, 0, 6);
-
- for (int i = 0; i < pass->shader.texture_count; i++) {
- glActiveTexture(GL_TEXTURE0 + i);
- glBindTexture(GL_TEXTURE_2D, 0);
- }
-
-#if 0
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
- glBindFramebuffer(GL_READ_FRAMEBUFFER, pass->target->buffer.id);
-
- glBlitFramebuffer(0, engine->context->height, engine->context->width, 0, 0, 0,
- engine->context->width, engine->context->height,
- GL_COLOR_BUFFER_BIT, GL_NEAREST);
-
- engine->context->swap_buffers(engine->context);
-
- usleep(1400000);
-#endif
-}
-
-void mri_pass_unload(mri_pass *pass) {
- // TODO render pass unloading
-
- for (int i = 0; i < 7; i++) {
- if (pass->textures[i]) mstr_free(pass->textures[i]);
- }
-
- mri_uniform *uniform;
- mvec_loop_ptr(pass->uniforms, uniform, i) {
- mstr_free(uniform->name);
- }
-
- mri_combo *combo;
- mvec_loop_ptr(pass->combos, combo, i) {
- mstr_free(combo->name);
- }
-
- mvec_free(pass->uniforms);
- mvec_free(pass->combos);
-
- if (pass->shader) {
- mri_shader_unload(pass->shader);
- free(pass->shader);
- }
-
- if (pass->material) {
- mri_material_unload(pass->material);
- free(pass->material);
- }
-
- if (pass->target)
- mstr_free(pass->target);
-}
diff --git a/src/objects/pass.cc b/src/objects/pass.cc
new file mode 100644
index 0000000..7825602
--- /dev/null
+++ b/src/objects/pass.cc
@@ -0,0 +1,346 @@
+#include <fmt/core.h>
+#include <glm/fwd.hpp>
+#include <glm/gtc/type_ptr.hpp>
+#include <thread>
+
+#include "assets.h"
+#include "engine.h"
+#include "gl.h"
+#include "json.h"
+#include "shader.h"
+#include "json.h"
+#include "texture.h"
+
+#include "objects/pass.h"
+#include "objects/material.h"
+#include "objects/model.h"
+#include "objects/object.h"
+#include "objects/scene.h"
+
+using namespace Mauri;
+
+Pass::Pass(Json::Value root, PassStage stage)
+{
+ switch (stage)
+ {
+ case EFFECT0_PASS: {
+ auto uniforms = root["constantshadervalues"];
+
+ for (auto &name : uniforms.getMemberNames())
+ {
+ auto uniform = Uniform();
+
+ uniform.name = name;
+
+ json_number(json_user_value(uniforms[name]),
+ glm::value_ptr(uniform.value));
+
+ this->uniforms.push_back(uniform);
+ }
+
+ break;
+ }
+ case EFFECT1_PASS: {
+ auto material = root["material"];
+
+ if (material.isString())
+ this->material = new Material(material.asString());
+
+ this->target = root.get("target", "previous").asString();
+
+ for (auto &bind : root["bind"])
+ {
+ auto index = bind["index"].asInt();
+ this->binds[index] = bind["name"].asString();
+ }
+
+ break;
+ }
+ case MATERIAL_ONLY_PASS:
+ this->target = "previous";
+ [[fallthrough]];
+ case MATERIAL_PASS: {
+ this->shader = root["shader"].asString();
+
+ auto blend = root.get("blending", "normal").asString();
+
+ if (blend == "normal")
+ this->blend = NORMAL;
+ else if (blend == "translucent")
+ this->blend = TRANSLUCENT;
+
+ break;
+ }
+ }
+
+ auto _textures = root["textures"];
+
+ for (int i = 0; i < textures.size(); i++)
+ {
+ auto texture = _textures[i];
+ if (texture.isString())
+ this->textures[i] = texture.asString();
+ }
+
+ auto _combos = root["combos"];
+
+ for (auto &name : _combos.getMemberNames())
+ {
+ this->combos.emplace_back((Combo){name, _combos[name].asInt()});
+ }
+}
+
+void Pass::load(PassStage stage, Pass *pass)
+{
+ for (int i = 0; i < 8; i++)
+ {
+ if (this->textures[i].empty())
+ continue;
+
+ pass->textures[i] = this->textures[i];
+ }
+
+ for (auto &combo : this->combos)
+ {
+ pass->combos.push_back(combo);
+ }
+
+ switch (stage)
+ {
+ case EFFECT0_PASS:
+ for (auto &uniform : this->uniforms)
+ {
+ pass->uniforms.push_back(uniform);
+ }
+ break;
+ case EFFECT1_PASS:
+ pass->target = this->target;
+
+ if (pass->target == "previous")
+ {
+ if (pass->combine)
+ pass->target = COMBINE_BUFFER;
+ else
+ pass->target = pass->object->get_target_buffer();
+
+ pass->textures[0] = pass->object->get_texture_buffer();
+ }
+ else
+ pass->target.append(pass->effect->buffer_id);
+
+ for (int i = 0; i < 8; i++)
+ {
+ if (this->binds[i].empty())
+ continue;
+
+ if (this->binds[i] == "previous")
+ pass->textures[i] = pass->object->get_texture_buffer();
+ else
+ pass->textures[i] = this->binds[i] + pass->effect->buffer_id;
+ }
+
+ if (this->target == "previous")
+ pass->object->swap_buffer();
+
+ if (this->material != nullptr)
+ this->material->load(pass->object, MATERIAL_EFFECT, pass, false);
+
+ break;
+ case MATERIAL_ONLY_PASS:
+ if (pass->combine)
+ pass->target = COMBINE_BUFFER;
+ else
+ {
+ pass->target = pass->object->get_target_buffer();
+ pass->object->swap_buffer();
+ }
+ [[fallthrough]];
+ case MATERIAL_PASS:
+ pass->shader = this->shader;
+ break;
+ }
+}
+
+void Pass::generate_pass(Engine *engine)
+{
+ this->rpass = new RenderPass();
+
+ this->rpass->combine = this->combine;
+ this->rpass->combine_blend = this->object->color_blend_mode;
+
+ this->rpass->shader = new Shader(this->shader);
+
+ auto rshader = this->rpass->shader;
+
+ for (int i = 0; i < 8; i++)
+ {
+ if (this->textures[i].empty() && !rshader->textures[i].empty())
+ this->textures[i] = rshader->textures[i];
+
+ if (this->textures[i].empty())
+ continue;
+
+ auto asset = asset_manager()->get_file(this->textures[i], TEXTURE);
+
+ if (asset->type != ASSET_VOID)
+ this->rpass->textures[i] = new Texture(asset);
+ else
+ this->rpass->textures[i] = engine->get_framebuffer_texture(this->textures[i]);
+ }
+
+ for (auto &uniform : rshader->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 (this->rpass->textures[index] != nullptr)
+ uniform.value = this->rpass->textures[index]->texture_resolution;
+ }
+ }
+
+ for (auto &pass_uniform : this->uniforms)
+ {
+ for (auto &shader_uniform : rshader->uniforms)
+ {
+ if (shader_uniform.name.empty())
+ continue;
+ if (pass_uniform.name == shader_uniform.name)
+ {
+ shader_uniform.value = pass_uniform.value;
+ break;
+ }
+ }
+ }
+
+ for (auto &combo : rshader->combos)
+ {
+ if (combo.name == "AUDIOPROCESSING")
+ {
+ combo.value = 0;
+ break;
+ }
+ }
+
+ for (auto &pass_combo : this->combos)
+ {
+ auto add = true;
+ for (auto &shader_combo : rshader->combos)
+ {
+ if (pass_combo.name == shader_combo.name)
+ {
+ shader_combo.value = pass_combo.value;
+ add = false;
+ break;
+ }
+ }
+ if (add)
+ rshader->combos.push_back(pass_combo);
+ }
+
+ this->rpass->shader->compile();
+
+ this->rpass->target = engine->get_framebuffer(this->target);
+
+ if (this->effect == nullptr)
+ {
+ if (this->object->passthrough || this->combine)
+ this->rpass->model = &this->object->model;
+ else
+ this->rpass->model = &this->object->ortho;
+
+ if (this->object->passthrough)
+ this->rpass->robject = this->object->gl_object;
+ else
+ this->rpass->robject = this->object->gl_uv_object;
+ }
+ else
+ {
+ if (this->combine)
+ {
+ this->rpass->robject = this->object->gl_object;
+ this->rpass->model = &this->object->model;
+ }
+ else
+ {
+ this->rpass->robject = engine->default_object;
+ this->rpass->model = &engine->identity;
+ }
+ }
+}
+
+void Pass::draw(Engine *engine)
+{
+ if (this->rpass != nullptr)
+ this->rpass->draw(engine);
+}
+
+Pass::~Pass()
+{
+ if (this->material != nullptr)
+ delete this->material;
+
+ if (this->rpass != nullptr)
+ delete this->rpass;
+}
+
+void RenderPass::draw(Engine *engine)
+{
+ this->target->buffer->bind();
+ this->shader->bind(engine, this->model);
+
+ this->robject->bind();
+
+ for (int i = 0; i < this->shader->texture_count; i++)
+ {
+ if (this->textures[i] != nullptr)
+ this->textures[i]->bind(i);
+ }
+
+ BlendMode blend;
+
+ if (this->combine)
+ blend = this->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;
+ }
+
+ if (this->combine)
+ engine->view.center_scale(engine->context->width, engine->context->height);
+ else
+ engine->view.default_viewport(this->target->buffer->width, this->target->buffer->height);
+
+ glDrawArrays(GL_TRIANGLES, 0, 6);
+
+#if 0
+ engine->combine_buffer->buffer->blit(this->context->width, this->context->height);
+ engine->context->swap_buffers();
+ std::this_thread::sleep_for(std::chrono::seconds(1));
+#endif
+}
+
+RenderPass::~RenderPass()
+{
+ if (this->shader != nullptr)
+ delete this->shader;
+
+ for (int i = 0; i < 8; i++)
+ {
+ if (this->textures[i] != nullptr && !this->textures[i]->wrapped)
+ delete this->textures[i];
+ }
+}
+
diff --git a/src/objects/pass.h b/src/objects/pass.h
index 59dcdba..f7d5129 100644
--- a/src/objects/pass.h
+++ b/src/objects/pass.h
@@ -1,79 +1,86 @@
#ifndef _PASS_H
#define _PASS_H
-#include <jansson.h>
+#include <glm/glm.hpp>
+#include <jsoncpp/json/json.h>
-#include "src/gl.h"
-#include "types.h"
+#include "context.h"
+#include "engine.h"
+#include "gl.h"
+#include "shader.h"
+#include "texture.h"
-#include "../context.h"
-#include "../shader.h"
-#include "../texture.h"
+#include "objects/object.h"
-typedef enum {
- EFFECT0_PASS,
- EFFECT1_PASS,
- MATERIAL_PASS,
- MATERIAL_ONLY_PASS
-} mri_pass_stage;
+namespace Mauri
+{
-typedef enum {
- BACKGROUND,
- BACKGROUND_ONLY,
- TRANSFORM,
- COMBINE,
- PASS,
-} mri_render_pass_stage;
+enum PassStage
+{
+ EFFECT0_PASS,
+ EFFECT1_PASS,
+ MATERIAL_PASS,
+ MATERIAL_ONLY_PASS
+};
-typedef enum {
- TRANSLUCENT,
- NORMAL
-} mri_pass_blend_mode;
+struct RenderPass;
-struct mri_pass {
- int id;
+class Pass
+{
+ public:
+ Pass() {}
+ Pass(Json::Value root, PassStage stage);
- mri_material *material;
+ ~Pass();
- mri_shader *shader;
+ std::string target;
- mstr *textures[7];
+ Object *object;
+ Effect *effect;
- mstr *target;
- mstr *binds[7];
+ bool combine;
- mri_pass_blend_mode blend;
+ void load(PassStage stage, Pass *pass);
+ void draw(Engine *engine);
- mvec(mri_uniform) uniforms;
- mvec(mri_combo) combos;
-};
+ void generate_pass(Engine *engine);
-struct mri_render_pass {
- mri_shader shader;
+ private:
+ std::string shader;
- mri_object *object;
- mri_effect *effect;
+ Material *material = nullptr;
- mat4 model;
- gl_object *gl_object;
+ std::array<std::string, 8> textures;
+ std::array<std::string, 8> binds;
- mri_texture *textures[7];
- mri_framebuffer *target;
+ BlendMode blend;
- bool combine;
+ std::vector<Uniform> uniforms;
+ std::vector<Combo> combos;
- mri_pass_blend_mode combine_blend;
+ RenderPass *rpass = nullptr;
+};
- mri_render_pass_stage stage;
+struct RenderPass
+{
+ RenderPass() {};
+ ~RenderPass();
- mvec(mri_uniform) uniforms;
- mvec(mri_combo) combos;
-};
+ Shader *shader;
+ Framebuffer *target;
+
+ mat4x4 *model;
+ RenderObject *robject;
-void mri_pass_parse(mri_pass *pass, json_t *root, mri_pass_stage stage);
-void mri_pass_load(mri_engine *engine, mri_pass *pass, mri_pass_stage stage, mri_render_pass *rpass);
-void mri_pass_unload(mri_pass *pass);
+ bool combine;
+
+ BlendMode combine_blend;
+
+ std::array<Texture *, 8> textures = {0};
+
+ void draw(Engine *engine);
+};
-void mri_render_pass_draw(mri_engine *engine, mri_render_pass *pass);
+} // namespace Mauri
#endif // _PASS_H
diff --git a/src/objects/scene.c b/src/objects/scene.c
deleted file mode 100644
index 3bcd6ac..0000000
--- a/src/objects/scene.c
+++ /dev/null
@@ -1,104 +0,0 @@
-#include <jansson.h>
-#include <moro_vec.h>
-
-#include "scene.h"
-#include "object.h"
-
-#include "../json.h"
-#include "../log.h"
-#include "../engine.h"
-#include "src/objects/types.h"
-
-void mri_scene_parse(mri_scene *scene) {
- mri_asset *scene_asset = mri_asset_manager_get(mstr_c("scene.json"), NONE);
-
- if (scene_asset->type == ASSET_VOID) {
- log_error("err: failed to open scene.json");
- return;
- }
-
- json_t *root = json_load_mstr(mri_asset_as_str(scene_asset));
-
- json_t *camera = json_object_get(root, "camera");
- json_t *general = json_object_get(root, "general");
- json_t *ortho = json_object_get(general, "orthogonalprojection");
-
- json_get_vec3(&scene->camera.center, camera, "center");
- json_get_vec3(&scene->camera.eye, camera, "eye");
- json_get_vec3(&scene->camera.up, camera, "up");
-
- json_get_bool(&scene->clear_enabled, general, "clearenabled");
-
- json_get_vec3((vec3 *)&scene->clear_color, general, "clearcolor");
- scene->clear_color[3] = 1.f;
-
- json_get_vec3(&scene->ambient_color, general, "ambientcolor");
- json_get_vec3(&scene->skylight_color, general, "skylightcolor");
-
- json_get_float(&scene->width, ortho, "width");
- json_get_float(&scene->height, ortho, "height");
-
- mvec_init(scene->objects);
-
- json_t *object;
- json_t *objects = json_object_get(root, "objects");
- json_array(object, objects) {
- mri_object_parse(mvec_next(scene->objects), object);
- }
-
- json_decref(root);
-}
-
-int mri_scene_framebuffer_count(mri_scene *scene) {
- int total = 0;
-
- mri_object *object;
- mvec_loop_ptr(scene->objects, object, i) {
- mri_effect *effect;
- mvec_loop_ptr(object->effects, effect, s) {
- mri_pass *pass;
- mvec_loop_ptr(effect->passes1, pass, j) {
- if (pass->target) {
- total++;
- }
- }
- }
- total += 2;
- }
-
- return total;
-}
-
-void mri_scene_load(mri_engine *engine, mri_scene *scene) {
- engine->width = scene->width;
- engine->height = scene->height;
-
- mri_object *object;
- mvec_loop_ptr(scene->objects, object, i) {
- int dep;
- mvec_loop(object->deps, dep, s) {
- mri_object *dep_object;
- mvec_loop_ptr(scene->objects, dep_object, j) {
- if (dep_object->id == dep) {
- mri_object_load(engine, dep_object);
- }
- }
- }
- mri_object_load(engine, object);
- }
-}
-
-void mri_scene_draw(mri_engine *engine, mri_scene *scene) {
- mri_object *object;
- mvec_loop_ptr(scene->objects, object, i) {
- mri_object_draw(engine, object);
- }
-}
-
-void mri_scene_unload(mri_scene *scene) {
- mri_object *object;
- mvec_loop_ptr(scene->objects, object, i) {
- mri_object_unload(object);
- }
- mvec_free(scene->objects);
-}
diff --git a/src/objects/scene.cc b/src/objects/scene.cc
new file mode 100644
index 0000000..5c00147
--- /dev/null
+++ b/src/objects/scene.cc
@@ -0,0 +1,120 @@
+#include <istream>
+#include <jsoncpp/json/json.h>
+#include <sstream>
+
+#include "assets.h"
+#include "json.h"
+#include "log.h"
+
+#include "objects/scene.h"
+#include "objects/pass.h"
+
+using namespace Mauri;
+
+Scene::Scene(std::string path)
+{
+ auto asset = asset_manager()->get_file(path, NONE);
+
+ if (asset->type == ASSET_VOID)
+ {
+ log_error("err: failed to open scene.json");
+ return;
+ }
+
+ Json::Value root = asset->as_json();
+
+ auto camera = root["camera"];
+ auto general = root["general"];
+ auto ortho = general["orthogonalprojection"];
+
+ sscanf_vec3(json_user_value(camera.get("center", "")).asCString(), this->camera.center);
+ sscanf_vec3(json_user_value(camera.get("eye", "")).asCString(), this->camera.eye);
+ sscanf_vec3(json_user_value(camera.get("up", "")).asCString(), this->camera.up);
+
+ this->clear_enabled = general.get("clearenabled", false).asBool();
+
+ sscanf_vec3(json_user_value(general.get("clearcolor", "")).asCString(), this->clear_color);
+ this->clear_color[3] = 1.f;
+
+ this->width = json_user_value(ortho.get("width", 0.f)).asFloat();
+ this->height = json_user_value(ortho.get("height", 0.f)).asFloat();
+
+ for (auto &object : root["objects"])
+ {
+ this->objects.emplace_back(new Object(object));
+ }
+}
+
+Object *Scene::get_object_by_id(u32 id)
+{
+ for (auto &object : this->objects)
+ {
+ if (object->id == id)
+ {
+ return object;
+ }
+ }
+
+ return nullptr;
+}
+
+void Scene::load(Engine *engine)
+{
+ engine->view.width = this->width;
+ engine->view.height = this->height;
+
+ for (auto &object : this->objects)
+ {
+ for (auto &dep : object->deps)
+ {
+ auto dep_object = this->get_object_by_id(dep);
+ if (dep_object)
+ dep_object->load(engine);
+ }
+
+ object->load(engine);
+ }
+
+ for (auto &object : this->objects)
+ {
+ for (auto &pass : object->passes)
+ pass->generate_pass(engine);
+ }
+}
+
+void Scene::draw(Engine *engine)
+{
+ for (auto &object : this->objects)
+ {
+ object->draw(engine);
+ }
+}
+
+Scene::~Scene()
+{
+ for (auto &object : this->objects)
+ {
+ delete object;
+ }
+}
+
+s32 Scene::estimated_buffer_count()
+{
+ return 0;
+// s32 total = 0;
+//
+// for (auto &object : this->objects)
+// {
+// for (auto &effect : object->effects)
+// {
+// for (auto &pass1 : effect->passes1)
+// {
+// if (!pass1->target.empty())
+// total++;
+// }
+// }
+// total += 2;
+// }
+//
+// return total;
+}
diff --git a/src/objects/scene.h b/src/objects/scene.h
index 9514580..47aa19a 100644
--- a/src/objects/scene.h
+++ b/src/objects/scene.h
@@ -1,47 +1,54 @@
#ifndef _SCENE_H
#define _SCENE_H
-#include <cglm/cglm.h>
-#include <moro_vec.h>
+#include <glm/glm.hpp>
-#include "types.h"
-#include "object.h"
+#include <vector>
-#include "../assets.h"
+#include "assets.h"
+#include "engine.h"
-struct mri_scene {
- float width;
- float height;
+#include "objects/object.h"
- struct {
- vec3 center;
- vec3 eye;
- vec3 up;
+using namespace glm;
- float farz;
- float nearz;
- float fov;
- } camera;
+namespace Mauri
+{
- bool clear_enabled;
+class Scene
+{
+ public:
+ Scene(std::string path);
+ ~Scene();
- vec4 clear_color;
- vec3 ambient_color;
- vec3 skylight_color;
+ f32 width;
+ f32 height;
- bool bloom;
+ bool clear_enabled;
+ vec4 clear_color;
- float bloom_strength;
- float bloom_threshold;
+ void load(Engine *engine);
+ void draw(Engine *engine);
- mvec(mri_object) objects;
-};
+ s32 estimated_buffer_count();
+
+ Object *get_object_by_id(u32 id);
+
+ std::vector<Object *> objects;
-void mri_scene_parse(mri_scene *scene);
-void mri_scene_load(mri_engine *engine, mri_scene *scene);
-void mri_scene_draw(mri_engine *engine, mri_scene *scene);
-void mri_scene_unload(mri_scene *scene);
+ private:
+ struct
+ {
+ vec3 center;
+ vec3 eye;
+ vec3 up;
+
+ float farz;
+ float nearz;
+ float fov;
+ } camera;
+};
-int mri_scene_framebuffer_count(mri_scene *scene);
+} // namespace Mauri
#endif // _SCENE_H
diff --git a/src/objects/types.h b/src/objects/types.h
deleted file mode 100644
index 76fd8eb..0000000
--- a/src/objects/types.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef _TYPES_H
-#define _TYPES_H
-
-typedef struct mri_scene mri_scene;
-typedef struct mri_object mri_object;
-typedef struct mri_model mri_model;
-typedef struct mri_material mri_material;
-typedef struct mri_pass mri_pass;
-typedef struct mri_effect mri_effect;
-
-typedef struct mri_render_pass mri_render_pass;
-
-typedef struct mri_engine mri_engine;
-
-#endif // _TYPES_H