diff options
| -rwxr-xr-x | scripts/line_count.sh | 2 | ||||
| -rw-r--r-- | src/engine.c | 75 | ||||
| -rw-r--r-- | src/engine.h | 14 | ||||
| -rw-r--r-- | src/gl.c | 13 | ||||
| -rw-r--r-- | src/gl.h | 4 | ||||
| -rw-r--r-- | src/mauri.c | 2 | ||||
| -rw-r--r-- | src/objects/effect.c | 12 | ||||
| -rw-r--r-- | src/objects/object.c | 25 | ||||
| -rw-r--r-- | src/objects/object.h | 5 | ||||
| -rw-r--r-- | src/objects/pass.c | 45 | ||||
| -rw-r--r-- | src/objects/pass.h | 3 | ||||
| -rw-r--r-- | src/objects/scene.c | 24 | ||||
| -rw-r--r-- | src/objects/scene.h | 3 | ||||
| -rw-r--r-- | src/shader.c | 26 | ||||
| -rw-r--r-- | src/texture.c | 16 | ||||
| -rw-r--r-- | src/texture.h | 9 |
16 files changed, 208 insertions, 70 deletions
diff --git a/scripts/line_count.sh b/scripts/line_count.sh new file mode 100755 index 0000000..dbc74af --- /dev/null +++ b/scripts/line_count.sh @@ -0,0 +1,2 @@ +#!/bin/sh +find ./src -type f | xargs wc -l diff --git a/src/engine.c b/src/engine.c index 58350a2..1b21277 100644 --- a/src/engine.c +++ b/src/engine.c @@ -1,11 +1,13 @@ #include "engine.h" #include "objects/object.h" +#include "objects/scene.h" #include <cglm/cglm.h> typedef enum { BACKGROUND, + BACKGROUND_ONLY, TRANSFORM, COMBINE, PASS @@ -29,6 +31,11 @@ static void center_scale(float w0, float h0, float w1, float h1) { static void draw_pass(mri_engine *engine, render_pass_stage s, mri_render_pass *pass, mri_render_object *object) { switch (s) { + case BACKGROUND_ONLY: + mri_framebuffer_bind(engine->combine_buffer, false); + mri_shader_bind(engine, &pass->shader, object->ortho); + bind_gl_object(&object->gl_uv_object); + break; case BACKGROUND: mri_framebuffer_bind(pass->target, true); if (object->object->passthrough) { @@ -46,8 +53,10 @@ static void draw_pass(mri_engine *engine, render_pass_stage s, mri_render_pass * break; case TRANSFORM: mri_framebuffer_bind(pass->target, true); - mri_shader_bind(engine, &pass->shader, object->model); - bind_gl_object(&object->gl_object); + mri_shader_bind(engine, &pass->shader, NULL); + bind_gl_object(&engine->default_gl_object); + //mri_shader_bind(engine, &pass->shader, object->model); + //bind_gl_object(&object->gl_object); break; case COMBINE: mri_framebuffer_bind(engine->combine_buffer, false); @@ -61,8 +70,7 @@ static void draw_pass(mri_engine *engine, render_pass_stage s, mri_render_pass * } if (s == COMBINE || (s == BACKGROUND && object->object->passthrough)) { - center_scale(engine->width, engine->height, - engine->context->width, engine->context->height); + center_scale(engine->width, engine->height, engine->context->width, engine->context->height); } else { glViewport(0, 0, pass->target->width, pass->target->height); } @@ -70,8 +78,16 @@ static void draw_pass(mri_engine *engine, render_pass_stage s, mri_render_pass * glDrawArrays(GL_TRIANGLES, 0, 6); } -void mri_engine_load(mri_engine *engine) { + +void mri_engine_load(mri_engine *engine, mri_scene *scene) { mvec_init(engine->objects); + mvec_init(engine->framebuffers); + + mvec_reserve(engine->objects, mvec_size(scene->objects)); + mvec_reserve(engine->framebuffers, mri_scene_framebuffer_count(scene)); + + engine->width = scene->width; + engine->height = scene->height; engine->texel_size[0] = 1.f / engine->width; engine->texel_size[1] = 1.f / engine->height; @@ -79,8 +95,9 @@ void mri_engine_load(mri_engine *engine) { engine->texel_half_size[0] = .5f / engine->width; engine->texel_half_size[1] = .5f / engine->height; - engine->combine_buffer = mri_framebuffer_load( - mstr_c("combine"), engine->context->width, engine->context->height, 1.f); + engine->combine_buffer = mri_engine_get_or_new_framebuffer(engine, + mstr_c("_rt_FullFrameBuffer"), engine->context->width, engine->context->height, 1.f, + scene->clear_color); create_gl_object(&engine->default_gl_object, DEFAULT, 0, 0); } @@ -104,11 +121,13 @@ void mri_engine_next_object(mri_engine *engine, mri_object *object) { glm_ortho(-width, width, -height, height, 0.f, 1.f, engine->current_object->ortho); - engine->current_object->buffer_a = mri_framebuffer_load( - mstr_c("buffer_a"), engine->width, engine->height, 1.f); + engine->current_object->abuffer = mri_engine_get_or_new_framebuffer(engine, + object->abuffer, engine->width, engine->height, 1.f, + (vec4){0.f, 0.f, 0.f, 0.f}); - engine->current_object->buffer_b = mri_framebuffer_load( - mstr_c("buffer_b"), engine->width, engine->height, 1.f); + engine->current_object->bbuffer = mri_engine_get_or_new_framebuffer(engine, + object->bbuffer, engine->width, engine->height, 1.f, + (vec4){0.f, 0.f, 0.f, 0.f}); engine->current_object->buffer_switch = false; } @@ -129,16 +148,42 @@ void mri_engine_update(mri_engine *engine) { engine->time = engine->context->current_time(engine->context); } +mri_framebuffer *mri_engine_get_framebuffer(mri_engine *engine, mstr *name) { + mri_framebuffer *existing_buffer; + mvec_loop_ptr(engine->framebuffers, existing_buffer, i) { + if (mstr_eq(existing_buffer->name, name)) { + return existing_buffer; + } + } + return NULL; +} + +mri_framebuffer *mri_engine_get_or_new_framebuffer(mri_engine *engine, + mstr *name, float width, float height, float scale, vec4 clear_color) { + + mri_framebuffer *buffer = mri_engine_get_framebuffer(engine, name); + + if (!buffer) { + buffer = mvec_next(engine->framebuffers); + mri_framebuffer_create(buffer, name, width, height, scale); + mri_framebuffer_load(buffer, clear_color); + } + + return buffer; +} + void mri_engine_draw(mri_engine *engine) { mri_framebuffer_bind(engine->combine_buffer, true); mri_render_object *object; mvec_loop_ptr(engine->objects, object, i) { - mri_render_pass *_pass; - mvec_loop_ptr(object->background.passes, _pass, s) { - draw_pass(engine, BACKGROUND, _pass, object); + mri_render_pass *background_pass; + mvec_loop_ptr(object->background.passes, background_pass, s) { + draw_pass(engine, BACKGROUND, background_pass, object); + if (mvec_size(object->effects) == 0) { + draw_pass(engine, BACKGROUND_ONLY, background_pass, object); + } } - mri_render_effect *effect; mvec_loop_ptr(object->effects, effect, s) { mri_render_pass *pass; diff --git a/src/engine.h b/src/engine.h index 1d0a93a..407988e 100644 --- a/src/engine.h +++ b/src/engine.h @@ -31,8 +31,8 @@ typedef struct { mat4 ortho; mat4 model; - mri_framebuffer *buffer_a; - mri_framebuffer *buffer_b; + mri_framebuffer *abuffer; + mri_framebuffer *bbuffer; bool buffer_switch; @@ -56,6 +56,8 @@ struct mri_engine { mri_framebuffer *combine_buffer; + mvec(mri_framebuffer) framebuffers; + mri_render_pass *current_pass; mri_render_effect *current_effect; mri_render_object *current_object; @@ -63,10 +65,16 @@ struct mri_engine { mvec(mri_render_object) objects; }; -void mri_engine_load(mri_engine *engine); +void mri_engine_load(mri_engine *engine, mri_scene *scene); + +mri_framebuffer *mri_engine_get_framebuffer(mri_engine *engine, mstr *name); +mri_framebuffer *mri_engine_get_or_new_framebuffer(mri_engine *engine, + mstr *name, float width, float height, float scale, vec4 clear_color); + void mri_engine_next_pass(mri_engine *engine); void mri_engine_next_effect(mri_engine *engine); void mri_engine_next_object(mri_engine *engine, mri_object *object); + void mri_engine_run(mri_engine *engine); #endif // _ENGINE_H @@ -54,11 +54,14 @@ void destroy_gl_texture(gl_texture *tex) { void bind_gl_framebuffer(gl_framebuffer *fbo, bool clear) { glBindFramebuffer(GL_FRAMEBUFFER, fbo->id); - if (clear) + if (clear) { + glClearColor(fbo->clear_color[1], fbo->clear_color[1], fbo->clear_color[2], + fbo->clear_color[3]); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } } -void create_gl_framebuffer(gl_framebuffer *fbo, float width, float height) { +void create_gl_framebuffer(gl_framebuffer *fbo, float width, float height, vec4 clear_color) { glGenFramebuffers(1, &fbo->id); glGenTextures(1, &fbo->texture.id); @@ -76,7 +79,11 @@ void create_gl_framebuffer(gl_framebuffer *fbo, float width, float height) { glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo->texture.id, 0); - glClearColor(0.f, 0.f, 0.f, 0.f); + memcpy(fbo->clear_color, clear_color, sizeof(vec4)); + + glClearColor(fbo->clear_color[1], fbo->clear_color[1], fbo->clear_color[2], + fbo->clear_color[3]); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } @@ -2,6 +2,7 @@ #define _GL_H #include <stdbool.h> +#include <cglm/cglm.h> typedef enum { DEFAULT, @@ -25,6 +26,7 @@ typedef struct { typedef struct { unsigned int id; gl_texture texture; + vec4 clear_color; } gl_framebuffer; typedef enum { @@ -42,7 +44,7 @@ void upload_gl_texture(gl_texture *tex, unsigned char *data, int width, int heig void destroy_gl_texture(gl_texture *tex); void bind_gl_framebuffer(gl_framebuffer *fbo, bool clear); -void create_gl_framebuffer(gl_framebuffer *fbo, float width, float height); +void create_gl_framebuffer(gl_framebuffer *fbo, float width, float height, vec4 clear_color); void destroy_gl_framebuffer(gl_framebuffer *fbo); void create_gl_object(gl_object *obj, gl_obj_type type, float width, float height); diff --git a/src/mauri.c b/src/mauri.c index 9680b8b..6e8e2ed 100644 --- a/src/mauri.c +++ b/src/mauri.c @@ -20,7 +20,7 @@ int main(int argc, char* argv[]) { mri_engine engine = {0}; engine.context = context; - mri_engine_load(&engine); + mri_engine_load(&engine, &scene); mri_scene_load(&engine, &scene); diff --git a/src/objects/effect.c b/src/objects/effect.c index 1ab6df3..7458f62 100644 --- a/src/objects/effect.c +++ b/src/objects/effect.c @@ -30,16 +30,10 @@ void mri_effect_parse(mri_effect *effect, json_t *root) { 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) { + for (int i = 0; i < mvec_size(effect->passes0); 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); + mri_pass_load(engine, mvec_at(effect->passes0, i), EFFECT0_PASS); + mri_pass_load(engine, mvec_at(effect->passes1, i), EFFECT1_PASS); } } diff --git a/src/objects/object.c b/src/objects/object.c index 55ed1c9..ee96a9e 100644 --- a/src/objects/object.c +++ b/src/objects/object.c @@ -32,8 +32,6 @@ void mri_object_parse(mri_object *object, json_t *root) { 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"); json_t *config = json_object_get(root, "config"); @@ -41,6 +39,26 @@ 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; + } + mvec_init(object->effects); json_t *effect; @@ -105,6 +123,9 @@ void mri_object_unload(mri_object *object) { mvec_free(object->effects); mvec_free(object->deps); + mstr_free(object->abuffer); + mstr_free(object->bbuffer); + mri_model_unload(&object->image); } diff --git a/src/objects/object.h b/src/objects/object.h index 6965224..7c6969b 100644 --- a/src/objects/object.h +++ b/src/objects/object.h @@ -19,7 +19,6 @@ typedef enum { struct mri_object { int id; - char *name; mvec(int) deps; @@ -35,6 +34,7 @@ struct mri_object { bool copy_background; mri_model image; + bool has_image; vec2 size; vec3 origin; @@ -45,6 +45,9 @@ struct mri_object { bool passthrough; bool fullscreen; + mstr *abuffer; + mstr *bbuffer; + mvec(mri_effect) effects; }; diff --git a/src/objects/pass.c b/src/objects/pass.c index 942ea5e..809fde5 100644 --- a/src/objects/pass.c +++ b/src/objects/pass.c @@ -51,13 +51,15 @@ void mri_pass_parse(mri_pass *pass, json_t *root, mri_pass_stage stage) { json_t *target = json_object_get(root, "target"); if (json_is_string(target)) { - printf("%s\n", json_string_value(target)); + pass->target = mstr_from(json_string_value(target)); } - json_t *binds = json_object_get(root, "binds"); + json_t *bind; + json_t *binds = json_object_get(root, "bind"); - if (json_is_array(binds)) { - printf("%li\n", json_array_size(binds)); + 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; @@ -133,18 +135,36 @@ void mri_pass_load(mri_engine *engine, mri_pass *pass, mri_pass_stage stage) { break; } case EFFECT1_PASS: - if (!robject->buffer_switch) { - rpass->target = robject->buffer_b; - rpass->textures[0] = &robject->buffer_a->texture; + 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}); } else { - rpass->target = robject->buffer_a; - rpass->textures[0] = &robject->buffer_b->texture; + if (!robject->buffer_switch) { + rpass->target = robject->bbuffer; + rpass->textures[0] = &robject->abuffer->texture; + } else { + rpass->target = robject->abuffer; + rpass->textures[0] = &robject->bbuffer->texture; + } + robject->buffer_switch = !robject->buffer_switch; + } + for (int i = 0; i < 7; i++) { + if (!pass->binds[i]) continue; + if (mstr_eq(pass->binds[i], mstr_c("previous"))) { + if (!robject->buffer_switch) { + rpass->textures[i] = &robject->bbuffer->texture; + } else { + rpass->textures[i] = &robject->abuffer->texture; + } + } else { + rpass->textures[i] = &mri_engine_get_framebuffer(engine, pass->binds[i])->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->target = robject->abuffer; rpass->textures[0] = pass->textures[0]; case MATERIAL_PASS: { memcpy(&rpass->shader, pass->shader, sizeof(mri_shader)); @@ -218,4 +238,7 @@ void mri_pass_unload(mri_pass *pass) { mri_material_unload(pass->material); free(pass->material); } + + if (pass->target) + mstr_free(pass->target); } diff --git a/src/objects/pass.h b/src/objects/pass.h index 94bad25..116f91d 100644 --- a/src/objects/pass.h +++ b/src/objects/pass.h @@ -16,6 +16,9 @@ struct mri_pass { mri_shader *shader; mri_texture *textures[7]; + mstr *target; + mstr *binds[7]; + mvec(mri_uniform) uniforms; mvec(mri_combo) combos; }; diff --git a/src/objects/scene.c b/src/objects/scene.c index 2448659..f887f13 100644 --- a/src/objects/scene.c +++ b/src/objects/scene.c @@ -27,7 +27,9 @@ void mri_scene_parse(mri_scene *scene) { json_get_bool(&scene->clear_enabled, general, "clearenabled"); - json_get_vec3(&scene->clear_color, general, "clearcolor"); + 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"); @@ -48,6 +50,26 @@ void mri_scene_parse(mri_scene *scene) { 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; diff --git a/src/objects/scene.h b/src/objects/scene.h index ff0464b..dee6d50 100644 --- a/src/objects/scene.h +++ b/src/objects/scene.h @@ -25,7 +25,7 @@ struct mri_scene { bool clear_enabled; - vec3 clear_color; + vec4 clear_color; vec3 ambient_color; vec3 skylight_color; @@ -38,6 +38,7 @@ 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_unload(mri_scene *scene); diff --git a/src/shader.c b/src/shader.c index 7d7783a..b8d2ed9 100644 --- a/src/shader.c +++ b/src/shader.c @@ -215,6 +215,7 @@ void mri_shader_bind(mri_engine *engine, mri_shader *shader, mat4 mvp) { mri_uniform *uniform; mvec_loop_ptr(shader->uniforms, uniform, i) { mri_uniform_set(shader, uniform); + //printf("%.*s %f\n", uniform->uname->len, uniform->uname->ptr, uniform->value[0]); } set_gl_uniform_named("g_Time", &shader->gl_shader, TYPE_FLOAT, &engine->time); @@ -223,19 +224,20 @@ void mri_shader_bind(mri_engine *engine, mri_shader *shader, mat4 mvp) { set_gl_uniform_named("g_TexelSizeHalf", &shader->gl_shader, TYPE_VEC2, &engine->texel_half_size[0]); - if (!mvp) { - mat4 _mvp; + mat4 _mvp, _inverse; + + if (!mvp) glm_mat4_identity(_mvp); - set_gl_uniform_named("g_ModelViewProjectionMatrix", &shader->gl_shader, - TYPE_MAT4, (float *)_mvp); - } else { - set_gl_uniform_named("g_ModelViewProjectionMatrix", &shader->gl_shader, - TYPE_MAT4, (float *)mvp); - mat4 _inverse; - glm_mat4_inv(mvp, _inverse); - set_gl_uniform_named("g_ModelViewProjectionMatrixInverse", &shader->gl_shader, - TYPE_MAT4, (float *)_inverse); - } + else + glm_mat4_copy(mvp, _mvp); + + glm_mat4_inv(_mvp, _inverse); + + set_gl_uniform_named("g_ModelViewProjectionMatrix", + &shader->gl_shader, TYPE_MAT4, (float *)_mvp); + + set_gl_uniform_named("g_ModelViewProjectionMatrixInverse", + &shader->gl_shader, TYPE_MAT4, (float *)_inverse); } void mri_shader_unload(mri_shader *shader) { diff --git a/src/texture.c b/src/texture.c index 76dfb5d..50b9591 100644 --- a/src/texture.c +++ b/src/texture.c @@ -130,30 +130,28 @@ void mri_texture_bind(mri_texture *t, int index) { bind_gl_texture(&t->texture, index); } -mri_framebuffer *mri_framebuffer_load(mstr *name, float width, float height, float scale) { - mri_framebuffer *buffer = (mri_framebuffer *)malloc(sizeof(mri_framebuffer)); +void mri_framebuffer_create(mri_framebuffer *buffer, mstr *name, float width, float height, float scale) { buffer->name = mstr_clone(name); - create_gl_framebuffer(&buffer->buffer, width / scale, height / scale); - - buffer->width = width; - buffer->height = height; + buffer->width = width / scale; + buffer->height = height / scale; buffer->texture.texture_resolution[0] = width; buffer->texture.texture_resolution[1] = height; buffer->texture.texture_resolution[2] = width; buffer->texture.texture_resolution[3] = height; +} +void mri_framebuffer_load(mri_framebuffer *buffer, vec4 clear_color) { + create_gl_framebuffer(&buffer->buffer, buffer->width, buffer->height, clear_color); buffer->texture.texture.id = buffer->buffer.texture.id; - - return buffer; } void mri_framebuffer_unload(mri_framebuffer *buffer) { mstr_free(buffer->name); destroy_gl_framebuffer(&buffer->buffer); - free(buffer); + //free(buffer); } void mri_framebuffer_bind(mri_framebuffer *buffer, bool clear) { diff --git a/src/texture.h b/src/texture.h index 706beb1..4156072 100644 --- a/src/texture.h +++ b/src/texture.h @@ -50,8 +50,14 @@ typedef struct { typedef struct { mstr *name; + float width, height; + float scale; + + bool loaded; + gl_framebuffer buffer; + mri_texture texture; } mri_framebuffer; @@ -59,7 +65,8 @@ mri_texture *mri_texture_load(mri_asset *_asset); void mri_texture_unload(mri_texture *texture); void mri_texture_bind(mri_texture *t, int index); -mri_framebuffer *mri_framebuffer_load(mstr *name, float width, float height, float scale); +void mri_framebuffer_create(mri_framebuffer *buffer, mstr *name, float width, float height, float scale); +void mri_framebuffer_load(mri_framebuffer *buffer, vec4 clear_color); void mri_framebuffer_unload(mri_framebuffer *buffer); void mri_framebuffer_bind(mri_framebuffer *buffer, bool clear); |