summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/assets.c16
-rw-r--r--src/context_glfw.c7
-rw-r--r--src/engine.c19
-rw-r--r--src/engine.h3
-rw-r--r--src/gl.c11
-rw-r--r--src/gl.h5
-rw-r--r--src/mauri.c4
-rw-r--r--src/objects/c1
-rw-r--r--src/objects/effect.c58
-rw-r--r--src/objects/effect.h10
-rw-r--r--src/objects/material.c13
-rw-r--r--src/objects/material.h3
-rw-r--r--src/objects/model.c4
-rw-r--r--src/objects/model.h2
-rw-r--r--src/objects/object.c59
-rw-r--r--src/objects/object.h4
-rw-r--r--src/objects/pass.c162
-rw-r--r--src/objects/pass.h9
-rw-r--r--src/objects/scene.c18
-rw-r--r--src/shader.c69
-rw-r--r--src/texture.c38
-rw-r--r--src/texture.h4
22 files changed, 311 insertions, 208 deletions
diff --git a/src/assets.c b/src/assets.c
index cd68bb8..1e18eb9 100644
--- a/src/assets.c
+++ b/src/assets.c
@@ -3,6 +3,7 @@
#include "log.h"
#include "assets.h"
+#include "moro_str.h"
#include "moro_vec.h"
#include "util.h"
@@ -54,14 +55,14 @@ static void asset_from_path(mstr *path, mri_asset *asset) {
fclose(asset_file);
if (res != asset->size) {
- //log_error("failed to read file (%s)", path);
+ log_error("failed to read file (%.*s)", MSTR_PRINTF(path));
free(asset->data);
return;
}
}
static void mri_asset_manager_init() {
- asset_manager.pkg.type = ASSET_VOID;
+ memset(&asset_manager.pkg, 0, sizeof(mri_asset));
mvec_init(asset_manager.files);
}
@@ -71,7 +72,7 @@ bool mri_asset_manager_load_pkg(mstr *path) {
asset_from_path(path, &asset_manager.pkg);
if (asset_manager.pkg.type == ASSET_VOID) {
- //log_error("failed to load pkg file: (%s)", path);
+ log_error("failed to load pkg file: (%.*s)", MSTR_PRINTF(path));
return false;
}
@@ -79,7 +80,7 @@ bool mri_asset_manager_load_pkg(mstr *path) {
mri_asset_value(&asset_manager.pkg, int));
if (!mstr_eqn(&signature, mstr_c("PKGV"), 4)) {
- //log_error("invalid pkg file: (%.*s)", path.len, path.ptr);
+ log_error("invalid pkg file: (%.*s)", MSTR_PRINTF(path));
return false;
}
@@ -102,12 +103,12 @@ bool mri_asset_manager_load_pkg(mstr *path) {
mri_asset_ptr(&asset_manager.pkg) + file->offset,
mri_asset_ptr(&asset_manager.pkg) + file->offset + file->length);
- //log_debug("loaded file (%.*s)", mstr_expand(&file->path));
+ log_debug("loaded file (%.*s)", MSTR_PRINTF(&file->path));
mvec_push(asset_manager.files, asset);
}
- //log_info("successfully loaded pkg file (%s)", path);
+ log_info("successfully loaded pkg file (%.*s)", MSTR_PRINTF(path));
free(pkg_files);
@@ -155,8 +156,7 @@ mri_asset *mri_asset_manager_get(mstr *part, mri_file_type_hint hint) {
asset = mvec_next(asset_manager.files);
asset_from_path(path, asset);
if (asset->type == ASSET_VOID) {
- mvec_pop(asset_manager.files);
- asset = &asset_void;
+ asset = &mvec_pop(asset_manager.files);
}
}
diff --git a/src/context_glfw.c b/src/context_glfw.c
index 6470205..d40b595 100644
--- a/src/context_glfw.c
+++ b/src/context_glfw.c
@@ -34,13 +34,10 @@ static bool create_window(mri_context *c, float width, float height, const char
return false;
}
- glEnable(GL_MULTISAMPLE);
-
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- //glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA);
+ glEnable(GL_MULTISAMPLE);
- //glDisable(GL_CULL_FACE);
+ glDisable(GL_CULL_FACE);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
diff --git a/src/engine.c b/src/engine.c
index 0cf7fe4..155dd85 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -1,6 +1,5 @@
#include "engine.h"
-#include "cglm/vec4.h"
#include "objects/object.h"
#include "objects/scene.h"
#include "src/context.h"
@@ -28,11 +27,7 @@ void mri_engine_load(mri_engine *engine, mri_scene *scene) {
engine->texel_half_size[1] = .5f / engine->height;
engine->combine_buffer = mri_engine_get_or_new_framebuffer(engine,
- mstr_c("_rt_FullFrameBuffer"), engine->context->width, engine->context->height,
- 1.f, NULL);
-
- mri_shader_load(&engine->mininal_shader, mstr_c("minimal"));
- mri_shader_compile(&engine->mininal_shader);
+ mstr_c("_rt_FullFrameBuffer"), engine->context->width, engine->context->height, 1.f);
create_gl_object(&engine->default_gl_object, DEFAULT, 0, 0);
}
@@ -48,14 +43,14 @@ 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) {
+ float width, float height, float scale) {
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, engine->scene->clear_color);
+ mri_framebuffer_load(buffer);
}
return buffer;
@@ -67,10 +62,8 @@ void mri_engine_update(mri_engine *engine) {
}
void mri_engine_draw(mri_engine *engine) {
- mri_framebuffer *buffer;
- mvec_loop_ptr(engine->framebuffers, buffer, i) {
- mri_framebuffer_bind(buffer, true);
- }
+ mri_framebuffer_bind(engine->combine_buffer);
+ glClearBufferfv(GL_COLOR, 0, engine->scene->clear_color);
mri_scene_draw(engine, engine->scene);
@@ -85,13 +78,13 @@ void mri_engine_draw(mri_engine *engine) {
void mri_engine_run(mri_engine *engine) {
const float TARGET_FPS = 60.f;
+
float time = engine->context->current_time(engine->context);
while (!engine->context->should_close(engine->context)) {
mri_engine_update(engine);
mri_engine_draw(engine);
-
while (engine->context->current_time(engine->context) < time + 1.f / TARGET_FPS) {
usleep(2000); // 2ms
}
diff --git a/src/engine.h b/src/engine.h
index 3a15a2f..95fccae 100644
--- a/src/engine.h
+++ b/src/engine.h
@@ -26,7 +26,6 @@ struct mri_engine {
gl_object default_gl_object;
mri_framebuffer *combine_buffer;
- mri_shader mininal_shader;
mvec(mri_framebuffer) framebuffers;
@@ -37,7 +36,7 @@ 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);
+ mstr *name, float width, float height, float scale);
void mri_engine_next_pass(mri_engine *engine);
void mri_engine_next_effect(mri_engine *engine);
diff --git a/src/gl.c b/src/gl.c
index a03083e..b40880a 100644
--- a/src/gl.c
+++ b/src/gl.c
@@ -55,14 +55,11 @@ void destroy_gl_texture(gl_texture *tex) {
glDeleteTextures(1, &tex->id);
}
-void bind_gl_framebuffer(gl_framebuffer *buffer, bool clear) {
+void bind_gl_framebuffer(gl_framebuffer *buffer) {
glBindFramebuffer(GL_FRAMEBUFFER, buffer->id);
- if (clear) {
- glClearBufferfv(GL_COLOR, 0, buffer->clear_color);
- }
}
-void create_gl_framebuffer(gl_framebuffer *buffer, float width, float height, vec4 clear_color) {
+void create_gl_framebuffer(gl_framebuffer *buffer, float width, float height) {
glGenFramebuffers(1, &buffer->id);
glGenTextures(1, &buffer->texture.id);
@@ -80,11 +77,9 @@ void create_gl_framebuffer(gl_framebuffer *buffer, float width, float height, ve
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
buffer->texture.id, 0);
- glm_vec4_copy(clear_color, buffer->clear_color);
-
glDrawBuffers(1, (GLenum[]){GL_COLOR_ATTACHMENT0});
- glClearBufferfv(GL_COLOR, 0, (vec4){1.f, 1.f, 1.f, 1.f});
+ glClearBufferfv(GL_COLOR, 0, (vec4){0.f, 0.f, 0.f, 0.f});
}
void destroy_gl_framebuffer(gl_framebuffer *buffer) {
diff --git a/src/gl.h b/src/gl.h
index 885293d..f85b716 100644
--- a/src/gl.h
+++ b/src/gl.h
@@ -26,7 +26,6 @@ typedef struct {
typedef struct {
unsigned int id;
gl_texture texture;
- vec4 clear_color;
} gl_framebuffer;
typedef enum {
@@ -44,8 +43,8 @@ void upload_gl_texture(gl_texture *tex, unsigned char *data, int width, int heig
unsigned int format);
void destroy_gl_texture(gl_texture *tex);
-void bind_gl_framebuffer(gl_framebuffer *buffer, bool clear);
-void create_gl_framebuffer(gl_framebuffer *buffer, float width, float height, vec4 clear_color);
+void bind_gl_framebuffer(gl_framebuffer *buffer);
+void create_gl_framebuffer(gl_framebuffer *buffer, float width, float height);
void destroy_gl_framebuffer(gl_framebuffer *buffer);
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 8a8b2be..75d9d47 100644
--- a/src/mauri.c
+++ b/src/mauri.c
@@ -12,7 +12,9 @@ int main(int argc, char* argv[]) {
context->create_window(context, 1920, 1080, "mauri", false);
if (argc == 2) {
- mri_asset_manager_load_pkg(mstr_c(argv[1]));
+ if (!mri_asset_manager_load_pkg(mstr_c(argv[1]))) {
+ return 1;
+ }
mri_scene scene = {0};
mri_scene_parse(&scene);
diff --git a/src/objects/c b/src/objects/c
deleted file mode 100644
index 8b13789..0000000
--- a/src/objects/c
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/src/objects/effect.c b/src/objects/effect.c
index 1bc0726..cb37281 100644
--- a/src/objects/effect.c
+++ b/src/objects/effect.c
@@ -5,6 +5,8 @@
#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 <jansson.h>
@@ -14,6 +16,8 @@ void mri_effect_parse(mri_effect *effect, json_t *root) {
mvec_init(effect->passes0);
mvec_init(effect->passes1);
+ json_get_int(&effect->id, root, "id");
+
json_t *pass0;
json_t *passes0 = json_object_get(root, "passes");
json_array(pass0, passes0) {
@@ -36,6 +40,18 @@ void mri_effect_parse(mri_effect *effect, json_t *root) {
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);
+ }
}
}
@@ -46,19 +62,35 @@ mri_render_pass *mri_effect_next_pass(mri_effect *effect) {
return pass;
}
-void mri_effect_load(mri_engine *engine, mri_effect *effect) {
+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);
- if (i == mvec_size(effect->passes0) - 1) {
- pass->combine = true;
- }
-
pass->object = engine->current_object;
- pass->gl_object = &engine->default_gl_object;
+ pass->effect = effect;
- glm_mat4_identity(pass->model);
+ 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);
}
@@ -67,8 +99,8 @@ void mri_effect_load(mri_engine *engine, mri_effect *effect) {
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);
+ //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);
}
}
@@ -88,4 +120,12 @@ void mri_effect_unload(mri_effect *effect) {
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.h b/src/objects/effect.h
index 9570fde..374a39f 100644
--- a/src/objects/effect.h
+++ b/src/objects/effect.h
@@ -6,16 +6,24 @@
#include "types.h"
#include "pass.h"
+typedef struct {
+ mstr *name;
+ float scale;
+} mri_effect_buffer;
+
struct mri_effect {
mstr *name;
+ int id;
mvec(mri_pass) passes0;
mvec(mri_pass) passes1;
mvec(mri_render_pass) passes;
+
+ mvec(mri_effect_buffer) fbos;
};
void mri_effect_parse(mri_effect *effect, json_t *root);
-void mri_effect_load(mri_engine *engine, mri_effect *effect);
+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);
diff --git a/src/objects/material.c b/src/objects/material.c
index c340463..75422d1 100644
--- a/src/objects/material.c
+++ b/src/objects/material.c
@@ -39,7 +39,7 @@ mri_render_pass *mri_material_next_pass(mri_material *material) {
}
void mri_material_load(mri_engine *engine, mri_material *material, mri_material_type t,
- mri_render_pass *pass) {
+ mri_render_pass *pass, bool no_effects) {
mri_pass *pass0;
mvec_loop_ptr(material->passes0, pass0, i) {
switch (t) {
@@ -50,15 +50,20 @@ void mri_material_load(mri_engine *engine, mri_material *material, mri_material_
pass = mri_material_next_pass(material);
pass->object = engine->current_object;
+ pass->combine = no_effects;
- if (engine->current_object->passthrough) {
- pass->gl_object = &engine->current_object->gl_object;
+ if (engine->current_object->passthrough || no_effects) {
glm_mat4_copy(engine->current_object->model, pass->model);
} else {
- pass->gl_object = &engine->current_object->gl_uv_object;
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;
}
diff --git a/src/objects/material.h b/src/objects/material.h
index 5c8f7b5..e8bc13d 100644
--- a/src/objects/material.h
+++ b/src/objects/material.h
@@ -17,7 +17,8 @@ struct mri_material {
};
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);
+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);
diff --git a/src/objects/model.c b/src/objects/model.c
index 81cd0b0..45317f2 100644
--- a/src/objects/model.c
+++ b/src/objects/model.c
@@ -30,8 +30,8 @@ void mri_model_parse(mri_model *model, json_t *value) {
}
}
-void mri_model_load(mri_engine *engine, mri_model *model) {
- mri_material_load(engine, &model->material, MATERIAL_MODEL, NULL);
+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) {
diff --git a/src/objects/model.h b/src/objects/model.h
index 4d17c72..9daed21 100644
--- a/src/objects/model.h
+++ b/src/objects/model.h
@@ -15,7 +15,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_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);
diff --git a/src/objects/object.c b/src/objects/object.c
index d525d3a..6a67bea 100644
--- a/src/objects/object.c
+++ b/src/objects/object.c
@@ -84,22 +84,17 @@ void mri_object_load(mri_engine *engine, mri_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);
+ 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,
- mstr_c(abuffer), width, height, 1.f,
- engine->scene->clear_color);
+ abuffer, width, height, 1.f);
object->bbuffer = mri_engine_get_or_new_framebuffer(engine,
- mstr_c(bbuffer), width, height, 1.f,
- engine->scene->clear_color);
+ bbuffer, width, height, 1.f);
- free(abuffer);
- free(bbuffer);
+ mstr_free(abuffer);
+ mstr_free(bbuffer);
object->buffer_switch = false;
@@ -115,7 +110,7 @@ void mri_object_load(mri_engine *engine, mri_object *object) {
create_gl_object(&engine->current_object->gl_object,
OBJECT, width, height);
- mri_model_load(engine, &object->image);
+ mri_model_load(engine, &object->image, mvec_size(object->effects) == 0);
if (object->image.fullscreen) {
object->fullscreen = true;
@@ -131,23 +126,20 @@ void mri_object_load(mri_engine *engine, mri_object *object) {
mri_effect *effect;
mvec_loop_ptr(object->effects, effect, i) {
- mri_effect_load(engine, effect);
+ mri_effect_load(engine, effect, i == (mvec_size(object->effects) - 1));
}
}
-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;
+void mri_object_switch_buffer(mri_object *object) {
+ object->buffer_switch = !object->buffer_switch;
+}
- float wpad = (width - w1) / -2.f;
- float hpad = (height - h1) / -2.f;
+mri_framebuffer *mri_object_get_target_buffer(mri_object *object) {
+ return (object->buffer_switch) ? object->abuffer : object->bbuffer;
+}
- glViewport(wpad, hpad, width, height);
+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) {
@@ -157,25 +149,6 @@ void mri_object_draw(mri_engine *engine, mri_object *object) {
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) {
diff --git a/src/objects/object.h b/src/objects/object.h
index c7bb883..6431237 100644
--- a/src/objects/object.h
+++ b/src/objects/object.h
@@ -62,6 +62,10 @@ struct mri_object {
void mri_object_get_model(mri_object *object, mat4 model, float width, float height);
+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);
+
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);
diff --git a/src/objects/pass.c b/src/objects/pass.c
index e5604e6..4820065 100644
--- a/src/objects/pass.c
+++ b/src/objects/pass.c
@@ -2,6 +2,7 @@
#include <unistd.h>
#include "moro_str.h"
+#include "moro_vec.h"
#include "pass.h"
#include "material.h"
#include "model.h"
@@ -13,8 +14,8 @@
#include "../engine.h"
#include "../assets.h"
#include "../gl.h"
-#include "src/objects/types.h"
-#include "src/shader.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));
@@ -76,6 +77,16 @@ void mri_pass_parse(mri_pass *pass, json_t *root, mri_pass_stage stage) {
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;
}
}
@@ -119,7 +130,7 @@ 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) {
mri_object *object = engine->current_object;
- for (int i = 1; i < 7; i++) {
+ for (int i = 0; i < 7; i++) {
if (pass->textures[i]) rpass->textures[i] = pass->textures[i];
}
@@ -138,57 +149,59 @@ void mri_pass_load(mri_engine *engine, mri_pass *pass, mri_pass_stage stage, mri
}
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, 0.4f});
- } else {
- // 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;
+ if (!pass->target) {
+ if (rpass->combine) {
+ rpass->target = engine->combine_buffer;
} else {
- rpass->target = object->bbuffer;
- rpass->textures[0] = &object->abuffer->texture;
+ // 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"))) {
- if (object->buffer_switch) {
- rpass->textures[i] = &object->bbuffer->texture;
- } else {
- rpass->textures[i] = &object->abuffer->texture;
- }
+ 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
+
+ // 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);
+ 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:
- // 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_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: {
- memcpy(&rpass->shader, pass->shader, sizeof(mri_shader));
+ rpass->shader = *pass->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));
+ 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
@@ -196,7 +209,8 @@ void mri_pass_load(mri_engine *engine, mri_pass *pass, mri_pass_stage stage, mri
if (!rpass->textures[i] && rpass->shader.textures[i]) {
rpass->textures[i] = rpass->shader.textures[i];
}
- // Set TEX0FORMAT incase extra steps are needed when sampling,
+
+ // Set TEX0FORMAT in-case extra steps are needed when sampling,
// see "common_fragment.h".
if (rpass->textures[i] && i == 0) {
mri_combo c = {
@@ -262,8 +276,27 @@ void mri_pass_load(mri_engine *engine, mri_pass *pass, mri_pass_stage stage, mri
}
}
+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, false);
+ mri_framebuffer_bind(pass->target);
mri_shader_bind(engine, &pass->shader, pass->model);
bind_gl_object(pass->gl_object);
@@ -272,27 +305,50 @@ void mri_render_pass_draw(mri_engine *engine, mri_render_pass *pass) {
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);
+ 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);
+ }
+
+ 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);
+#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);
+ 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);
+ engine->context->swap_buffers(engine->context);
- usleep(5000000);
- }
+ usleep(1400000);
+#endif
}
void mri_pass_unload(mri_pass *pass) {
diff --git a/src/objects/pass.h b/src/objects/pass.h
index 37c0997..64947c9 100644
--- a/src/objects/pass.h
+++ b/src/objects/pass.h
@@ -25,6 +25,10 @@ typedef enum {
PASS,
} mri_render_pass_stage;
+typedef enum {
+ TRANSLUCENT,
+ NORMAL
+} mri_pass_blend_mode;
struct mri_pass {
int id;
@@ -37,6 +41,8 @@ struct mri_pass {
mstr *target;
mstr *binds[7];
+ mri_pass_blend_mode blend;
+
mvec(mri_uniform) uniforms;
mvec(mri_combo) combos;
};
@@ -45,6 +51,7 @@ struct mri_render_pass {
mri_shader shader;
mri_object *object;
+ mri_effect *effect;
mat4 model;
gl_object *gl_object;
@@ -54,6 +61,8 @@ struct mri_render_pass {
bool combine;
+ mri_pass_blend_mode combine_blend;
+
mri_render_pass_stage stage;
mvec(mri_uniform) uniforms;
diff --git a/src/objects/scene.c b/src/objects/scene.c
index e320acf..62c70b2 100644
--- a/src/objects/scene.c
+++ b/src/objects/scene.c
@@ -82,15 +82,15 @@ 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);
- }
- }
- }
+ //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 3df4a21..b054cbb 100644
--- a/src/shader.c
+++ b/src/shader.c
@@ -6,6 +6,7 @@
#include <moro.h>
+#include "moro_str.h"
#include "shader.h"
#include "assets.h"
#include "json.h"
@@ -36,11 +37,11 @@ static const char *gl_compat =
static const char *version = "#version 120\n";
-static mstr *build_shader_source(mri_shader *shader, mstr *isource, bool start) {
+static mstr *build_shader_source(mri_shader *shader, mstr *isource, bool root) {
mstr *source = mstr_from("\0");
- if (start)
- mstr_cat(source, mstr_c(gl_compat));
+ // Append compatablity macros once per shader
+ if (root) mstr_cat(source, mstr_c(gl_compat));
mstr line = {0};
@@ -81,23 +82,36 @@ static mstr *build_shader_source(mri_shader *shader, mstr *isource, bool start)
json_t *root = json_load_mstr(&combo_str);
- if (!root) continue;
+ if (!root) {
+ log_error("err: failed to load the combo for (%.*s)", MSTR_PRINTF(u->uname));
+ continue;
+ }
+ // If material is present, it's always used to reference this
+ // uniform for setting its values. If material is not present,
+ // label is used.
json_t *label = json_object_get(root, "label");
json_t *material = json_object_get(root, "material");
- if (json_is_string(material))
+ if (json_is_string(material)) {
u->name = mstr_clone(mstr_c(json_string_value(material)));
- else if (json_is_string(label))
+ } else if (json_is_string(label)) {
u->name = mstr_clone(mstr_c(json_string_value(label)));
+ }
switch (u->type) {
case TYPE_SAMPLER2D: {
+ int index = (int)u->value[0];
+
json_t *texture = json_object_get(root, "default");
if (json_is_string(texture)) {
- mri_asset *_a = mri_asset_manager_get(mstr_c(json_string_value(texture)), TEXTURE);
- shader->textures[(int)u->value[0]] = mri_texture_load(_a);
+ mstr *path = mstr_c(json_string_value(texture));
+ shader->textures[index] = mri_texture_load(
+ mri_asset_manager_get(path, TEXTURE));
}
+
+ // NOTE: I assume the only case where this is wrong would
+ // be if "combo" is present and not "default".
json_t *combo = json_object_get(root, "combo");
if (json_is_string(combo)) {
mri_combo c = {
@@ -106,6 +120,7 @@ static mstr *build_shader_source(mri_shader *shader, mstr *isource, bool start)
};
mvec_push(shader->combos, c);
}
+
break;
}
case TYPE_FLOAT:
@@ -133,12 +148,22 @@ static mstr *build_shader_source(mri_shader *shader, mstr *isource, bool start)
json_t *root = json_load_mstr(&combo);
- mri_combo c = {
- .name = mstr_from(json_string_value(json_object_get(root, "combo"))),
- .value = json_integer_value(json_object_get(root, "default"))
- };
+ if (!root) {
+ log_error("%s", "err: failed to load [COMBO]");
+ continue;
+ }
+
+ json_t *_combo = json_object_get(root, "combo");
+ json_t *_value = json_object_get(root, "default");
- mvec_push(shader->combos, c);
+ if (json_is_string(_combo) && json_is_integer(_value)) {
+ mri_combo c = {
+ .name = mstr_from(json_string_value(_combo)),
+ .value = json_integer_value(_value)
+ };
+
+ mvec_push(shader->combos, c);
+ }
json_decref(root);
}
@@ -152,11 +177,9 @@ static mstr *build_shader_source(mri_shader *shader, mstr *isource, bool start)
return source;
}
-static char *mri_combo_to_str(mri_combo *combo) {
- char *combo_str;
- asprintf(&combo_str, "#define %.*s %i\n", (int)combo->name->len,
+static mstr *mri_combo_to_str(mri_combo *combo) {
+ return mstr_sprintf("#define %.*s %i\n", (int)combo->name->len,
combo->name->ptr, combo->value);
- return combo_str;
}
void mri_shader_compile(mri_shader *shader) {
@@ -165,10 +188,10 @@ void mri_shader_compile(mri_shader *shader) {
mri_combo *combo;
mvec_loop_ptr(shader->combos, combo, i) {
- char *combo_str = mri_combo_to_str(combo);
- mstr_prepend(vs_source, mstr_c(combo_str));
- mstr_prepend(fs_source, mstr_c(combo_str));
- free(combo_str);
+ mstr *combo_str = mri_combo_to_str(combo);
+ mstr_prepend(vs_source, combo_str);
+ mstr_prepend(fs_source, combo_str);
+ mstr_free(combo_str);
}
mstr_prepend(vs_source, mstr_c(version));
@@ -195,7 +218,7 @@ void mri_shader_load(mri_shader *shader, mstr *name) {
if (vs_asset->type != ASSET_VOID) {
shader->vs_source = build_shader_source(shader, mri_asset_as_str(vs_asset), true);
} else {
- log_error("failed to load shader file (%.*s.vert)", name->len, name->ptr);
+ log_error("failed to load shader file (%.*s.vert)", MSTR_PRINTF(name));
}
mri_asset *fs_asset = mri_asset_manager_get(name, FRAGMENT_SHADER);
@@ -203,7 +226,7 @@ void mri_shader_load(mri_shader *shader, mstr *name) {
if (fs_asset->type != ASSET_VOID) {
shader->fs_source = build_shader_source(shader, mri_asset_as_str(fs_asset), true);
} else {
- log_error("failed to load shader file (%.*s.frag)", name->len, name->ptr);
+ log_error("failed to load shader file (%.*s.frag)", MSTR_PRINTF(name));
}
}
diff --git a/src/texture.c b/src/texture.c
index edc81a0..29f6cab 100644
--- a/src/texture.c
+++ b/src/texture.c
@@ -18,26 +18,27 @@ static unsigned char *load_image_rgba(unsigned char *data, int len) {
return stbi_load_from_memory(data, len, &w, &h, &channels, 4);
}
-static uint32_t rgba_to_brga(uint32_t x) {
- return ((x) & 0xff00ff00) |
- ((x >> 16) & 0xFF) |
- ((x << 16) & 0xFF0000);
-}
-
-static uint32_t argb_to_brga(uint32_t x) {
- return ((x & 0xFF000000) >> 24) | //______AA
- ((x & 0x00FF0000) >> 8) | //____RR__
- ((x & 0x0000FF00) << 8) | //__GG____
- ((x & 0x000000FF) << 24);
-}
+//static uint32_t rgba_to_brga(uint32_t x) {
+// return ((x) & 0xff00ff00) |
+// ((x >> 16) & 0xFF) |
+// ((x << 16) & 0xFF0000);
+//}
+//
+//static uint32_t argb_to_brga(uint32_t x) {
+// return ((x & 0xFF000000) >> 24) | //______AA
+// ((x & 0x00FF0000) >> 8) | //____RR__
+// ((x & 0x0000FF00) << 8) | //__GG____
+// ((x & 0x000000FF) << 24);
+//}
mri_texture *mri_texture_load(mri_asset *asset) {
// check if texture was previously loaded
mri_texture *t = (mri_texture *)malloc(sizeof(mri_texture));
- mstr type = mri_asset_str(asset, 9);
- mstr itype = mri_asset_str(asset, 9);
+ //mstr type = mri_asset_str(asset, 9);
+ //mstr itype = mri_asset_str(asset, 9);
+ mri_asset_seek(asset, 18);
t->format = (mri_texture_format)mri_asset_value(asset, unsigned int);
@@ -159,7 +160,6 @@ void mri_texture_bind(mri_texture *t, int index) {
bind_gl_texture(&t->texture, index);
}
-
void mri_framebuffer_create(mri_framebuffer *buffer, mstr *name, float width, float height, float scale) {
buffer->name = mstr_clone(name);
@@ -172,8 +172,8 @@ void mri_framebuffer_create(mri_framebuffer *buffer, mstr *name, float width, fl
buffer->texture.texture_resolution[3] = buffer->height;
}
-void mri_framebuffer_load(mri_framebuffer *buffer, vec4 clear_color) {
- create_gl_framebuffer(&buffer->buffer, buffer->width, buffer->height, clear_color);
+void mri_framebuffer_load(mri_framebuffer *buffer) {
+ create_gl_framebuffer(&buffer->buffer, buffer->width, buffer->height);
buffer->texture.texture.id = buffer->buffer.texture.id;
}
@@ -183,8 +183,8 @@ void mri_framebuffer_unload(mri_framebuffer *buffer) {
//free(buffer);
}
-void mri_framebuffer_bind(mri_framebuffer *buffer, bool clear) {
- bind_gl_framebuffer(&buffer->buffer, clear);
+void mri_framebuffer_bind(mri_framebuffer *buffer) {
+ bind_gl_framebuffer(&buffer->buffer);
}
diff --git a/src/texture.h b/src/texture.h
index 68211b4..0ed692f 100644
--- a/src/texture.h
+++ b/src/texture.h
@@ -61,8 +61,8 @@ void mri_texture_unload(mri_texture *texture);
void mri_texture_bind(mri_texture *t, int index);
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_load(mri_framebuffer *buffer);
void mri_framebuffer_unload(mri_framebuffer *buffer);
-void mri_framebuffer_bind(mri_framebuffer *buffer, bool clear);
+void mri_framebuffer_bind(mri_framebuffer *buffer);
#endif // _TEXTURE_H