From af15a948f7aa8ebe99ca76c56841b9b8681979f5 Mon Sep 17 00:00:00 2001 From: Andrew Opalach Date: Thu, 10 Sep 2020 20:44:57 -0400 Subject: refactor all the rendering code --- src/objects/effect.c | 47 +++++++++++++++++--- src/objects/effect.h | 4 ++ src/objects/material.c | 45 ++++++++++++++----- src/objects/material.h | 6 ++- src/objects/model.c | 9 +++- src/objects/model.h | 3 +- src/objects/object.c | 112 +++++++++++++++++++++++++++++++++++++---------- src/objects/object.h | 16 +++++-- src/objects/pass.c | 115 ++++++++++++++++++++++++++++++++++++++----------- src/objects/pass.h | 48 +++++++++++++++++---- src/objects/scene.c | 22 +++++++++- src/objects/scene.h | 4 +- src/objects/types.h | 4 ++ 13 files changed, 352 insertions(+), 83 deletions(-) (limited to 'src/objects') diff --git a/src/objects/effect.c b/src/objects/effect.c index 7458f62..f90fad8 100644 --- a/src/objects/effect.c +++ b/src/objects/effect.c @@ -1,5 +1,13 @@ #include "effect.h" + +#include "../engine.h" #include "../json.h" +#include "../log.h" + +#include "cglm/mat4.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->passes0); @@ -20,6 +28,8 @@ void mri_effect_parse(mri_effect *effect, json_t *root) { 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) { @@ -28,16 +38,43 @@ void mri_effect_parse(mri_effect *effect, json_t *root) { } } +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) { - mri_engine_next_effect(engine); - for (int i = 0; i < mvec_size(effect->passes0); i++) { - mri_engine_next_pass(engine); - mri_pass_load(engine, mvec_at(effect->passes0, i), EFFECT0_PASS); - mri_pass_load(engine, mvec_at(effect->passes1, i), EFFECT1_PASS); + for (unsigned int i = 0; i < mvec_size(effect->passes0); i++) { + mri_render_pass *pass = mri_effect_next_pass(effect); + + if (i == mvec_size(effect->passes0) - 1) { + pass->combine = true; + } + + pass->object = engine->current_object; + 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) { diff --git a/src/objects/effect.h b/src/objects/effect.h index 76af254..9570fde 100644 --- a/src/objects/effect.h +++ b/src/objects/effect.h @@ -7,12 +7,16 @@ #include "pass.h" struct mri_effect { + mstr *name; + mvec(mri_pass) passes0; mvec(mri_pass) passes1; + mvec(mri_render_pass) passes; }; void mri_effect_parse(mri_effect *effect, json_t *root); void mri_effect_load(mri_engine *engine, mri_effect *effect); +void mri_effect_draw(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 d934970..2076274 100644 --- a/src/objects/material.c +++ b/src/objects/material.c @@ -1,10 +1,13 @@ #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); @@ -20,32 +23,54 @@ void mri_material_parse(mri_material *material, json_t *value) { json_t *pass; json_t *passes = json_object_get(root, "passes"); json_array(pass, passes) { - mri_pass_parse(mvec_next(material->passes), pass, MATERIAL_PASS); + mri_pass_parse(mvec_next(material->passes0), pass, MATERIAL_PASS); } json_decref(root); } } -void mri_material_load(mri_engine *engine, mri_material *material, mri_material_type t) { - mri_pass *pass; - mvec_loop_ptr(material->passes, pass, i) { +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) { + mri_pass *pass0; + mvec_loop_ptr(material->passes0, pass0, i) { switch (t) { case MATERIAL_EFFECT: - mri_pass_load(engine, pass, MATERIAL_PASS); + mri_pass_load(engine, pass0, MATERIAL_PASS, pass); break; case MATERIAL_MODEL: - mri_engine_next_pass(engine); - mri_pass_load(engine, pass, MATERIAL_ONLY_PASS); + pass = mri_material_next_pass(material); + + pass->object = engine->current_object; + pass->gl_object = &engine->current_object->gl_uv_object; + + glm_mat4_copy(engine->current_object->ortho, pass->model); + + mri_pass_load(engine, pass0, MATERIAL_ONLY_PASS, pass); break; } } } -void mri_material_unload(mri_material *material) { - mri_pass *pass; +void mri_material_draw(mri_engine *engine, mri_material *material) { + mri_render_pass *pass; mvec_loop_ptr(material->passes, pass, i) { - mri_pass_unload(pass); + 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.h b/src/objects/material.h index 805a198..5c8f7b5 100644 --- a/src/objects/material.h +++ b/src/objects/material.h @@ -12,11 +12,13 @@ typedef enum { } mri_material_type; struct mri_material { - mvec(mri_pass) passes; + mvec(mri_pass) passes0; + mvec(mri_render_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_load(mri_engine *engine, mri_material *material, mri_material_type t, mri_render_pass *pass); +void mri_material_draw(mri_engine *engine, mri_material *material); void mri_material_unload(mri_material *material); #endif // MATERIAL_H diff --git a/src/objects/model.c b/src/objects/model.c index 3fe8e1d..81cd0b0 100644 --- a/src/objects/model.c +++ b/src/objects/model.c @@ -4,8 +4,10 @@ #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)) { @@ -29,8 +31,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); + mri_material_load(engine, &model->material, MATERIAL_MODEL, NULL); +} + +void mri_model_draw(mri_engine *engine, mri_model *model) { + mri_material_draw(engine, &model->material); } void mri_model_unload(mri_model *model) { diff --git a/src/objects/model.h b/src/objects/model.h index 38f4405..4d17c72 100644 --- a/src/objects/model.h +++ b/src/objects/model.h @@ -7,8 +7,6 @@ #include "pass.h" #include "material.h" -#include "../engine.h" - struct mri_model { bool autosize; bool fullscreen; @@ -18,6 +16,7 @@ struct 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_draw(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 ee96a9e..b3b57c2 100644 --- a/src/objects/object.c +++ b/src/objects/object.c @@ -1,17 +1,25 @@ #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; @@ -39,25 +47,7 @@ void mri_object_parse(mri_object *object, json_t *root) { json_get_bool(&object->passthrough, config, "passthrough"); } - char *abuffer, *bbuffer; - - asprintf(&abuffer, "_rt_imageLayerComposite_%i_a", object->id); - asprintf(&bbuffer, "_rt_imageLayerComposite_%i_b", object->id); - - object->abuffer = mstr_from(abuffer); - object->bbuffer = mstr_from(bbuffer); - - free(abuffer); - free(bbuffer); - - json_t *image = json_object_get(root, "image"); - - if (json_is_string(image)) { - mri_model_parse(&object->image, image); - object->has_image = true; - } else { - object->has_image = false; - } + mri_model_parse(&object->image, json_object_get(root, "image")); mvec_init(object->effects); @@ -92,7 +82,41 @@ void mri_object_get_model(mri_object *object, mat4 model, float width, float hei } void mri_object_load(mri_engine *engine, mri_object *object) { - mri_engine_next_object(engine, object); + engine->current_object = object; + + float width = object->size[0]; + float height = object->size[1]; + + // mstr_sprintf + char *abuffer, *bbuffer; + + asprintf(&abuffer, "_rt_imageLayerComposite_%i_a", object->id); + asprintf(&bbuffer, "_rt_imageLayerComposite_%i_b", object->id); + + object->abuffer = mri_engine_get_or_new_framebuffer(engine, + mstr_c(abuffer), width, height, 1.f, + engine->scene->clear_color); + + object->bbuffer = mri_engine_get_or_new_framebuffer(engine, + mstr_c(bbuffer), width, height, 1.f, + engine->scene->clear_color); + + free(abuffer); + 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); @@ -114,7 +138,51 @@ void mri_object_load(mri_engine *engine, mri_object *object) { } } +static void 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); +} + +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); + } + + mri_framebuffer_bind(engine->combine_buffer, false); + + if (object->buffer_switch) { + mri_texture_bind(&object->bbuffer->texture, 0); + } else { + mri_texture_bind(&object->abuffer->texture, 0); + } + + mri_shader_bind(engine, &engine->mininal_shader, object->model); + + bind_gl_object(&object->gl_object); + + center_scale(engine->width, engine->height, engine->context->width, engine->context->height); + + glDrawArrays(GL_TRIANGLES, 0, 6); + + log_debug("combine (%.*s)", object->name->len, object->name->ptr); +} + 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); @@ -123,8 +191,8 @@ void mri_object_unload(mri_object *object) { mvec_free(object->effects); mvec_free(object->deps); - mstr_free(object->abuffer); - mstr_free(object->bbuffer); + mri_framebuffer_unload(object->abuffer); + mri_framebuffer_unload(object->bbuffer); mri_model_unload(&object->image); } diff --git a/src/objects/object.h b/src/objects/object.h index 7c6969b..c7bb883 100644 --- a/src/objects/object.h +++ b/src/objects/object.h @@ -6,6 +6,7 @@ #include #include +#include "src/texture.h" #include "types.h" #include "model.h" #include "pass.h" @@ -19,6 +20,7 @@ typedef enum { struct mri_object { int id; + mstr *name; mvec(int) deps; @@ -34,7 +36,6 @@ struct mri_object { bool copy_background; mri_model image; - bool has_image; vec2 size; vec3 origin; @@ -45,8 +46,16 @@ struct mri_object { bool passthrough; bool fullscreen; - mstr *abuffer; - mstr *bbuffer; + gl_object gl_uv_object; + gl_object gl_object; + + mat4 ortho; + mat4 model; + + mri_framebuffer *abuffer; + mri_framebuffer *bbuffer; + + bool buffer_switch; mvec(mri_effect) effects; }; @@ -55,6 +64,7 @@ void mri_object_get_model(mri_object *object, mat4 model, float width, float hei 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); #endif // _OBJECT_H diff --git a/src/objects/pass.c b/src/objects/pass.c index fadac16..f0cac99 100644 --- a/src/objects/pass.c +++ b/src/objects/pass.c @@ -1,3 +1,5 @@ +#include + #include "pass.h" #include "material.h" #include "model.h" @@ -5,8 +7,11 @@ #include "../json.h" #include "../texture.h" +#include "../engine.h" #include "../assets.h" #include "../gl.h" +#include "src/objects/types.h" +#include "src/shader.h" void mri_pass_parse(mri_pass *pass, json_t *root, mri_pass_stage stage) { memset(pass, 0, sizeof(mri_pass)); @@ -42,21 +47,18 @@ void mri_pass_parse(mri_pass *pass, json_t *root, mri_pass_stage stage) { } 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"))); @@ -67,24 +69,22 @@ void mri_pass_parse(mri_pass *pass, json_t *root, mri_pass_stage stage) { 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)) { - 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); + mri_asset *texture_asset = mri_asset_manager_get( + mstr_c(json_string_value(texture)), TEXTURE); + if (texture_asset->type != ASSET_VOID) { + pass->textures[i] = mri_texture_load(texture_asset); } } } @@ -113,9 +113,8 @@ 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_object *robject = engine->current_object; - mri_render_pass *rpass = engine->current_pass; +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 = 1; i < 7; i++) { if (pass->textures[i]) rpass->textures[i] = pass->textures[i]; @@ -135,44 +134,74 @@ void mri_pass_load(mri_engine *engine, mri_pass *pass, mri_pass_stage stage) { break; } case EFFECT1_PASS: + // If there is an explicit target framebuffer, set it. if (pass->target) { rpass->target = mri_engine_get_or_new_framebuffer(engine, pass->target, engine->width, engine->height, 2.f, - (vec4){0.f, 0.f, 0.f, 1.0f}); + (vec4){0.f, 0.f, 0.f, 0.2f}); } else { - if (!robject->buffer_switch) { - rpass->target = robject->bbuffer; - rpass->textures[0] = &robject->abuffer->texture; + // If no target was specified pick the next buffer in the + // alternating AB buffers. + if (object->buffer_switch) { + rpass->target = object->abuffer; + rpass->textures[0] = &object->bbuffer->texture; } else { - rpass->target = robject->abuffer; - rpass->textures[0] = &robject->bbuffer->texture; + rpass->target = object->bbuffer; + rpass->textures[0] = &object->abuffer->texture; } - robject->buffer_switch = !robject->buffer_switch; } 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"))) { - if (!robject->buffer_switch) { - rpass->textures[i] = &robject->bbuffer->texture; + if (object->buffer_switch) { + rpass->textures[i] = &object->bbuffer->texture; } else { - rpass->textures[i] = &robject->abuffer->texture; + rpass->textures[i] = &object->abuffer->texture; } } else { rpass->textures[i] = &mri_engine_get_framebuffer(engine, pass->binds[i])->texture; } } - mri_material_load(engine, pass->material, MATERIAL_EFFECT); + // If we selected one of the AB buffers, switch the flag after + // setting binds to keep the ordering correct. + if (!pass->target) + object->buffer_switch = !object->buffer_switch; + mri_material_load(engine, pass->material, MATERIAL_EFFECT, rpass); break; case MATERIAL_ONLY_PASS: - rpass->target = robject->abuffer; + // This object has no effects so Texture0 is an image and draw on the A buffer. + rpass->target = object->abuffer; rpass->textures[0] = pass->textures[0]; case MATERIAL_PASS: { memcpy(&rpass->shader, pass->shader, sizeof(mri_shader)); + // mvec_clone + mvec_ptr(rpass->shader.uniforms) = (mri_uniform *)malloc( + sizeof(mri_uniform) * mvec_alloc(pass->shader->uniforms)); + memcpy(mvec_ptr(rpass->shader.uniforms), mvec_ptr(pass->shader->uniforms), + sizeof(mri_uniform) * mvec_alloc(pass->shader->uniforms)); + + mvec_ptr(rpass->shader.combos) = (mri_combo *)malloc( + sizeof(mri_combo) * mvec_alloc(pass->shader->combos)); + memcpy(mvec_ptr(rpass->shader.combos), mvec_ptr(pass->shader->combos), + sizeof(mri_combo) * mvec_alloc(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]) { rpass->textures[i] = rpass->shader.textures[i]; } + // Set TEX0FORMAT incase 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; @@ -183,11 +212,13 @@ void mri_pass_load(mri_engine *engine, mri_pass *pass, mri_pass_stage stage) { mstr_cmp(shader_uniform->uname, mstr_c("Resolution"), 10, 10) == 0) { 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)); + 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; @@ -196,6 +227,7 @@ void mri_pass_load(mri_engine *engine, mri_pass *pass, mri_pass_stage stage) { } } + // Handle combo value overrides. mri_combo *pass_combo, *shader_combo; mvec_loop_ptr(rpass->combos, pass_combo, i) mvec_loop_ptr(rpass->shader.combos, shader_combo, s) { @@ -204,6 +236,7 @@ void mri_pass_load(mri_engine *engine, mri_pass *pass, mri_pass_stage stage) { } } + // compile the shader with the new combo values. mri_shader_compile(&rpass->shader); break; @@ -211,7 +244,37 @@ void mri_pass_load(mri_engine *engine, mri_pass *pass, mri_pass_stage stage) { } } +void mri_render_pass_draw(mri_engine *engine, mri_render_pass *pass) { + mri_framebuffer_bind(pass->target, pass->combine); + 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); + } + + glViewport(0, 0, pass->target->width, pass->target->height); + glDrawArrays(GL_TRIANGLES, 0, 6); + + if (0) { + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + glBindFramebuffer(GL_READ_FRAMEBUFFER, pass->target->buffer.id); + + // Drawing past the dimensions of the read buffer is an error. + 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(1000000); + } +} + void mri_pass_unload(mri_pass *pass) { + // TODO render pass unloading + for (int i = 0; i < 7; i++) { if (pass->textures[i]) mri_texture_unload(pass->textures[i]); } diff --git a/src/objects/pass.h b/src/objects/pass.h index 116f91d..37c0997 100644 --- a/src/objects/pass.h +++ b/src/objects/pass.h @@ -3,14 +3,32 @@ #include +#include "src/gl.h" #include "types.h" #include "../context.h" #include "../shader.h" -#include "../engine.h" #include "../texture.h" +typedef enum { + EFFECT0_PASS, + EFFECT1_PASS, + MATERIAL_PASS, + MATERIAL_ONLY_PASS +} mri_pass_stage; + +typedef enum { + BACKGROUND, + BACKGROUND_ONLY, + TRANSFORM, + COMBINE, + PASS, +} mri_render_pass_stage; + + struct mri_pass { + int id; + mri_material *material; mri_shader *shader; @@ -23,15 +41,29 @@ struct mri_pass { mvec(mri_combo) combos; }; -typedef enum { - EFFECT0_PASS, - EFFECT1_PASS, - MATERIAL_PASS, - MATERIAL_ONLY_PASS -} mri_pass_stage; +struct mri_render_pass { + mri_shader shader; + + mri_object *object; + + mat4 model; + gl_object *gl_object; + + mri_texture *textures[7]; + mri_framebuffer *target; + + bool combine; + + mri_render_pass_stage stage; + + mvec(mri_uniform) uniforms; + mvec(mri_combo) combos; +}; 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_load(mri_engine *engine, mri_pass *pass, mri_pass_stage stage, mri_render_pass *rpass); void mri_pass_unload(mri_pass *pass); +void mri_render_pass_draw(mri_engine *engine, mri_render_pass *pass); + #endif // _PASS_H diff --git a/src/objects/scene.c b/src/objects/scene.c index f887f13..db6656f 100644 --- a/src/objects/scene.c +++ b/src/objects/scene.c @@ -6,6 +6,8 @@ #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); @@ -28,7 +30,7 @@ void mri_scene_parse(mri_scene *scene) { json_get_bool(&scene->clear_enabled, general, "clearenabled"); json_get_vec3((vec3 *)&scene->clear_color, general, "clearcolor"); - scene->clear_color[3] = 1.f; + scene->clear_color[3] = 0.f; json_get_vec3(&scene->ambient_color, general, "ambientcolor"); json_get_vec3(&scene->skylight_color, general, "skylightcolor"); @@ -43,7 +45,7 @@ void mri_scene_parse(mri_scene *scene) { json_array(object, objects) { bool visible; json_get_bool(&visible, object, "visible"); - if (visible) + if (visible && !(json_is_null(json_object_get(object, "image")))) mri_object_parse(mvec_next(scene->objects), object); } @@ -80,6 +82,22 @@ void mri_scene_load(mri_engine *engine, mri_scene *scene) { } } +void mri_scene_draw(mri_engine *engine, mri_scene *scene) { + 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_draw(engine, dep_object); + } + } + } + mri_object_draw(engine, object); + } +} + void mri_scene_unload(mri_scene *scene) { mri_object *object; mvec_loop_ptr(scene->objects, object, i) { diff --git a/src/objects/scene.h b/src/objects/scene.h index dee6d50..9514580 100644 --- a/src/objects/scene.h +++ b/src/objects/scene.h @@ -38,8 +38,10 @@ struct mri_scene { }; void mri_scene_parse(mri_scene *scene); -int mri_scene_framebuffer_count(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); +int mri_scene_framebuffer_count(mri_scene *scene); + #endif // _SCENE_H diff --git a/src/objects/types.h b/src/objects/types.h index 9701cb0..76fd8eb 100644 --- a/src/objects/types.h +++ b/src/objects/types.h @@ -8,4 +8,8 @@ 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