summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Opalach <andrew@akon.city> 2020-08-24 19:20:38 -0400
committerAndrew Opalach <andrew@akon.city> 2020-08-24 19:20:38 -0400
commit8846a97329d0ec632b837347ab0b4389b862c860 (patch)
tree930c71d179555bb8e6c5269d1f8ff4d29186b183 /src
parent099cd3b45f6f0f2acf01b0497c61046f16df7c0c (diff)
downloadmauri-8846a97329d0ec632b837347ab0b4389b862c860.tar.gz
mauri-8846a97329d0ec632b837347ab0b4389b862c860.tar.bz2
mauri-8846a97329d0ec632b837347ab0b4389b862c860.zip
implement most of the shader parsing
Diffstat (limited to 'src')
-rw-r--r--src/assets.h8
-rw-r--r--src/objects/material.h6
-rw-r--r--src/objects/model.h1
-rw-r--r--src/objects/pass.c12
-rw-r--r--src/objects/pass.h8
-rw-r--r--src/shader.c170
-rw-r--r--src/shader.h44
-rw-r--r--src/texture.h1
8 files changed, 242 insertions, 8 deletions
diff --git a/src/assets.h b/src/assets.h
index cffb936..0a49bfe 100644
--- a/src/assets.h
+++ b/src/assets.h
@@ -48,12 +48,12 @@ typedef struct {
// not thread-safe
extern mri_asset_manager asset_manager;
-#define asset_ptr(asset) &asset.data[asset.pos]
-#define seek(asset, n) asset.pos += n
+#define asset_ptr(asset) &(asset).data[(asset).pos]
+#define seek(asset, n) (asset).pos += n
#define read_value(asset, type) ({ \
type val = *((type *)(asset_ptr(asset))); \
- seek(asset, sizeof(type)); \
+ seek((asset), sizeof(type)); \
val; \
})
@@ -63,7 +63,7 @@ extern mri_asset_manager asset_manager;
.len = _n, \
.ptr = asset_ptr(asset) \
}; \
- seek(asset, _n); \
+ seek((asset), _n); \
val; \
})
diff --git a/src/objects/material.h b/src/objects/material.h
index 72b2d45..e7311c0 100644
--- a/src/objects/material.h
+++ b/src/objects/material.h
@@ -1,11 +1,13 @@
#ifndef _MATERIAL_H
#define _MATERIAL_H
+#include <jansson.h>
+
#include "pass.h"
-typedef struct {
+struct mri_material {
mvec(mri_pass) passes;
-} mri_material;
+};
void mri_material_parse(mri_material *material, json_t *value);
void mri_material_unload(mri_material *material);
diff --git a/src/objects/model.h b/src/objects/model.h
index e59b369..f1068d7 100644
--- a/src/objects/model.h
+++ b/src/objects/model.h
@@ -3,6 +3,7 @@
#include <jansson.h>
+#include "pass.h"
#include "material.h"
typedef struct {
diff --git a/src/objects/pass.c b/src/objects/pass.c
index c90eb92..ba9de8c 100644
--- a/src/objects/pass.c
+++ b/src/objects/pass.c
@@ -1,10 +1,15 @@
#include "pass.h"
+#include "material.h"
#include "../json.h"
#include "../texture.h"
#include "../assets.h"
void mri_pass_parse(mri_pass *pass, json_t *root) {
+ // TODO
+ pass->material = (mri_material *)malloc(sizeof(mri_material));
+ mri_material_parse(pass->material, json_object_get(root, "material"));
+
json_t *texture;
json_t *textures = json_object_get(root, "textures");
json_array(texture, textures) {
@@ -13,7 +18,14 @@ void mri_pass_parse(mri_pass *pass, json_t *root) {
mri_texture_unload(pass->textures[i]);
}
}
+
+ json_t *shader = json_object_get(root, "shader");
+ if (json_is_string(shader)) {
+ mri_shader_load(&pass->shader, json_string_value(shader));
+ mri_shader_unload(&pass->shader);
+ }
}
void mri_pass_unload(mri_pass *pass) {
+ free(pass->material);
}
diff --git a/src/objects/pass.h b/src/objects/pass.h
index aa8e2fb..ce34edd 100644
--- a/src/objects/pass.h
+++ b/src/objects/pass.h
@@ -3,11 +3,15 @@
#include <jansson.h>
+#include "../shader.h"
#include "../texture.h"
+typedef struct mri_material mri_material;
+
typedef struct {
- // mri_shader *shader;
- // mri_material *material;
+ mri_material *material;
+
+ mri_shader shader;
mri_texture *textures[7];
// mvec(mri_uniform) uniforms;
diff --git a/src/shader.c b/src/shader.c
new file mode 100644
index 0000000..c2d7d1a
--- /dev/null
+++ b/src/shader.c
@@ -0,0 +1,170 @@
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "shader.h"
+#include "assets.h"
+#include "log.h"
+
+static const char *gl_compat =
+ "#define highp\n"
+ "#define mediump\n"
+ "#define lowp\n"
+ "#define mul(x, y) (y * x)\n"
+ "#define frac fract\n"
+ "#define CAST2(x) (vec2(x))\n"
+ "#define CAST3(x) (vec3(x))\n"
+ "#define CAST4(x) (vec4(x))\n"
+ "#define CAST3X3(x) (mat3(x))\n"
+ "#define saturate(x) (clamp(x, 0.0, 1.0))\n"
+ "#define texSample2D texture2D\n"
+ "#define texSample2DLod texture2DLod\n"
+ "#define texture2DLod texture2D\n"
+ "#define atan2(y,x) atan(x,y)\n"
+ "#define ddx dFdx\n"
+ "#define ddy(x) dFdy(-(x))\n"
+ "#define GLSL 1\n\0";
+
+static const char *version = "#version 120\n";
+
+static char *build_shader_source(mri_shader *shader, char *buffer, bool first) {
+ size_t source_len = strlen(buffer) + strlen(gl_compat);
+ size_t source_index = 0;
+
+ char *source = (char *)malloc(source_len);
+ source[source_index] = '\0';
+
+ if (first) {
+ source_index += strlen(gl_compat) + 1;
+ strncat(source, gl_compat, source_index);
+ }
+
+ char *line = buffer;
+
+ while (line) {
+ char *next_line = strchr(line, '\n');
+ size_t len = next_line ? (size_t)(next_line - line) : strlen(line);
+
+ if (memcmp(line, "#include", 8) == 0) {
+ char *open = strchr(line, '"') + 1;
+ char *close = strchr(open, '"') + 1;
+
+ char *include = (char *)malloc(close - open);
+ snprintf(include, close - open, "%s", open);
+
+ mri_asset *include_asset = mri_asset_manager_get(include, SHADER);
+
+ if (include_asset->type == ASSET_VOID) {
+ return NULL;
+ }
+
+ char *include_str = mri_str_to_c_str(read_string(*include_asset, include_asset->size));
+ char *include_src = build_shader_source(shader, include_str, false);
+
+ if (!include_src) {
+ return NULL;
+ }
+
+ size_t include_len = strlen(include_src);
+
+ if (!(source = realloc(source, source_len + include_len))) {
+ log_error("%s", "failed to allocate memory for shader source");
+ abort(); // fatal
+ }
+
+ strncat(source, include_src, include_len + 1);
+ source_index += include_len + 1;
+
+ free(include);
+ free(include_src);
+ free(include_str);
+ } else if (memcmp(line, "uniform", 7) == 0) {
+ mri_uniform _u = {0};
+ mvec_push(shader->uniforms, _u);
+
+ mri_uniform *u = &mvec_last(shader->uniforms);
+
+ char *type_start = strchr(line, ' ') + 1;
+ char *type_end = strchr(type_start, ' ') + 1;
+
+ char *type = (char *)malloc(type_end - type_start);
+ snprintf(type, type_end - type_start, "%s", type_start);
+
+ if (memcmp(type, "float", 5) == 0) u->type = TYPE_FLOAT;
+ else if (memcmp(type, "vec4", 4) == 0) u->type = TYPE_VEC4;
+ else if (memcmp(type, "vec3", 4) == 0) u->type = TYPE_VEC3;
+ else if (memcmp(type, "vec2", 4) == 0) u->type = TYPE_VEC2;
+ else if (memcmp(type, "sampler2D", 10) == 0) {
+ u->type = TYPE_SAMPLER2D;
+ }
+
+ char *name_end = strchr(type_end, ';') + 1;
+
+ u->uname = (char *)malloc(name_end - type_end);
+ snprintf(u->uname, name_end - type_end, "%s", type_end);
+
+ char *combo_start = strchr(line, '/');
+
+ if (combo_start && combo_start - line < len) {
+ // parse combo
+ }
+ } else {
+ strncat(source, line, len + 1);
+ source_index += len + 1;
+ source[source_index] = '\0';
+ }
+
+ line = next_line ? next_line + 1 : NULL;
+ }
+
+ return source;
+}
+
+void mri_shader_load(mri_shader *shader, const char *name) {
+ mvec_init(shader->uniforms);
+
+ mri_asset *vertex_asset = mri_asset_manager_get(name, VERTEX_SHADER);
+ if (vertex_asset->type != ASSET_VOID) {
+ char *vertex_str = mri_str_to_c_str(read_string(*vertex_asset, vertex_asset->size));
+ shader->vertex_source = build_shader_source(shader, vertex_str, true);
+
+ if (!shader->vertex_source) {
+ log_error("failed to parse shader (%s.vert)", name);
+ }
+
+ free(vertex_str);
+ } else {
+ log_error("failed to load shader file (%s.vert)", name);
+ }
+
+ mri_asset *fragment_asset = mri_asset_manager_get(name, FRAGMENT_SHADER);
+ if (fragment_asset->type != ASSET_VOID) {
+ char *fragment_str = mri_str_to_c_str(read_string(*fragment_asset, fragment_asset->size));
+ shader->fragment_source = build_shader_source(shader, fragment_str, true);
+
+ if (!shader->fragment_source) {
+ log_error("failed to parse shader (%s.frag)", name);
+ }
+
+ free(fragment_str);
+ } else {
+ log_error("failed to load shader file (%s.frag)", name);
+ }
+}
+
+void mri_shader_unload(mri_shader *shader) {
+ free(shader->vertex_source);
+ free(shader->fragment_source);
+
+ mri_uniform *uniform;
+ mvec_loop_ptr(shader->uniforms, uniform) {
+ printf("%s\n", uniform->uname);
+ printf("%i\n", uniform->type);
+ free(uniform->uname);
+ }
+
+ mvec_free(shader->uniforms);
+}
+
+
+
diff --git a/src/shader.h b/src/shader.h
new file mode 100644
index 0000000..a9548c3
--- /dev/null
+++ b/src/shader.h
@@ -0,0 +1,44 @@
+#ifndef _SHADER_H
+#define _SHADER_H
+
+#include "texture.h"
+
+typedef enum {
+ TYPE_FLOAT,
+ TYPE_VEC4,
+ TYPE_VEC3,
+ TYPE_VEC2,
+ TYPE_MAT4,
+ TYPE_SAMPLER2D
+} mri_uniform_type;
+
+typedef struct {
+ mri_uniform_type type;
+ const char *name;
+ const char *uname;
+ vec4 value;
+} mri_uniform;
+
+typedef struct {
+ const char *name;
+ int value;
+} mri_combo;
+
+typedef struct {
+ const char *name;
+
+ char *vertex_source;
+ char *fragment_source;
+
+ int texture_count;
+
+ mri_texture *textures[7];
+
+ mvec(mri_combo) combos;
+ mvec(mri_uniform) uniforms;
+} mri_shader;
+
+void mri_shader_load(mri_shader *shader, const char *name);
+void mri_shader_unload(mri_shader *shader);
+
+#endif // _SHADER_H
diff --git a/src/texture.h b/src/texture.h
index a750ba6..58e3b67 100644
--- a/src/texture.h
+++ b/src/texture.h
@@ -1,6 +1,7 @@
#ifndef _TEXTURE_H
#define _TEXTURE_H
+#include <stdbool.h>
#include <cglm/cglm.h>
#include "assets.h"