From f114f3ad193313676be1de0d9388b9062a8559ab Mon Sep 17 00:00:00 2001 From: Andrew Opalach Date: Mon, 14 Sep 2020 19:26:57 -0400 Subject: texture cache, load objects in order of dependencies --- src/engine.c | 3 +++ src/engine.h | 2 ++ src/gl.h | 18 +++++++++--------- src/objects/effect.c | 2 ++ src/objects/effect.h | 2 ++ src/objects/object.c | 4 ++++ src/objects/object.h | 2 ++ src/objects/pass.c | 37 ++++++++++++++++++++++++++++--------- src/objects/pass.h | 3 ++- src/objects/scene.c | 18 +++++++++--------- src/shader.c | 6 ++---- src/shader.h | 4 ++-- src/texture.c | 14 +++++++++++--- src/texture.h | 6 +++++- 14 files changed, 83 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/engine.c b/src/engine.c index 155dd85..f8cb450 100644 --- a/src/engine.c +++ b/src/engine.c @@ -1,5 +1,6 @@ #include "engine.h" +#include "moro_vec.h" #include "objects/object.h" #include "objects/scene.h" #include "src/context.h" @@ -13,8 +14,10 @@ void mri_engine_load(mri_engine *engine, mri_scene *scene) { engine->scene = scene; + mvec_init(engine->texture_cache); mvec_init(engine->framebuffers); + mvec_reserve(engine->texture_cache, 100); mvec_reserve(engine->framebuffers, mri_scene_framebuffer_count(scene) + 1); engine->width = scene->width; diff --git a/src/engine.h b/src/engine.h index 95fccae..1b5026a 100644 --- a/src/engine.h +++ b/src/engine.h @@ -29,6 +29,8 @@ struct mri_engine { mvec(mri_framebuffer) framebuffers; + mvec(mri_texture) texture_cache; + mri_object *current_object; }; diff --git a/src/gl.h b/src/gl.h index f85b716..9d56378 100644 --- a/src/gl.h +++ b/src/gl.h @@ -10,6 +10,15 @@ typedef enum { OBJECT } gl_obj_type; +typedef enum { + TYPE_FLOAT, + TYPE_VEC4, + TYPE_VEC3, + TYPE_VEC2, + TYPE_MAT4, + TYPE_SAMPLER2D +} uniform_type; + typedef struct { unsigned int vao; unsigned int vbo; @@ -28,15 +37,6 @@ typedef struct { gl_texture texture; } gl_framebuffer; -typedef enum { - TYPE_FLOAT, - TYPE_VEC4, - TYPE_VEC3, - TYPE_VEC2, - TYPE_MAT4, - TYPE_SAMPLER2D -} uniform_type; - void bind_gl_texture(gl_texture *tex, unsigned int index); void create_gl_texture(gl_texture *tex, bool interp, bool clamp_uv, int mm_count); void upload_gl_texture(gl_texture *tex, unsigned char *data, int width, int height, int level, diff --git a/src/objects/effect.c b/src/objects/effect.c index cb37281..d5fb747 100644 --- a/src/objects/effect.c +++ b/src/objects/effect.c @@ -18,6 +18,8 @@ void mri_effect_parse(mri_effect *effect, json_t *root) { 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) { diff --git a/src/objects/effect.h b/src/objects/effect.h index 374a39f..4d31081 100644 --- a/src/objects/effect.h +++ b/src/objects/effect.h @@ -15,6 +15,8 @@ struct mri_effect { mstr *name; int id; + bool visible; + mvec(mri_pass) passes0; mvec(mri_pass) passes1; mvec(mri_render_pass) passes; diff --git a/src/objects/object.c b/src/objects/object.c index 6a67bea..431852e 100644 --- a/src/objects/object.c +++ b/src/objects/object.c @@ -79,6 +79,8 @@ void mri_object_get_model(mri_object *object, mat4 model, float width, float hei } void mri_object_load(mri_engine *engine, mri_object *object) { + if (object->loaded) return; + engine->current_object = object; float width = object->size[0]; @@ -128,6 +130,8 @@ void mri_object_load(mri_engine *engine, mri_object *object) { 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) { diff --git a/src/objects/object.h b/src/objects/object.h index 6431237..fbaae60 100644 --- a/src/objects/object.h +++ b/src/objects/object.h @@ -57,6 +57,8 @@ struct mri_object { bool buffer_switch; + bool loaded; + mvec(mri_effect) effects; }; diff --git a/src/objects/pass.c b/src/objects/pass.c index 4820065..df3b70d 100644 --- a/src/objects/pass.c +++ b/src/objects/pass.c @@ -36,6 +36,10 @@ void mri_pass_parse(mri_pass *pass, json_t *root, mri_pass_stage stage) { .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)) { @@ -95,11 +99,7 @@ void mri_pass_parse(mri_pass *pass, json_t *root, mri_pass_stage stage) { json_t *textures = json_object_get(root, "textures"); json_array(texture, textures) { if (json_is_string(texture)) { - 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); - } + pass->textures[i] = mstr_from(json_string_value(texture)); } } @@ -131,7 +131,19 @@ void mri_pass_load(mri_engine *engine, mri_pass *pass, mri_pass_stage stage, mri mri_object *object = engine->current_object; for (int i = 0; i < 7; i++) { - if (pass->textures[i]) rpass->textures[i] = pass->textures[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; @@ -160,6 +172,7 @@ void mri_pass_load(mri_engine *engine, mri_pass *pass, mri_pass_stage stage, mri 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); @@ -173,6 +186,7 @@ void mri_pass_load(mri_engine *engine, mri_pass *pass, mri_pass_stage stage, mri 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); @@ -207,7 +221,11 @@ void mri_pass_load(mri_engine *engine, mri_pass *pass, mri_pass_stage stage, mri // 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]; + 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, @@ -330,7 +348,8 @@ void mri_render_pass_draw(mri_engine *engine, mri_render_pass *pass) { viewport_default(pass->target->width, pass->target->height); } - glDrawArrays(GL_TRIANGLES, 0, 6); + if (pass->object->visible) + glDrawArrays(GL_TRIANGLES, 0, 6); for (int i = 0; i < pass->shader.texture_count; i++) { glActiveTexture(GL_TEXTURE0 + i); @@ -355,7 +374,7 @@ 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]); + if (pass->textures[i]) mstr_free(pass->textures[i]); } mri_uniform *uniform; diff --git a/src/objects/pass.h b/src/objects/pass.h index 64947c9..59dcdba 100644 --- a/src/objects/pass.h +++ b/src/objects/pass.h @@ -36,7 +36,8 @@ struct mri_pass { mri_material *material; mri_shader *shader; - mri_texture *textures[7]; + + mstr *textures[7]; mstr *target; mstr *binds[7]; diff --git a/src/objects/scene.c b/src/objects/scene.c index 62c70b2..3bcd6ac 100644 --- a/src/objects/scene.c +++ b/src/objects/scene.c @@ -75,6 +75,15 @@ void mri_scene_load(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_load(engine, dep_object); + } + } + } mri_object_load(engine, object); } } @@ -82,15 +91,6 @@ 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); } } diff --git a/src/shader.c b/src/shader.c index b054cbb..a89eebc 100644 --- a/src/shader.c +++ b/src/shader.c @@ -105,9 +105,7 @@ static mstr *build_shader_source(mri_shader *shader, mstr *isource, bool root) { json_t *texture = json_object_get(root, "default"); if (json_is_string(texture)) { - mstr *path = mstr_c(json_string_value(texture)); - shader->textures[index] = mri_texture_load( - mri_asset_manager_get(path, TEXTURE)); + shader->textures[index] = mstr_from(json_string_value(texture)); } // NOTE: I assume the only case where this is wrong would @@ -276,7 +274,7 @@ void mri_shader_bind(mri_engine *engine, mri_shader *shader, mat4 mvp) { void mri_shader_unload(mri_shader *shader) { for (int i = 0; i < 7; i++) { - if (shader->textures[i]) mri_texture_unload(shader->textures[i]); + if (shader->textures[i]) mstr_free(shader->textures[i]); } if (shader->vs_source) diff --git a/src/shader.h b/src/shader.h index 8a62b98..30c9e6c 100644 --- a/src/shader.h +++ b/src/shader.h @@ -25,12 +25,12 @@ typedef struct { typedef struct { mstr *vs_source; mstr *fs_source; - + gl_shader gl_shader; int texture_count; - mri_texture *textures[7]; + mstr *textures[7]; mvec(mri_combo) combos; mvec(mri_uniform) uniforms; diff --git a/src/texture.c b/src/texture.c index 29f6cab..42f0830 100644 --- a/src/texture.c +++ b/src/texture.c @@ -12,6 +12,7 @@ #include "assets.h" #include "gl.h" #include "log.h" +#include "engine.h" static unsigned char *load_image_rgba(unsigned char *data, int len) { int w, h, channels; @@ -31,10 +32,17 @@ static unsigned char *load_image_rgba(unsigned char *data, int len) { // ((x & 0x000000FF) << 24); //} -mri_texture *mri_texture_load(mri_asset *asset) { - // check if texture was previously loaded +mri_texture *mri_texture_load(mri_engine *engine, mri_asset *asset) { + mri_texture *previous_texture; + mvec_loop_ptr(engine->texture_cache, previous_texture, i) { + if (previous_texture->hash == asset->hash) { + return previous_texture; + } + } + + mri_texture *t = mvec_next(engine->texture_cache); - mri_texture *t = (mri_texture *)malloc(sizeof(mri_texture)); + t->hash = asset->hash; //mstr type = mri_asset_str(asset, 9); //mstr itype = mri_asset_str(asset, 9); diff --git a/src/texture.h b/src/texture.h index 0ed692f..316d7fd 100644 --- a/src/texture.h +++ b/src/texture.h @@ -7,6 +7,8 @@ #include "gl.h" #include "assets.h" +#include "objects/types.h" + typedef enum { RGBA8888 = 0, DXT5 = 4, @@ -33,6 +35,8 @@ typedef struct { int width, height; int texture_width, texture_height; + unsigned long hash; + gl_texture texture; vec4 texture_resolution; @@ -56,7 +60,7 @@ typedef struct { mri_texture texture; } mri_framebuffer; -mri_texture *mri_texture_load(mri_asset *_asset); +mri_texture *mri_texture_load(mri_engine *engine, mri_asset *asset); void mri_texture_unload(mri_texture *texture); void mri_texture_bind(mri_texture *t, int index); -- cgit v1.2.3-101-g0448