diff options
Diffstat (limited to 'src/objects')
| -rw-r--r-- | src/objects/effect.c | 59 | ||||
| -rw-r--r-- | src/objects/effect.h | 18 | ||||
| -rw-r--r-- | src/objects/material.c | 38 | ||||
| -rw-r--r-- | src/objects/material.h | 7 | ||||
| -rw-r--r-- | src/objects/model.c | 17 | ||||
| -rw-r--r-- | src/objects/model.h | 8 | ||||
| -rw-r--r-- | src/objects/object.c | 82 | ||||
| -rw-r--r-- | src/objects/object.h | 19 | ||||
| -rw-r--r-- | src/objects/pass.c | 212 | ||||
| -rw-r--r-- | src/objects/pass.h | 26 | ||||
| -rw-r--r-- | src/objects/scene.c | 30 | ||||
| -rw-r--r-- | src/objects/scene.h | 6 | ||||
| -rw-r--r-- | src/objects/types.h | 11 |
13 files changed, 463 insertions, 70 deletions
diff --git a/src/objects/effect.c b/src/objects/effect.c new file mode 100644 index 0000000..1ab6df3 --- /dev/null +++ b/src/objects/effect.c @@ -0,0 +1,59 @@ +#include "effect.h" +#include "../json.h" + +void mri_effect_parse(mri_effect *effect, json_t *root) { + mvec_init(effect->passes0); + mvec_init(effect->passes1); + + 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)); + + 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); + } + } +} + +void mri_effect_load(mri_engine *engine, mri_effect *effect) { + mri_engine_next_effect(engine); + + mri_pass *pass; + + mvec_loop_ptr(effect->passes0, pass, i) { + mri_engine_next_pass(engine); + mri_pass_load(engine, pass, EFFECT0_PASS); + } + + mvec_loop_ptr(effect->passes1, pass, i) { + mri_pass_load(engine, pass, EFFECT1_PASS); + } +} + +void mri_effect_unload(mri_effect *effect) { + 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); +} diff --git a/src/objects/effect.h b/src/objects/effect.h new file mode 100644 index 0000000..76af254 --- /dev/null +++ b/src/objects/effect.h @@ -0,0 +1,18 @@ +#ifndef _EFFECT_H +#define _EFFECT_H + +#include <moro.h> + +#include "types.h" +#include "pass.h" + +struct mri_effect { + mvec(mri_pass) passes0; + mvec(mri_pass) passes1; +}; + +void mri_effect_parse(mri_effect *effect, json_t *root); +void mri_effect_load(mri_engine *engine, mri_effect *effect); +void mri_effect_unload(mri_effect *effect); + +#endif // _EFFECT_H diff --git a/src/objects/material.c b/src/objects/material.c index d01b8fe..d934970 100644 --- a/src/objects/material.c +++ b/src/objects/material.c @@ -1,40 +1,50 @@ #include "material.h" #include "pass.h" +#include <moro_str.h> + #include "../log.h" #include "../json.h" void mri_material_parse(mri_material *material, json_t *value) { - if (json_is_string(value)) { - mri_asset *asset = mri_asset_manager_get(json_string_value(value), NONE); + mvec_init(material->passes); - json_error_t error; - json_t *root = json_loadb((char *)asset->data, asset->size, 0, &error); + if (json_is_string(value)) { + mri_asset *material_asset = mri_asset_manager_get(mstr_c(json_string_value(value)), NONE); - if (!root) { - log_error("error parsing json on line %d: %s", error.line, error.text); + if (material_asset->type == ASSET_VOID) return; - } - mvec_init(material->passes); + 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 _pass; - mri_pass_parse(&_pass, pass); - mvec_push(material->passes, _pass); + mri_pass_parse(mvec_next(material->passes), pass, MATERIAL_PASS); } json_decref(root); - } else { - memset(material, 0, sizeof(mri_material)); + } +} + +void mri_material_load(mri_engine *engine, mri_material *material, mri_material_type t) { + mri_pass *pass; + mvec_loop_ptr(material->passes, pass, i) { + switch (t) { + case MATERIAL_EFFECT: + mri_pass_load(engine, pass, MATERIAL_PASS); + break; + case MATERIAL_MODEL: + mri_engine_next_pass(engine); + mri_pass_load(engine, pass, MATERIAL_ONLY_PASS); + break; + } } } void mri_material_unload(mri_material *material) { mri_pass *pass; - mvec_loop_ptr(material->passes, pass) { + mvec_loop_ptr(material->passes, pass, i) { mri_pass_unload(pass); } mvec_free(material->passes); diff --git a/src/objects/material.h b/src/objects/material.h index e7311c0..805a198 100644 --- a/src/objects/material.h +++ b/src/objects/material.h @@ -3,13 +3,20 @@ #include <jansson.h> +#include "types.h" #include "pass.h" +typedef enum { + MATERIAL_MODEL, + MATERIAL_EFFECT +} mri_material_type; + struct mri_material { mvec(mri_pass) passes; }; void mri_material_parse(mri_material *material, json_t *value); +void mri_material_load(mri_engine *engine, mri_material *material, mri_material_type t); void mri_material_unload(mri_material *material); #endif // MATERIAL_H diff --git a/src/objects/model.c b/src/objects/model.c index c821786..3fe8e1d 100644 --- a/src/objects/model.c +++ b/src/objects/model.c @@ -1,4 +1,5 @@ #include <jansson.h> +#include <moro_str.h> #include "../json.h" #include "../assets.h" @@ -8,15 +9,12 @@ void mri_model_parse(mri_model *model, json_t *value) { if (json_is_string(value)) { - mri_asset *asset = mri_asset_manager_get(json_string_value(value), NONE); + mri_asset *model_asset = mri_asset_manager_get(mstr_c(json_string_value(value)), NONE); - json_error_t error; - json_t *root = json_loadb((char *)asset->data, asset->size, 0, &error); - - if (!root) { - log_error("error parsing json on line %d: %s", error.line, error.text); + 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"); @@ -30,6 +28,11 @@ void mri_model_parse(mri_model *model, json_t *value) { } } +void mri_model_load(mri_engine *engine, mri_model *model) { + engine->current_effect = &engine->current_object->background; + mri_material_load(engine, &model->material, MATERIAL_MODEL); +} + void mri_model_unload(mri_model *model) { mri_material_unload(&model->material); } diff --git a/src/objects/model.h b/src/objects/model.h index f1068d7..38f4405 100644 --- a/src/objects/model.h +++ b/src/objects/model.h @@ -3,17 +3,21 @@ #include <jansson.h> +#include "types.h" #include "pass.h" #include "material.h" -typedef struct { +#include "../engine.h" + +struct mri_model { bool autosize; bool fullscreen; bool passthrough; mri_material material; -} mri_model; +}; void mri_model_parse(mri_model *model, json_t *value); +void mri_model_load(mri_engine *engine, mri_model *model); void mri_model_unload(mri_model *model); #endif // _MODEL_H diff --git a/src/objects/object.c b/src/objects/object.c index 6b679a0..55ed1c9 100644 --- a/src/objects/object.c +++ b/src/objects/object.c @@ -1,23 +1,17 @@ #include <jansson.h> +#include <cglm/cglm.h> +#include "types.h" #include "object.h" #include "model.h" #include "../log.h" +#include "../gl.h" #include "../json.h" void mri_object_parse(mri_object *object, json_t *root) { json_get_int(&object->id, root, "id"); - json_get_float(&object->alpha, root, "alpha"); - - json_get_vec3(&object->angles, root, "angles"); - json_get_vec3(&object->color, root, "color"); - - json_get_int(&object->color_blend_mode, root, "colorblendmode"); - - json_get_bool(&object->copy_background, root, "copybackground"); - mvec_init(object->deps); json_t *dep; @@ -27,26 +21,90 @@ void mri_object_parse(mri_object *object, json_t *root) { 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"); mri_model_parse(&object->image, json_object_get(root, "image")); json_get_bool(&object->visible, root, "visible"); - //mvec_init(object->effects); + json_t *config = json_object_get(root, "config"); + if (json_is_object(config)) { + json_get_bool(&object->passthrough, config, "passthrough"); + } + + mvec_init(object->effects); json_t *effect; json_t *effects = json_object_get(root, "effects"); json_array(effect, effects) { - // parse effect + bool visible; + json_get_bool(&visible, effect, "visible"); + if (visible) + 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) { + mri_engine_next_object(engine, object); + + mri_model_load(engine, &object->image); + + 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); } } void mri_object_unload(mri_object *object) { + mri_effect *effect; + mvec_loop_ptr(object->effects, effect, i) { + mri_effect_unload(effect); + } + + mvec_free(object->effects); mvec_free(object->deps); - //mvec_free(object->effects); + mri_model_unload(&object->image); } diff --git a/src/objects/object.h b/src/objects/object.h index 18c0dec..6965224 100644 --- a/src/objects/object.h +++ b/src/objects/object.h @@ -1,18 +1,23 @@ #ifndef _OBJECT_H #define _OBJECT_H -#include <moro_vec.h> +#include <moro.h> #include <jansson.h> #include <stdbool.h> #include <cglm/cglm.h> +#include "types.h" #include "model.h" +#include "pass.h" +#include "effect.h" + +#include "../gl.h" typedef enum { CENTER, } mri_object_alignment; -typedef struct { +struct mri_object { int id; char *name; @@ -37,10 +42,16 @@ typedef struct { bool visible; - //mvec(mri_effect) effects; -} mri_object; + bool passthrough; + bool fullscreen; + + mvec(mri_effect) effects; +}; + +void mri_object_get_model(mri_object *object, mat4 model, float width, float height); void mri_object_parse(mri_object *object, json_t *root); +void mri_object_load(mri_engine *engine, mri_object *object); void mri_object_unload(mri_object *object); #endif // _OBJECT_H diff --git a/src/objects/pass.c b/src/objects/pass.c index ba9de8c..942ea5e 100644 --- a/src/objects/pass.c +++ b/src/objects/pass.c @@ -1,31 +1,221 @@ #include "pass.h" #include "material.h" +#include "model.h" +#include "object.h" #include "../json.h" #include "../texture.h" #include "../assets.h" +#include "../gl.h" -void mri_pass_parse(mri_pass *pass, json_t *root) { - // TODO - pass->material = (mri_material *)malloc(sizeof(mri_material)); - mri_material_parse(pass->material, json_object_get(root, "material")); +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_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)) { + printf("%s\n", json_string_value(target)); + } + + json_t *binds = json_object_get(root, "binds"); + + if (json_is_array(binds)) { + printf("%li\n", json_array_size(binds)); + } + + 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))); + } + + break; + } + } json_t *texture; json_t *textures = json_object_get(root, "textures"); + json_array(texture, textures) { if (json_is_string(texture)) { - pass->textures[i] = mri_texture_load(mri_asset_manager_get(json_string_value(texture), TEXTURE)); - mri_texture_unload(pass->textures[i]); + mri_asset *_a = mri_asset_manager_get(mstr_c(json_string_value(texture)), TEXTURE); + if (_a->type != ASSET_VOID) { + pass->textures[i] = mri_texture_load(_a); + } } } - json_t *shader = json_object_get(root, "shader"); - if (json_is_string(shader)) { - mri_shader_load(&pass->shader, json_string_value(shader)); - mri_shader_unload(&pass->shader); + 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_object *robject = engine->current_object; + mri_render_pass *rpass = engine->current_pass; + + for (int i = 1; i < 7; i++) { + if (pass->textures[i]) rpass->textures[i] = pass->textures[i]; + } + + 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 (!robject->buffer_switch) { + rpass->target = robject->buffer_b; + rpass->textures[0] = &robject->buffer_a->texture; + } else { + rpass->target = robject->buffer_a; + rpass->textures[0] = &robject->buffer_b->texture; + } + robject->buffer_switch = !robject->buffer_switch; + mri_material_load(engine, pass->material, MATERIAL_EFFECT); + break; + case MATERIAL_ONLY_PASS: + rpass->target = robject->buffer_a; + rpass->textures[0] = pass->textures[0]; + case MATERIAL_PASS: { + memcpy(&rpass->shader, pass->shader, sizeof(mri_shader)); + + for (int i = 0; i < 7; i++) { + if (!rpass->textures[i] && rpass->shader.textures[i]) { + rpass->textures[i] = rpass->shader.textures[i]; + } + } + + 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) && + shader_uniform->type == TYPE_VEC4) { + int index = shader_uniform->uname->ptr[9] - '0'; + if (rpass->textures[index]) { + vec4 *texture_res = &rpass->textures[index]->texture_resolution; + memcpy(shader_uniform->value, texture_res, sizeof(vec4)); + } + } + } + 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)); + } + } + + mri_combo *pass_combo, *shader_combo; + mvec_loop_ptr(rpass->combos, pass_combo, i) + mvec_loop_ptr(rpass->shader.combos, shader_combo, s) { + if (mstr_eq(pass_combo->name, shader_combo->name)) { + shader_combo->value = pass_combo->value; + } + } + + mri_shader_compile(&rpass->shader); + + break; + } } } void mri_pass_unload(mri_pass *pass) { - free(pass->material); + for (int i = 0; i < 7; i++) { + if (pass->textures[i]) mri_texture_unload(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); + } } diff --git a/src/objects/pass.h b/src/objects/pass.h index ce34edd..94bad25 100644 --- a/src/objects/pass.h +++ b/src/objects/pass.h @@ -3,22 +3,32 @@ #include <jansson.h> +#include "types.h" + +#include "../context.h" #include "../shader.h" +#include "../engine.h" #include "../texture.h" -typedef struct mri_material mri_material; - -typedef struct { +struct mri_pass { mri_material *material; - mri_shader shader; + mri_shader *shader; mri_texture *textures[7]; - // mvec(mri_uniform) uniforms; - // mvec(mri_combo) combos; -} mri_pass; + mvec(mri_uniform) uniforms; + mvec(mri_combo) combos; +}; + +typedef enum { + EFFECT0_PASS, + EFFECT1_PASS, + MATERIAL_PASS, + MATERIAL_ONLY_PASS +} mri_pass_stage; -void mri_pass_parse(mri_pass *pass, json_t *root); +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); void mri_pass_unload(mri_pass *pass); #endif // _PASS_H diff --git a/src/objects/scene.c b/src/objects/scene.c index 6b8cfce..2448659 100644 --- a/src/objects/scene.c +++ b/src/objects/scene.c @@ -8,16 +8,15 @@ #include "../log.h" void mri_scene_parse(mri_scene *scene) { - mri_asset *scene_json = mri_asset_manager_get("scene.json", NONE); + mri_asset *scene_asset = mri_asset_manager_get(mstr_c("scene.json"), NONE); - json_error_t error; - json_t *root = json_loadb((char *)scene_json->data, scene_json->size, 0, &error); - - if (!root) { - log_error("error parsing json on line %d: %s", error.line, error.text); + 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"); @@ -40,17 +39,28 @@ void mri_scene_parse(mri_scene *scene) { json_t *object; json_t *objects = json_object_get(root, "objects"); json_array(object, objects) { - mri_object _object; - mri_object_parse(&_object, object); - mvec_push(scene->objects, _object); + bool visible; + json_get_bool(&visible, object, "visible"); + if (visible) + mri_object_parse(mvec_next(scene->objects), object); } json_decref(root); } +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) { + mri_object_load(engine, object); + } +} + void mri_scene_unload(mri_scene *scene) { mri_object *object; - mvec_loop_ptr(scene->objects, object) { + mvec_loop_ptr(scene->objects, object, i) { mri_object_unload(object); } mvec_free(scene->objects); diff --git a/src/objects/scene.h b/src/objects/scene.h index 5c7e90b..ff0464b 100644 --- a/src/objects/scene.h +++ b/src/objects/scene.h @@ -4,11 +4,12 @@ #include <cglm/cglm.h> #include <moro_vec.h> +#include "types.h" #include "object.h" #include "../assets.h" -typedef struct { +struct mri_scene { float width; float height; @@ -34,9 +35,10 @@ typedef struct { float bloom_threshold; mvec(mri_object) objects; -} mri_scene; +}; void mri_scene_parse(mri_scene *scene); +void mri_scene_load(mri_engine *engine, mri_scene *scene); void mri_scene_unload(mri_scene *scene); #endif // _SCENE_H diff --git a/src/objects/types.h b/src/objects/types.h new file mode 100644 index 0000000..9701cb0 --- /dev/null +++ b/src/objects/types.h @@ -0,0 +1,11 @@ +#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; + +#endif // _TYPES_H |