From 4c200513158ad0b974cda961deffe6192830ecae Mon Sep 17 00:00:00 2001 From: Andrew Opalach Date: Thu, 1 Oct 2020 04:28:13 -0400 Subject: switch to c++, add dxt5 and dxt1 handling --- src/objects/effect.c | 133 ---------------- src/objects/effect.cc | 90 +++++++++++ src/objects/effect.h | 49 +++--- src/objects/material.c | 87 ----------- src/objects/material.cc | 64 ++++++++ src/objects/material.h | 37 +++-- src/objects/model.c | 43 ----- src/objects/model.cc | 40 +++++ src/objects/model.h | 35 +++-- src/objects/object.c | 175 +-------------------- src/objects/object.cc | 174 +++++++++++++++++++++ src/objects/object.h | 110 +++++++------ src/objects/pass.c | 405 ------------------------------------------------ src/objects/pass.cc | 346 +++++++++++++++++++++++++++++++++++++++++ src/objects/pass.h | 111 ++++++------- src/objects/scene.c | 104 ------------- src/objects/scene.cc | 120 ++++++++++++++ src/objects/scene.h | 67 ++++---- src/objects/types.h | 15 -- 19 files changed, 1067 insertions(+), 1138 deletions(-) delete mode 100644 src/objects/effect.c create mode 100644 src/objects/effect.cc delete mode 100644 src/objects/material.c create mode 100644 src/objects/material.cc delete mode 100644 src/objects/model.c create mode 100644 src/objects/model.cc create mode 100644 src/objects/object.cc delete mode 100644 src/objects/pass.c create mode 100644 src/objects/pass.cc delete mode 100644 src/objects/scene.c create mode 100644 src/objects/scene.cc delete mode 100644 src/objects/types.h (limited to 'src/objects') 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 - -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 + +#include +#include + +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 +#include -#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 passes0; + std::vector passes1; - mvec(mri_effect_buffer) fbos; + std::vector 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 - -#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 + +#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 +#include -#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 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 -#include - -#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 + +#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 +#include -#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 -#include - -#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 +#include +#include + +#include +#include +#include + +#include + +#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 -#include -#include -#include +#include +#include + +#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 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 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 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 -#include - -#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 +#include +#include +#include + +#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 +#include +#include + +#include "context.h" +#include "engine.h" +#include "gl.h" +#include "shader.h" +#include "texture.h" + +#include "objects/object.h" + +namespace Mauri +{ + +enum PassStage +{ + EFFECT0_PASS, + EFFECT1_PASS, + MATERIAL_PASS, + MATERIAL_ONLY_PASS +}; -#include "src/gl.h" -#include "types.h" +struct RenderPass; -#include "../context.h" -#include "../shader.h" -#include "../texture.h" +class Pass +{ + public: + Pass() {} + Pass(Json::Value root, PassStage stage); -typedef enum { - EFFECT0_PASS, - EFFECT1_PASS, - MATERIAL_PASS, - MATERIAL_ONLY_PASS -} mri_pass_stage; + ~Pass(); -typedef enum { - BACKGROUND, - BACKGROUND_ONLY, - TRANSFORM, - COMBINE, - PASS, -} mri_render_pass_stage; + std::string target; -typedef enum { - TRANSLUCENT, - NORMAL -} mri_pass_blend_mode; + Object *object; + Effect *effect; -struct mri_pass { - int id; + bool combine; - mri_material *material; + void load(PassStage stage, Pass *pass); + void draw(Engine *engine); - mri_shader *shader; + void generate_pass(Engine *engine); - mstr *textures[7]; + private: + std::string shader; - mstr *target; - mstr *binds[7]; + Material *material = nullptr; - mri_pass_blend_mode blend; + std::array textures; + std::array binds; - mvec(mri_uniform) uniforms; - mvec(mri_combo) combos; -}; + BlendMode blend; -struct mri_render_pass { - mri_shader shader; + std::vector uniforms; + std::vector combos; - mri_object *object; - mri_effect *effect; + RenderPass *rpass = nullptr; +}; - mat4 model; - gl_object *gl_object; +struct RenderPass +{ + RenderPass() {}; + ~RenderPass(); - mri_texture *textures[7]; - mri_framebuffer *target; + Shader *shader; + Framebuffer *target; - bool combine; + mat4x4 *model; + RenderObject *robject; - mri_pass_blend_mode combine_blend; + bool combine; - mri_render_pass_stage stage; + BlendMode combine_blend; - mvec(mri_uniform) uniforms; - mvec(mri_combo) combos; -}; + std::array textures = {0}; -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); + 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 -#include - -#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 +#include +#include + +#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 -#include +#include -#include "types.h" -#include "object.h" +#include -#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 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 -- cgit v1.2.3-101-g0448