diff --git a/base/project.js b/base/project.js index 5daf5479..3624e628 100644 --- a/base/project.js +++ b/base/project.js @@ -33,6 +33,7 @@ let dir = flags.name.substr(5).toLowerCase(); // ArmorPaint -> paint let project = new Project("Base"); project.add_include_dir("sources"); project.add_include_dir("sources/libs"); +project.add_tsfiles("sources"); project.add_tsfiles("sources/ts"); project.add_shaders("shaders/*.kong"); project.add_assets("assets/*", {destination : "data/{name}"}); diff --git a/base/sources/engine.c b/base/sources/engine.c index e69de29b..935b22f9 100644 --- a/base/sources/engine.c +++ b/base/sources/engine.c @@ -0,0 +1,919 @@ +#include "engine.h" + +i32 _object_uid_counter = 0; +extern any_array_t *scene_empties; +extern any_array_t *scene_meshes; +extern object_t *_scene_scene_parent; + +void mesh_object_remove(void *raw); +void camera_object_remove(void *raw); +_scene_t *data_get_scene_raw(char *name); + +gpu_buffer_t *gpu_create_vertex_buffer(i32 count, gpu_vertex_structure_t *structure); +gpu_buffer_t *gpu_create_index_buffer(i32 count); +buffer_t *gpu_lock_vertex_buffer(gpu_buffer_t *buffer); +u32_array_t *gpu_lock_index_buffer(gpu_buffer_t *buffer); +void gpu_delete_buffer(gpu_buffer_t *buffer); +f32 math_floor(f32 x); +gpu_shader_t *gpu_create_shader(buffer_t *data, i32 shader_type); +gpu_shader_t *gpu_create_shader_from_source(char *source, int source_size, gpu_shader_type_t shader_type); +gpu_pipeline_t *gpu_create_pipeline(); +void gpu_delete_pipeline(gpu_pipeline_t *pipeline); +#ifdef arm_embed +gpu_shader_t *sys_get_shader(char *name); +#endif + +// ██████╗ ██████╗ ██╗███████╗ ██████╗████████╗ +// ██╔═══██╗██╔══██╗ ██║██╔════╝██╔════╝╚══██╔══╝ +// ██║ ██║██████╔╝ ██║█████╗ ██║ ██║ +// ██║ ██║██╔══██╗██ ██║██╔══╝ ██║ ██║ +// ╚██████╔╝██████╔╝╚█████╔╝███████╗╚██████╗ ██║ +// ╚═════╝ ╚═════╝ ╚════╝ ╚══════╝ ╚═════╝ ╚═╝ + +object_t *object_create(bool is_empty) { + object_t *raw = gc_alloc(sizeof(object_t)); + raw->name = ""; + raw->children = any_array_create(0); + raw->visible = true; + raw->culled = false; + raw->uid = _object_uid_counter++; + raw->transform = transform_create(raw); + raw->is_empty = is_empty; + if (raw->is_empty) { + any_array_push(scene_empties, raw); + } + return raw; +} + +void object_set_parent(object_t *raw, object_t *parent_object) { + if (parent_object == raw || parent_object == raw->parent) { + return; + } + + if (raw->parent != NULL) { + array_remove(raw->parent->children, raw); + raw->parent = NULL; // Rebuild matrix without a parent + transform_build_matrix(raw->transform); + } + + if (parent_object == NULL) { + parent_object = _scene_scene_parent; + } + raw->parent = parent_object; + any_array_push(raw->parent->children, raw); +} + +void object_remove_super(object_t *raw) { + if (raw->is_empty) { + array_remove(scene_empties, raw); + } + while (raw->children->length > 0) { + object_remove((object_t *)raw->children->buffer[0]); + } + if (raw->parent != NULL) { + array_remove(raw->parent->children, raw); + raw->parent = NULL; + } +} + +void object_remove(object_t *raw) { + if (string_equals(raw->ext_type, "mesh_object_t")) { + mesh_object_remove(raw->ext); + } + else if (string_equals(raw->ext_type, "camera_object_t")) { + camera_object_remove(raw->ext); + } + else { + object_remove_super(raw); + } +} + +object_t *object_get_child(object_t *raw, char *name) { + if (string_equals(raw->name, name)) { + return raw; + } + for (i32 i = 0; i < raw->children->length; ++i) { + object_t *c = (object_t *)raw->children->buffer[i]; + object_t *r = object_get_child(c, name); + if (r != NULL) { + return r; + } + } + return NULL; +} + +// ████████╗██████╗ █████╗ ███╗ ██╗███████╗███████╗ ██████╗ ██████╗ ███╗ ███╗ +// ╚══██╔══╝██╔══██╗██╔══██╗████╗ ██║██╔════╝██╔════╝██╔═══██╗██╔══██╗████╗ ████║ +// ██║ ██████╔╝███████║██╔██╗ ██║███████╗█████╗ ██║ ██║██████╔╝██╔████╔██║ +// ██║ ██╔══██╗██╔══██║██║╚██╗██║╚════██║██╔══╝ ██║ ██║██╔══██╗██║╚██╔╝██║ +// ██║ ██║ ██║██║ ██║██║ ╚████║███████║██║ ╚██████╔╝██║ ██║██║ ╚═╝ ██║ +// ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═══╝╚══════╝╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ + +transform_t *transform_create(object_t *object) { + transform_t *raw = gc_alloc(sizeof(transform_t)); + raw->scale_world = 1.0; + raw->object = object; + transform_reset(raw); + return raw; +} + +void transform_reset(transform_t *raw) { + raw->world = mat4_identity(); + raw->world_unpack = mat4_identity(); + raw->local = mat4_identity(); + raw->loc = vec4_create(0.0, 0.0, 0.0, 0.0); + raw->rot = quat_create(0.0, 0.0, 0.0, 1.0); + raw->scale = vec4_create(1.0, 1.0, 1.0, 0.0); + raw->dim = vec4_create(2.0, 2.0, 2.0, 0.0); + raw->radius = 1.0; + raw->dirty = true; +} + +void transform_update(transform_t *raw) { + if (raw->dirty) { + transform_build_matrix(raw); + } +} + +void transform_build_matrix(transform_t *raw) { + raw->local = mat4_compose(raw->loc, raw->rot, raw->scale); + + if (raw->object->parent != NULL) { + raw->world = mat4_mult_mat3x4(raw->local, raw->object->parent->transform->world); + } + else { + raw->world = mat4_clone(raw->local); + } + + raw->world_unpack = mat4_clone(raw->world); + if (raw->scale_world != 1.0) { + raw->world_unpack.m00 *= raw->scale_world; + raw->world_unpack.m01 *= raw->scale_world; + raw->world_unpack.m02 *= raw->scale_world; + raw->world_unpack.m03 *= raw->scale_world; + raw->world_unpack.m10 *= raw->scale_world; + raw->world_unpack.m11 *= raw->scale_world; + raw->world_unpack.m12 *= raw->scale_world; + raw->world_unpack.m13 *= raw->scale_world; + raw->world_unpack.m20 *= raw->scale_world; + raw->world_unpack.m21 *= raw->scale_world; + raw->world_unpack.m22 *= raw->scale_world; + raw->world_unpack.m23 *= raw->scale_world; + } + + transform_compute_dim(raw); + + // Update children + for (i32 i = 0; i < raw->object->children->length; ++i) { + object_t *n = (object_t *)raw->object->children->buffer[i]; + transform_build_matrix(n->transform); + } + + raw->dirty = false; +} + +void transform_set_matrix(transform_t *raw, mat4_t mat) { + raw->local = mat4_clone(mat); + transform_decompose(raw); + transform_build_matrix(raw); +} + +void transform_decompose(transform_t *raw) { + mat4_decomposed_t *dec = mat4_decompose(raw->local); + raw->loc = dec->loc; + raw->rot = dec->rot; + raw->scale = dec->scl; +} + +void transform_rotate(transform_t *raw, vec4_t axis, float f) { + quat_t q = quat_from_axis_angle(axis, f); + raw->rot = quat_mult(q, raw->rot); + transform_build_matrix(raw); +} + +void transform_move(transform_t *raw, vec4_t axis, float f) { + raw->loc = vec4_fadd(raw->loc, axis.x * f, axis.y * f, axis.z * f, 0.0); + transform_build_matrix(raw); +} + +void transform_compute_radius(transform_t *raw) { + raw->radius = sqrtf(raw->dim.x * raw->dim.x + raw->dim.y * raw->dim.y + raw->dim.z * raw->dim.z); +} + +void transform_compute_dim(transform_t *raw) { + if (raw->object->raw == NULL && string_equals(raw->object->ext_type, "mesh_object_t")) { + //// TODO + // mesh_object_t *mo = (mesh_object_t *)raw->object->ext; + // vec4_t aabb = mesh_data_calculate_aabb(mo->data); + // _obj_t *o_raw = gc_alloc(sizeof(_obj_t)); + // o_raw->dimensions = f32_array_create_xyz(aabb.x, aabb.y, aabb.z); + // raw->object->raw = o_raw; + } + + if (raw->object->raw == NULL || raw->object->raw->dimensions == NULL) { + raw->dim = vec4_create(2.0 * raw->scale.x, 2.0 * raw->scale.y, 2.0 * raw->scale.z, 0.0); + } + else { + f32_array_t *d = raw->object->raw->dimensions; + raw->dim = vec4_create(d->buffer[0] * raw->scale.x, d->buffer[1] * raw->scale.y, d->buffer[2] * raw->scale.z, 0.0); + } + transform_compute_radius(raw); +} + +vec4_t transform_look(transform_t *raw) { + return mat4_look(raw->world); +} + +vec4_t transform_right(transform_t *raw) { + return mat4_right(raw->world); +} + +vec4_t transform_up(transform_t *raw) { + return mat4_up(raw->world); +} + +float transform_world_x(transform_t *raw) { + return raw->world.m30; +} + +float transform_world_y(transform_t *raw) { + return raw->world.m31; +} + +float transform_world_z(transform_t *raw) { + return raw->world.m32; +} + +// ██████╗ █████╗ ███╗ ███╗███████╗██████╗ █████╗ ██████╗ █████╗ ████████╗ █████╗ +// ██╔════╝██╔══██╗████╗ ████║██╔════╝██╔══██╗██╔══██╗ ██╔══██╗██╔══██╗╚══██╔══╝██╔══██╗ +// ██║ ███████║██╔████╔██║█████╗ ██████╔╝███████║ ██║ ██║███████║ ██║ ███████║ +// ██║ ██╔══██║██║╚██╔╝██║██╔══╝ ██╔══██╗██╔══██║ ██║ ██║██╔══██║ ██║ ██╔══██║ +// ╚██████╗██║ ██║██║ ╚═╝ ██║███████╗██║ ██║██║ ██║ ██████╔╝██║ ██║ ██║ ██║ ██║ +// ╚═════╝╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ + +camera_data_t *camera_data_parse(char *name, char *id) { + _scene_t *format = data_get_scene_raw(name); + camera_data_t *raw = camera_data_get_raw_by_name(format->camera_datas, id); + if (raw == NULL) { + iron_log("Camera data '%s' not found!", id); + } + return raw; +} + +camera_data_t *camera_data_get_raw_by_name(any_array_t *datas, char *name) { + if (strcmp(name, "") == 0) { + return (camera_data_t *)datas->buffer[0]; + } + for (i32 i = 0; i < datas->length; ++i) { + camera_data_t *d = (camera_data_t *)datas->buffer[i]; + if (strcmp(d->name, name) == 0) { + return d; + } + } + return NULL; +} + +// ██╗ ██╗ ██████╗ ██████╗ ██╗ ██████╗ ██████╗ █████╗ ████████╗ █████╗ +// ██║ ██║██╔═══██╗██╔══██╗██║ ██╔══██╗ ██╔══██╗██╔══██╗╚══██╔══╝██╔══██╗ +// ██║ █╗ ██║██║ ██║██████╔╝██║ ██║ ██║ ██║ ██║███████║ ██║ ███████║ +// ██║███╗██║██║ ██║██╔══██╗██║ ██║ ██║ ██║ ██║██╔══██║ ██║ ██╔══██║ +// ╚███╔███╔╝╚██████╔╝██║ ██║███████╗ ██████╔╝ ██████╔╝██║ ██║ ██║ ██║ ██║ +// ╚══╝╚══╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ + +f32_array_t *_world_data_empty_irr = NULL; + +world_data_t *world_data_parse(char *name, char *id) { + _scene_t *format = data_get_scene_raw(name); + world_data_t *raw = world_data_get_raw_by_name(format->world_datas, id); + if (raw == NULL) { + iron_log("World data '%s' not found!", id); + return NULL; + } + + raw->_ = gc_alloc(sizeof(world_data_runtime_t)); + raw->_->radiance_mipmaps = any_array_create(0); + + raw->_->irradiance = world_data_set_irradiance(raw); + if (raw->radiance != NULL) { + raw->_->radiance = data_get_image(raw->radiance); + while (raw->_->radiance_mipmaps->length < raw->radiance_mipmaps) { + any_array_push(raw->_->radiance_mipmaps, NULL); + } + i32 dot = string_last_index_of(raw->radiance, "."); + char *ext = substring(raw->radiance, dot, string_length(raw->radiance)); + char *base = substring(raw->radiance, 0, dot); + + for (i32 i = 0; i < raw->radiance_mipmaps; ++i) { + char *mip_name = string_join(string_join(base, string_join("_", i32_to_string(i))), ext); + gpu_texture_t *mipimg = data_get_image(mip_name); + raw->_->radiance_mipmaps->buffer[i] = mipimg; + } + } + + return raw; +} + +world_data_t *world_data_get_raw_by_name(any_array_t *datas, char *name) { + if (strcmp(name, "") == 0) { + return (world_data_t *)datas->buffer[0]; + } + for (i32 i = 0; i < datas->length; ++i) { + world_data_t *d = (world_data_t *)datas->buffer[i]; + if (strcmp(d->name, name) == 0) { + return d; + } + } + return NULL; +} + +f32_array_t *world_data_get_empty_irradiance() { + if (_world_data_empty_irr == NULL) { + _world_data_empty_irr = f32_array_create(28); + gc_root(_world_data_empty_irr); + for (i32 i = 0; i < _world_data_empty_irr->length; ++i) { + _world_data_empty_irr->buffer[i] = 0.0; + } + } + return _world_data_empty_irr; +} + +f32_array_t *world_data_set_irradiance(world_data_t *raw) { + if (raw->irradiance == NULL) { + return world_data_get_empty_irradiance(); + } + buffer_t *b = data_get_blob(string_join(raw->irradiance, ".arm")); + irradiance_t *irradiance_parsed = (irradiance_t *)armpack_decode(b); + f32_array_t *irr = f32_array_create(28); // Align to mult of 4 - 27->28 + for (i32 i = 0; i < 27; ++i) { + irr->buffer[i] = irradiance_parsed->irradiance->buffer[i]; + } + return irr; +} + +void world_data_load_envmap(world_data_t *raw) { + if (raw->envmap != NULL) { + raw->_->envmap = data_get_image(raw->envmap); + } +} + +// ███╗ ███╗ █████╗ ████████╗███████╗██████╗ ██╗ █████╗ ██╗ ██████╗ █████╗ ████████╗ █████╗ +// ████╗ ████║██╔══██╗╚══██╔══╝██╔════╝██╔══██╗██║██╔══██╗██║ ██╔══██╗██╔══██╗╚══██╔══╝██╔══██╗ +// ██╔████╔██║███████║ ██║ █████╗ ██████╔╝██║███████║██║ ██║ ██║███████║ ██║ ███████║ +// ██║╚██╔╝██║██╔══██║ ██║ ██╔══╝ ██╔══██╗██║██╔══██║██║ ██║ ██║██╔══██║ ██║ ██╔══██║ +// ██║ ╚═╝ ██║██║ ██║ ██║ ███████╗██║ ██║██║██║ ██║███████╗ ██████╔╝██║ ██║ ██║ ██║ ██║ +// ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝╚═╝╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ + +i32 _material_data_uid_counter = 0; + +material_data_t *material_data_create(material_data_t *raw, char *file) { + raw->_ = gc_alloc(sizeof(material_data_runtime_t)); + raw->_->uid = (float)(++_material_data_uid_counter); // Start from 1 + + any_array_t *ref = string_split(raw->shader, "/"); + char *object_file = ""; + char *data_ref = ""; + if (ref->length == 2) { // File reference + object_file = (char *)ref->buffer[0]; + data_ref = (char *)ref->buffer[1]; + } + else { // Local data + object_file = file; + data_ref = raw->shader; + } + + raw->_->shader = data_get_shader(object_file, data_ref); + for (i32 i = 0; i < (i32)raw->contexts->length; ++i) { + material_context_t *c = (material_context_t *)raw->contexts->buffer[i]; + material_context_load(c); + } + return raw; +} + +material_data_t *material_data_parse(char *file, char *name) { + _scene_t *format = data_get_scene_raw(file); + material_data_t *raw = material_data_get_raw_by_name(format->material_datas, name); + if (raw == NULL) { + iron_log("Material data '%s' not found!", name); + return NULL; + } + return material_data_create(raw, file); +} + +material_data_t *material_data_get_raw_by_name(any_array_t *datas, char *name) { + if (strcmp(name, "") == 0) { + return (material_data_t *)datas->buffer[0]; + } + for (i32 i = 0; i < (i32)datas->length; ++i) { + material_data_t *d = (material_data_t *)datas->buffer[i]; + if (strcmp(d->name, name) == 0) { + return d; + } + } + return NULL; +} + +material_context_t *material_data_get_context(material_data_t *raw, char *name) { + for (i32 i = 0; i < (i32)raw->contexts->length; ++i) { + material_context_t *c = (material_context_t *)raw->contexts->buffer[i]; + if (strcmp(c->name, name) == 0) { + return c; + } + } + return NULL; +} + +void material_context_load(material_context_t *raw) { + raw->_ = gc_alloc(sizeof(material_context_runtime_t)); + if (raw->bind_textures != NULL && raw->bind_textures->length > 0) { + raw->_->textures = any_array_create(0); + for (i32 i = 0; i < (i32)raw->bind_textures->length; ++i) { + bind_tex_t *tex = (bind_tex_t *)raw->bind_textures->buffer[i]; + if (strcmp(tex->file, "") == 0) { // Empty texture + continue; + } + gpu_texture_t *image = data_get_image(tex->file); + any_array_push(raw->_->textures, image); + } + } +} + +// ███████╗██╗ ██╗ █████╗ ██████╗ ███████╗██████╗ ██████╗ █████╗ ████████╗ █████╗ +// ██╔════╝██║ ██║██╔══██╗██╔══██╗██╔════╝██╔══██╗ ██╔══██╗██╔══██╗╚══██╔══╝██╔══██╗ +// ███████╗███████║███████║██║ ██║█████╗ ██████╔╝ ██║ ██║███████║ ██║ ███████║ +// ╚════██║██╔══██║██╔══██║██║ ██║██╔══╝ ██╔══██╗ ██║ ██║██╔══██║ ██║ ██╔══██║ +// ███████║██║ ██║██║ ██║██████╔╝███████╗██║ ██║ ██████╔╝██║ ██║ ██║ ██║ ██║ +// ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝╚═════╝ ╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ + +shader_data_t *shader_data_create(shader_data_t *raw) { + for (i32 i = 0; i < raw->contexts->length; ++i) { + shader_context_t *c = (shader_context_t *)raw->contexts->buffer[i]; + shader_context_load(c); + } + return raw; +} + +char *shader_data_ext() { +#ifdef IRON_VULKAN + return ".spirv"; +#elif defined(IRON_METAL) + return ".metal"; +#elif defined(IRON_WASM) + return ".wgsl"; +#else + return ".d3d11"; +#endif +} + +shader_data_t *shader_data_parse(char *file, char *name) { + _scene_t *format = data_get_scene_raw(file); + shader_data_t *raw = shader_data_get_raw_by_name(format->shader_datas, name); + if (raw == NULL) { + iron_log("Shader data '%s' not found!", name); + return NULL; + } + return shader_data_create(raw); +} + +shader_data_t *shader_data_get_raw_by_name(_shader_data_t_array_t *datas, char *name) { + if (strcmp(name, "") == 0) { + return (shader_data_t *)datas->buffer[0]; + } + for (i32 i = 0; i < datas->length; ++i) { + shader_data_t *d = (shader_data_t *)datas->buffer[i]; + if (strcmp(d->name, name) == 0) { + return d; + } + } + return NULL; +} + +void shader_data_delete(shader_data_t *raw) { + for (i32 i = 0; i < raw->contexts->length; ++i) { + shader_context_t *c = (shader_context_t *)raw->contexts->buffer[i]; + shader_context_delete(c); + } +} + +shader_context_t *shader_data_get_context(shader_data_t *raw, char *name) { + for (i32 i = 0; i < raw->contexts->length; ++i) { + shader_context_t *c = (shader_context_t *)raw->contexts->buffer[i]; + if (strcmp(c->name, name) == 0) { + return c; + } + } + return NULL; +} + +void shader_context_load(shader_context_t *raw) { + if (raw->_ == NULL) { + raw->_ = gc_alloc(sizeof(shader_context_runtime_t)); + } + shader_context_parse_vertex_struct(raw); + shader_context_compile(raw); +} + +void shader_context_compile(shader_context_t *raw) { + if (raw->_->pipe != NULL) { + gpu_delete_pipeline(raw->_->pipe); + } + raw->_->pipe = gpu_create_pipeline(); + raw->_->constants = i32_array_create(0); + raw->_->tex_units = i32_array_create(0); + raw->_->pipe->input_layout = &raw->_->structure; + raw->_->pipe->depth_write = raw->depth_write; + raw->_->pipe->depth_mode = shader_context_get_compare_mode(raw->compare_mode); + raw->_->pipe->cull_mode = shader_context_get_cull_mode(raw->cull_mode); + if (raw->blend_source != NULL) { + raw->_->pipe->blend_source = shader_context_get_blend_fac(raw->blend_source); + } + if (raw->blend_destination != NULL) { + raw->_->pipe->blend_destination = shader_context_get_blend_fac(raw->blend_destination); + } + if (raw->alpha_blend_source != NULL) { + raw->_->pipe->alpha_blend_source = shader_context_get_blend_fac(raw->alpha_blend_source); + } + if (raw->alpha_blend_destination != NULL) { + raw->_->pipe->alpha_blend_destination = shader_context_get_blend_fac(raw->alpha_blend_destination); + } + if (raw->color_writes_red != NULL) { + for (i32 i = 0; i < raw->color_writes_red->length; ++i) { + raw->_->pipe->color_write_mask_red[i] = (bool)(intptr_t)raw->color_writes_red->buffer[i]; + } + } + if (raw->color_writes_green != NULL) { + for (i32 i = 0; i < raw->color_writes_green->length; ++i) { + raw->_->pipe->color_write_mask_green[i] = (bool)(intptr_t)raw->color_writes_green->buffer[i]; + } + } + if (raw->color_writes_blue != NULL) { + for (i32 i = 0; i < raw->color_writes_blue->length; ++i) { + raw->_->pipe->color_write_mask_blue[i] = (bool)(intptr_t)raw->color_writes_blue->buffer[i]; + } + } + if (raw->color_writes_alpha != NULL) { + for (i32 i = 0; i < raw->color_writes_alpha->length; ++i) { + raw->_->pipe->color_write_mask_alpha[i] = (bool)(intptr_t)raw->color_writes_alpha->buffer[i]; + } + } + if (raw->color_attachments != NULL) { + raw->_->pipe->color_attachment_count = raw->color_attachments->length; + for (i32 i = 0; i < raw->color_attachments->length; ++i) { + raw->_->pipe->color_attachment[i] = shader_context_get_tex_format((char *)raw->color_attachments->buffer[i]); + } + } + if (raw->depth_attachment != NULL) { + raw->_->pipe->depth_attachment_bits = strcmp(raw->depth_attachment, "NONE") == 0 ? 0 : 32; + } + + if (raw->shader_from_source) { + raw->_->pipe->vertex_shader = gpu_create_shader_from_source(raw->vertex_shader, raw->_->vertex_shader_size, GPU_SHADER_TYPE_VERTEX); + raw->_->pipe->fragment_shader = gpu_create_shader_from_source(raw->fragment_shader, raw->_->fragment_shader_size, GPU_SHADER_TYPE_FRAGMENT); + if (raw->_->pipe->vertex_shader == NULL || raw->_->pipe->fragment_shader == NULL) { + return; + } + } + else { +#ifdef arm_embed + raw->_->pipe->fragment_shader = sys_get_shader(raw->fragment_shader); + raw->_->pipe->vertex_shader = sys_get_shader(raw->vertex_shader); +#else + buffer_t *vs_buffer = data_get_blob(string_join(raw->vertex_shader, shader_data_ext())); + raw->_->pipe->vertex_shader = gpu_create_shader(vs_buffer, GPU_SHADER_TYPE_VERTEX); + buffer_t *fs_buffer = data_get_blob(string_join(raw->fragment_shader, shader_data_ext())); + raw->_->pipe->fragment_shader = gpu_create_shader(fs_buffer, GPU_SHADER_TYPE_FRAGMENT); +#endif + } + + shader_context_finish_compile(raw); +} + +i32 shader_context_type_size(char *t) { +#ifdef IRON_DIRECT3D12 + if (strcmp(t, "int") == 0) + return 4; + if (strcmp(t, "float") == 0) + return 4; + if (strcmp(t, "vec2") == 0) + return 8; + if (strcmp(t, "vec3") == 0) + return 12; + if (strcmp(t, "vec4") == 0) + return 16; + if (strcmp(t, "mat3") == 0) + return 48; + if (strcmp(t, "mat4") == 0) + return 64; + if (strcmp(t, "float2") == 0) + return 8; + if (strcmp(t, "float3") == 0) + return 12; + if (strcmp(t, "float4") == 0) + return 16; + if (strcmp(t, "float3x3") == 0) + return 48; + if (strcmp(t, "float4x4") == 0) + return 64; +#else + if (strcmp(t, "int") == 0) + return 4; + if (strcmp(t, "float") == 0) + return 4; + if (strcmp(t, "vec2") == 0) + return 8; + if (strcmp(t, "vec3") == 0) + return 16; + if (strcmp(t, "vec4") == 0) + return 16; + if (strcmp(t, "mat3") == 0) + return 48; + if (strcmp(t, "mat4") == 0) + return 64; + if (strcmp(t, "float2") == 0) + return 8; + if (strcmp(t, "float3") == 0) + return 16; + if (strcmp(t, "float4") == 0) + return 16; + if (strcmp(t, "float3x3") == 0) + return 48; + if (strcmp(t, "float4x4") == 0) + return 64; +#endif + return 0; +} + +i32 shader_context_type_pad(i32 offset, i32 size) { +#ifdef IRON_DIRECT3D12 + i32 r = offset % 16; + if (r == 0) { + return 0; + } + if (size >= 16 || r + size > 16) { + return 16 - r; + } + return 0; +#else + if (size > 16) { + size = 16; + } + return (size - (offset % size)) % size; +#endif +} + +void shader_context_finish_compile(shader_context_t *raw) { + gpu_pipeline_compile(raw->_->pipe); + if (raw->constants != NULL) { + i32 offset = 0; + for (i32 i = 0; i < raw->constants->length; ++i) { + shader_const_t *c = (shader_const_t *)raw->constants->buffer[i]; + i32 size = shader_context_type_size(c->type); + offset += shader_context_type_pad(offset, size); + shader_context_add_const(raw, offset); + offset += size; + } + } + if (raw->texture_units != NULL) { + for (i32 i = 0; i < raw->texture_units->length; ++i) { + shader_context_add_tex(raw, i); + } + } +} + +gpu_vertex_data_t shader_context_parse_data(char *data) { + if (strcmp(data, "float1") == 0) + return GPU_VERTEX_DATA_F32_1X; + if (strcmp(data, "float2") == 0) + return GPU_VERTEX_DATA_F32_2X; + if (strcmp(data, "float3") == 0) + return GPU_VERTEX_DATA_F32_3X; + if (strcmp(data, "float4") == 0) + return GPU_VERTEX_DATA_F32_4X; + if (strcmp(data, "short2norm") == 0) + return GPU_VERTEX_DATA_I16_2X_NORM; + if (strcmp(data, "short4norm") == 0) + return GPU_VERTEX_DATA_I16_4X_NORM; + return GPU_VERTEX_DATA_F32_1X; +} + +void shader_context_parse_vertex_struct(shader_context_t *raw) { + raw->_->structure = (gpu_vertex_structure_t){0}; + for (i32 i = 0; i < raw->vertex_elements->length; ++i) { + vertex_element_t *elem = (vertex_element_t *)raw->vertex_elements->buffer[i]; + gpu_vertex_structure_add(&raw->_->structure, elem->name, shader_context_parse_data(elem->data)); + } +} + +void shader_context_delete(shader_context_t *raw) { + if (raw->_->pipe->fragment_shader != NULL) { + gpu_shader_destroy(raw->_->pipe->fragment_shader); + } + if (raw->_->pipe->vertex_shader != NULL) { + gpu_shader_destroy(raw->_->pipe->vertex_shader); + } + gpu_delete_pipeline(raw->_->pipe); +} + +gpu_compare_mode_t shader_context_get_compare_mode(char *s) { + if (strcmp(s, "always") == 0) + return GPU_COMPARE_MODE_ALWAYS; + if (strcmp(s, "never") == 0) + return GPU_COMPARE_MODE_NEVER; + if (strcmp(s, "equal") == 0) + return GPU_COMPARE_MODE_EQUAL; + return GPU_COMPARE_MODE_LESS; +} + +gpu_cull_mode_t shader_context_get_cull_mode(char *s) { + if (strcmp(s, "none") == 0) + return GPU_CULL_MODE_NONE; + if (strcmp(s, "clockwise") == 0) + return GPU_CULL_MODE_CLOCKWISE; + return GPU_CULL_MODE_COUNTER_CLOCKWISE; +} + +gpu_blend_t shader_context_get_blend_fac(char *s) { + if (strcmp(s, "blend_one") == 0) + return GPU_BLEND_ONE; + if (strcmp(s, "blend_zero") == 0) + return GPU_BLEND_ZERO; + if (strcmp(s, "source_alpha") == 0) + return GPU_BLEND_SOURCE_ALPHA; + if (strcmp(s, "destination_alpha") == 0) + return GPU_BLEND_DEST_ALPHA; + if (strcmp(s, "inverse_source_alpha") == 0) + return GPU_BLEND_INV_SOURCE_ALPHA; + if (strcmp(s, "inverse_destination_alpha") == 0) + return GPU_BLEND_INV_DEST_ALPHA; + return GPU_BLEND_ONE; +} + +gpu_texture_format_t shader_context_get_tex_format(char *s) { + if (strcmp(s, "RGBA32") == 0) + return GPU_TEXTURE_FORMAT_RGBA32; + if (strcmp(s, "RGBA64") == 0) + return GPU_TEXTURE_FORMAT_RGBA64; + if (strcmp(s, "RGBA128") == 0) + return GPU_TEXTURE_FORMAT_RGBA128; + if (strcmp(s, "R32") == 0) + return GPU_TEXTURE_FORMAT_R32; + if (strcmp(s, "R16") == 0) + return GPU_TEXTURE_FORMAT_R16; + if (strcmp(s, "R8") == 0) + return GPU_TEXTURE_FORMAT_R8; + return GPU_TEXTURE_FORMAT_RGBA32; +} + +void shader_context_add_const(shader_context_t *raw, i32 offset) { + i32_array_push(raw->_->constants, offset); +} + +void shader_context_add_tex(shader_context_t *raw, i32 i) { + i32_array_push(raw->_->tex_units, i); +} + +// ███╗ ███╗███████╗███████╗██╗ ██╗ ██████╗ █████╗ ████████╗ █████╗ +// ████╗ ████║██╔════╝██╔════╝██║ ██║ ██╔══██╗██╔══██╗╚══██╔══╝██╔══██╗ +// ██╔████╔██║█████╗ ███████╗███████║ ██║ ██║███████║ ██║ ███████║ +// ██║╚██╔╝██║██╔══╝ ╚════██║██╔══██║ ██║ ██║██╔══██║ ██║ ██╔══██║ +// ██║ ╚═╝ ██║███████╗███████║██║ ██║ ██████╔╝██║ ██║ ██║ ██║ ██║ +// ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ + +mesh_data_t *mesh_data_parse(char *name, char *id) { + _scene_t *format = data_get_scene_raw(name); + mesh_data_t *raw = mesh_data_get_raw_by_name(format->mesh_datas, id); + if (raw == NULL) { + iron_log("Mesh data '%s' not found!", id); + return NULL; + } + return mesh_data_create(raw); +} + +mesh_data_t *mesh_data_get_raw_by_name(any_array_t *datas, char *name) { + if (string_equals(name, "")) { + return (mesh_data_t *)datas->buffer[0]; + } + for (i32 i = 0; i < datas->length; ++i) { + mesh_data_t *d = (mesh_data_t *)datas->buffer[i]; + if (string_equals(d->name, name)) { + return d; + } + } + return NULL; +} + +mesh_data_t *mesh_data_create(mesh_data_t *raw) { + raw->_ = gc_alloc(sizeof(mesh_data_runtime_t)); + if (raw->scale_pos == 0.0) { + raw->scale_pos = 1.0; + } + if (raw->scale_tex == 0.0) { + raw->scale_tex = 1.0; + } + raw->_->structure = mesh_data_get_vertex_struct(raw->vertex_arrays); + mesh_data_build(raw); + return raw; +} + +gpu_vertex_structure_t mesh_data_get_vertex_struct(any_array_t *vertex_arrays) { + gpu_vertex_structure_t structure = {0}; + for (i32 i = 0; i < vertex_arrays->length; ++i) { + vertex_array_t *va = (vertex_array_t *)vertex_arrays->buffer[i]; + gpu_vertex_structure_add(&structure, va->attrib, mesh_data_get_vertex_data(va->data)); + } + return structure; +} + +gpu_vertex_data_t mesh_data_get_vertex_data(char *data) { + if (string_equals(data, "short4norm")) { + return GPU_VERTEX_DATA_I16_4X_NORM; + } + return GPU_VERTEX_DATA_I16_2X_NORM; // short2norm +} + +i32 mesh_data_get_vertex_size(char *vertex_data) { + if (string_equals(vertex_data, "short4norm")) { + return 4; + } + return 2; // short2norm +} + +void mesh_data_build_vertices(gpu_buffer_t *vertex_buffer, any_array_t *vertex_arrays) { + vertex_array_t *va0 = (vertex_array_t *)vertex_arrays->buffer[0]; + buffer_t *vertices = gpu_lock_vertex_buffer(vertex_buffer); + i32 size = mesh_data_get_vertex_size(va0->data); + i32 num_verts = va0->values->length / size; + i32 di = -1; + for (i32 i = 0; i < num_verts; ++i) { + for (i32 va = 0; va < vertex_arrays->length; ++va) { + vertex_array_t *v = (vertex_array_t *)vertex_arrays->buffer[va]; + i32 l = mesh_data_get_vertex_size(v->data); + for (i32 o = 0; o < l; ++o) { + buffer_set_i16(vertices, ++di * 2, v->values->buffer[i * l + o]); + } + } + } + gpu_vertex_buffer_unlock(vertex_buffer); +} + +void mesh_data_build_indices(gpu_buffer_t *index_buffer, u32_array_t *index_array) { + u32_array_t *ia = gpu_lock_index_buffer(index_buffer); + memcpy(ia->buffer, index_array->buffer, ia->length * 4); + gpu_index_buffer_unlock(index_buffer); +} + +vertex_array_t *mesh_data_get_vertex_array(mesh_data_t *raw, char *name) { + for (i32 i = 0; i < raw->vertex_arrays->length; ++i) { + vertex_array_t *va = (vertex_array_t *)raw->vertex_arrays->buffer[i]; + if (string_equals(va->attrib, name)) { + return va; + } + } + return NULL; +} + +void mesh_data_build(mesh_data_t *raw) { + vertex_array_t *positions = mesh_data_get_vertex_array(raw, "pos"); + i32 size = mesh_data_get_vertex_size(positions->data); + raw->_->vertex_buffer = gpu_create_vertex_buffer(positions->values->length / size, &raw->_->structure); + mesh_data_build_vertices(raw->_->vertex_buffer, raw->vertex_arrays); + raw->_->index_buffer = gpu_create_index_buffer(raw->index_array->length); + mesh_data_build_indices(raw->_->index_buffer, raw->index_array); +} + +vec4_t mesh_data_calculate_aabb(mesh_data_t *raw) { + vec4_t aabb_min = vec4_create(-0.01, -0.01, -0.01, 0.0); + vec4_t aabb_max = vec4_create(0.01, 0.01, 0.01, 0.0); + vec4_t aabb = vec4_create(0.0, 0.0, 0.0, 0.0); + i32 i = 0; + vertex_array_t *positions = mesh_data_get_vertex_array(raw, "pos"); + while (i < positions->values->length) { + if (positions->values->buffer[i] > aabb_max.x) { + aabb_max.x = positions->values->buffer[i]; + } + if (positions->values->buffer[i + 1] > aabb_max.y) { + aabb_max.y = positions->values->buffer[i + 1]; + } + if (positions->values->buffer[i + 2] > aabb_max.z) { + aabb_max.z = positions->values->buffer[i + 2]; + } + if (positions->values->buffer[i] < aabb_min.x) { + aabb_min.x = positions->values->buffer[i]; + } + if (positions->values->buffer[i + 1] < aabb_min.y) { + aabb_min.y = positions->values->buffer[i + 1]; + } + if (positions->values->buffer[i + 2] < aabb_min.z) { + aabb_min.z = positions->values->buffer[i + 2]; + } + i += 4; + } + aabb.x = (fabsf(aabb_min.x) + fabsf(aabb_max.x)) / 32767 * raw->scale_pos; + aabb.y = (fabsf(aabb_min.y) + fabsf(aabb_max.y)) / 32767 * raw->scale_pos; + aabb.z = (fabsf(aabb_min.z) + fabsf(aabb_max.z)) / 32767 * raw->scale_pos; + return aabb; +} + +void mesh_data_delete(mesh_data_t *raw) { + gpu_delete_buffer(raw->_->vertex_buffer); + gpu_delete_buffer(raw->_->index_buffer); +} diff --git a/base/sources/engine.h b/base/sources/engine.h index e69de29b..89745ef3 100644 --- a/base/sources/engine.h +++ b/base/sources/engine.h @@ -0,0 +1,343 @@ +#pragma once + +#include "iron_armpack.h" +#include "iron_array.h" +#include "iron_gc.h" +#include "iron_gpu.h" +#include "iron_mat4.h" +#include "iron_quat.h" +#include "iron_string.h" +#include "iron_system.h" +#include "iron_vec4.h" +#include +#include + +typedef struct object object_t; + +typedef struct _obj_t_array { + struct obj **buffer; + int length; + int capacity; +} _obj_t_array_t; +typedef struct _vertex_array_t_array { + struct vertex_array **buffer; + int length; + int capacity; +} _vertex_array_t_array_t; +typedef struct _shader_data_t_array { + struct shader_data **buffer; + int length; + int capacity; +} _shader_data_t_array_t; +typedef struct _tex_unit_t_array { + struct tex_unit **buffer; + int length; + int capacity; +} _tex_unit_t_array_t; +typedef struct _shader_const_t_array { + struct shader_const **buffer; + int length; + int capacity; +} _shader_const_t_array_t; +typedef struct _vertex_element_t_array { + struct vertex_element **buffer; + int length; + int capacity; +} _vertex_element_t_array_t; +typedef struct _bind_const_t_array { + struct bind_const **buffer; + int length; + int capacity; +} _bind_const_t_array_t; +typedef struct _bind_tex_t_array { + struct bind_tex **buffer; + int length; + int capacity; +} _bind_tex_t_array_t; +typedef struct _material_context_t_array { + struct material_context **buffer; + int length; + int capacity; +} _material_context_t_array_t; + +typedef struct obj_runtime { + void *_gc; // Link to armpack_decode result +} obj_runtime_t; + +typedef struct obj { + char *name; + char *type; // object, mesh_object, camera_object + char *data_ref; + f32_array_t *transform; + f32_array_t *dimensions; + bool visible; + bool spawn; // Auto add object when creating scene + void *anim; // TODO: deprecated + char *material_ref; + _obj_t_array_t *children; + obj_runtime_t *_; +} obj_t; + +typedef struct vertex_array { + char *attrib; + char *data; // short4norm, short2norm + i16_array_t *values; +} vertex_array_t; + +typedef struct mesh_data_runtime { + char *handle; + gpu_buffer_t *vertex_buffer; + gpu_buffer_t *index_buffer; + gpu_vertex_structure_t structure; +} mesh_data_runtime_t; + +typedef struct mesh_data { + char *name; + float scale_pos; + float scale_tex; + _vertex_array_t_array_t *vertex_arrays; + u32_array_t *index_array; + mesh_data_runtime_t *_; +} mesh_data_t; + +typedef struct camera_data { + char *name; + float near_plane; + float far_plane; + float fov; + float aspect; + bool frustum_culling; + f32_array_t *ortho; // Indicates ortho camera, left, right, bottom, top +} camera_data_t; + +typedef struct world_data_runtime { + gpu_texture_t *envmap; + gpu_texture_t *radiance; + any_array_t *radiance_mipmaps; // gpu_texture_t[] + f32_array_t *irradiance; +} world_data_runtime_t; + +typedef struct world_data { + char *name; + i32 color; + float strength; + char *irradiance; // Reference to irradiance_t blob + char *radiance; + i32 radiance_mipmaps; + char *envmap; + world_data_runtime_t *_; +} world_data_t; + +typedef struct irradiance { + f32_array_t *irradiance; // Spherical harmonics, bands 0,1,2 +} irradiance_t; + +typedef struct _scene { + char *name; + any_array_t *objects; + any_array_t *mesh_datas; + any_array_t *camera_datas; + char *camera_ref; + any_array_t *material_datas; + any_array_t *shader_datas; + any_array_t *world_datas; + char *world_ref; + any_array_t *speaker_datas; // TODO: deprecated + char_ptr_array_t *embedded_datas; // Preload for this scene, images only for now +} _scene_t; + +typedef struct shader_context_runtime { + gpu_pipeline_t *pipe; + i32_array_t *constants; + i32_array_t *tex_units; + gpu_vertex_structure_t structure; + i32 vertex_shader_size; + i32 fragment_shader_size; +} shader_context_runtime_t; + +typedef struct vertex_element { + char *name; + char *data; // "short4norm", "short2norm" +} vertex_element_t; + +typedef struct shader_const { + char *name; + char *type; + char *link; +} shader_const_t; + +typedef struct tex_unit { + char *name; + char *link; +} tex_unit_t; + +typedef struct shader_context { + char *name; + bool depth_write; + char *compare_mode; + char *cull_mode; + char *vertex_shader; + char *fragment_shader; + bool shader_from_source; + char *blend_source; + char *blend_destination; + char *alpha_blend_source; + char *alpha_blend_destination; + u8_array_t *color_writes_red; // Per target masks + u8_array_t *color_writes_green; + u8_array_t *color_writes_blue; + u8_array_t *color_writes_alpha; + char_ptr_array_t *color_attachments; // RGBA32, RGBA64, R8 + char *depth_attachment; // D32 + _vertex_element_t_array_t *vertex_elements; // vertex_element_t[] + _shader_const_t_array_t *constants; // shader_const_t[] + _tex_unit_t_array_t *texture_units; // tex_unit_t[] + shader_context_runtime_t *_; +} shader_context_t; + +typedef struct shader_data { + char *name; + any_array_t *contexts; // shader_context_t[] +} shader_data_t; + +typedef struct bind_const { + char *name; + f32_array_t *vec; // bool (vec[0] > 0) | i32 | f32 | vec2 | vec3 | vec4 +} bind_const_t; + +typedef struct bind_tex { + char *name; + char *file; +} bind_tex_t; + +typedef struct material_context_runtime { + any_array_t *textures; // gpu_texture_t[] +} material_context_runtime_t; + +typedef struct material_context { + char *name; + _bind_const_t_array_t *bind_constants; // bind_const_t[] + _bind_tex_t_array_t *bind_textures; // bind_tex_t[] + material_context_runtime_t *_; +} material_context_t; + +typedef struct material_data_runtime { + float uid; + shader_data_t *shader; +} material_data_runtime_t; + +typedef struct material_data { + char *name; + char *shader; + _material_context_t_array_t *contexts; // material_context_t[] + material_data_runtime_t *_; +} material_data_t; + +typedef struct transform { + mat4_t world; + mat4_t local; + vec4_t loc; + quat_t rot; + vec4_t scale; + float scale_world; + mat4_t world_unpack; + bool dirty; + object_t *object; + vec4_t dim; + float radius; +} transform_t; + +typedef struct object { + i32 uid; + float urandom; + obj_t *raw; + char *name; + transform_t *transform; + object_t *parent; + any_array_t *children; + bool visible; + bool culled; + bool is_empty; + void *ext; + char *ext_type; +} object_t; + +extern i32 _object_uid_counter; + +object_t *object_create(bool is_empty); +void object_set_parent(object_t *raw, object_t *parent_object); +void object_remove_super(object_t *raw); +void object_remove(object_t *raw); +object_t *object_get_child(object_t *raw, char *name); + +transform_t *transform_create(object_t *object); +void transform_reset(transform_t *raw); +void transform_update(transform_t *raw); +void transform_build_matrix(transform_t *raw); +void transform_set_matrix(transform_t *raw, mat4_t mat); +void transform_decompose(transform_t *raw); +void transform_rotate(transform_t *raw, vec4_t axis, float f); +void transform_move(transform_t *raw, vec4_t axis, float f); +void transform_compute_radius(transform_t *raw); +void transform_compute_dim(transform_t *raw); +vec4_t transform_look(transform_t *raw); +vec4_t transform_right(transform_t *raw); +vec4_t transform_up(transform_t *raw); +float transform_world_x(transform_t *raw); +float transform_world_y(transform_t *raw); +float transform_world_z(transform_t *raw); + +camera_data_t *camera_data_parse(char *name, char *id); +camera_data_t *camera_data_get_raw_by_name(any_array_t *datas, char *name); + +extern f32_array_t *_world_data_empty_irr; +world_data_t *world_data_parse(char *name, char *id); +world_data_t *world_data_get_raw_by_name(any_array_t *datas, char *name); +f32_array_t *world_data_get_empty_irradiance(); +f32_array_t *world_data_set_irradiance(world_data_t *raw); +void world_data_load_envmap(world_data_t *raw); + +gpu_texture_t *data_get_image(char *file); +buffer_t *data_get_blob(char *file); + +extern i32 _material_data_uid_counter; +material_data_t *material_data_create(material_data_t *raw, char *file); +material_data_t *material_data_parse(char *file, char *name); +material_data_t *material_data_get_raw_by_name(any_array_t *datas, char *name); +material_context_t *material_data_get_context(material_data_t *raw, char *name); +void material_context_load(material_context_t *raw); +shader_data_t *data_get_shader(char *file, char *name); + +shader_data_t *shader_data_create(shader_data_t *raw); +char *shader_data_ext(); +shader_data_t *shader_data_parse(char *file, char *name); +shader_data_t *shader_data_get_raw_by_name(_shader_data_t_array_t *datas, char *name); +void shader_data_delete(shader_data_t *raw); +shader_context_t *shader_data_get_context(shader_data_t *raw, char *name); +void shader_context_load(shader_context_t *raw); +void shader_context_compile(shader_context_t *raw); +i32 shader_context_type_size(char *t); +i32 shader_context_type_pad(i32 offset, i32 size); +void shader_context_finish_compile(shader_context_t *raw); +gpu_vertex_data_t shader_context_parse_data(char *data); +void shader_context_parse_vertex_struct(shader_context_t *raw); +void shader_context_delete(shader_context_t *raw); +gpu_compare_mode_t shader_context_get_compare_mode(char *s); +gpu_cull_mode_t shader_context_get_cull_mode(char *s); +gpu_blend_t shader_context_get_blend_fac(char *s); +gpu_texture_format_t shader_context_get_tex_format(char *s); +void shader_context_add_const(shader_context_t *raw, i32 offset); +void shader_context_add_tex(shader_context_t *raw, i32 i); + +mesh_data_t *mesh_data_parse(char *name, char *id); +mesh_data_t *mesh_data_get_raw_by_name(any_array_t *datas, char *name); +mesh_data_t *mesh_data_create(mesh_data_t *raw); +gpu_vertex_structure_t mesh_data_get_vertex_struct(any_array_t *vertex_arrays); +gpu_vertex_data_t mesh_data_get_vertex_data(char *data); +i32 mesh_data_get_vertex_size(char *vertex_data); +void mesh_data_build_vertices(gpu_buffer_t *vertex_buffer, any_array_t *vertex_arrays); +void mesh_data_build_indices(gpu_buffer_t *index_buffer, u32_array_t *index_array); +vertex_array_t *mesh_data_get_vertex_array(mesh_data_t *raw, char *name); +void mesh_data_build(mesh_data_t *raw); +vec4_t mesh_data_calculate_aabb(mesh_data_t *raw); +void mesh_data_delete(mesh_data_t *raw); diff --git a/base/sources/engine.ts b/base/sources/engine.ts index e69de29b..5bd14f28 100644 --- a/base/sources/engine.ts +++ b/base/sources/engine.ts @@ -0,0 +1,105 @@ + +declare type transform_t = { + world?: mat4_t; + local?: mat4_t; + loc?: vec4_t; + rot?: quat_t; + scale?: vec4_t; + scale_world?: f32; + world_unpack?: mat4_t; + dirty?: bool; + object?: object_t; + dim?: vec4_t; + radius?: f32; +}; + +declare function transform_create(object: object_t): transform_t; +declare function transform_reset(raw: transform_t); +declare function transform_update(raw: transform_t); +declare function transform_build_matrix(raw: transform_t); +declare function transform_set_matrix(raw: transform_t, mat: mat4_t); +declare function transform_decompose(raw: transform_t); +declare function transform_rotate(raw: transform_t, axis: vec4_t, f: f32); +declare function transform_move(raw: transform_t, axis: vec4_t, f: f32 = 1.0); +declare function transform_compute_radius(raw: transform_t); +declare function transform_compute_dim(raw: transform_t); +declare function transform_look(raw: transform_t): vec4_t; +declare function transform_right(raw: transform_t): vec4_t; +declare function transform_up(raw: transform_t): vec4_t; +declare function transform_world_x(raw: transform_t): f32; +declare function transform_world_y(raw: transform_t): f32; +declare function transform_world_z(raw: transform_t): f32; + +declare type object_t = { + uid?: i32; + urandom?: f32; + raw?: obj_t; + name?: string; + transform?: transform_t; + parent?: object_t; + children?: object_t[]; + visible?: bool; // Skip render, keep updating + culled?: bool; // base_object_t was culled last frame + is_empty?: bool; + ext?: any; // mesh_object_t | camera_object_t + ext_type?: string; +}; + +declare let _object_uid_counter: i32; + +declare function object_create(is_empty: bool = true): object_t; +declare function object_set_parent(raw: object_t, parent_object: object_t); +declare function object_remove_super(raw: object_t); +declare function object_remove(raw: object_t); +declare function object_get_child(raw: object_t, name: string): object_t; + +declare function mesh_data_parse(name: string, id: string): mesh_data_t; +declare function mesh_data_get_raw_by_name(datas: mesh_data_t[], name: string): mesh_data_t; +declare function mesh_data_create(raw: mesh_data_t): mesh_data_t; +declare function mesh_data_get_vertex_struct(vertex_arrays: vertex_array_t[]): gpu_vertex_structure_t; +declare function mesh_data_get_vertex_data(data: string): gpu_vertex_data_t; +declare function mesh_data_get_vertex_size(vertex_data: string): i32; +declare function mesh_data_build_vertices(vertex_buffer: gpu_buffer_t, vertex_arrays: vertex_array_t[]); +declare function mesh_data_build_indices(index_buffer: gpu_buffer_t, index_array: u32_array_t); +declare function mesh_data_get_vertex_array(raw: mesh_data_t, name: string): vertex_array_t; +declare function mesh_data_build(raw: mesh_data_t); +declare function mesh_data_calculate_aabb(raw: mesh_data_t): vec4_t; +declare function mesh_data_delete(raw: mesh_data_t); + +declare function camera_data_parse(name: string, id: string): camera_data_t; +declare function camera_data_get_raw_by_name(datas: camera_data_t[], name: string): camera_data_t; + +declare let _world_data_empty_irr: f32_array_t = null; +declare function world_data_parse(name: string, id: string): world_data_t; +declare function world_data_get_raw_by_name(datas: world_data_t[], name: string): world_data_t; +declare function world_data_get_empty_irradiance(): f32_array_t; +declare function world_data_set_irradiance(raw: world_data_t): f32_array_t; +declare function world_data_load_envmap(raw: world_data_t); + +declare function shader_data_create(raw: shader_data_t): shader_data_t; +declare function shader_data_ext(): string; +declare function shader_data_parse(file: string, name: string): shader_data_t; +declare function shader_data_get_raw_by_name(datas: shader_data_t[], name: string): shader_data_t; +declare function shader_data_delete(raw: shader_data_t); +declare function shader_data_get_context(raw: shader_data_t, name: string): shader_context_t; +declare function shader_context_load(raw: shader_context_t); +declare function shader_context_compile(raw: shader_context_t); +declare function shader_context_type_size(t: string): i32; +declare function shader_context_type_pad(offset: i32, size: i32): i32; +declare function shader_context_finish_compile(raw: shader_context_t); +declare function shader_context_parse_data(data: string): gpu_vertex_data_t; +declare function shader_context_parse_vertex_struct(raw: shader_context_t); +declare function shader_context_delete(raw: shader_context_t); +declare function shader_context_get_compare_mode(s: string): gpu_compare_mode_t; +declare function shader_context_get_cull_mode(s: string): gpu_cull_mode_t; +declare function shader_context_get_blend_fac(s: string): gpu_blend_t; +declare function shader_context_get_tex_format(s: string): gpu_texture_format_t; +declare function shader_context_add_const(raw: shader_context_t, offset: i32); +declare function shader_context_add_tex(raw: shader_context_t, i: i32); + +declare let _material_data_uid_counter: i32; +declare function material_data_create(raw: material_data_t, file: string = ""): material_data_t; +declare function material_data_parse(file: string, name: string): material_data_t; +declare function material_data_get_raw_by_name(datas: material_data_t[], name: string): material_data_t; +declare function material_data_get_context(raw: material_data_t, name: string): material_context_t; +declare function material_context_load(raw: material_context_t); diff --git a/base/sources/iron.h b/base/sources/iron.h index 252b197b..c5112501 100644 --- a/base/sources/iron.h +++ b/base/sources/iron.h @@ -210,6 +210,7 @@ string_t *iron_get_arg(i32 index) { #include "iron_input.h" #include "iron_tilesheet.h" #include "iron_sys.h" +#include "engine.h" #include "kong/dir.h" #include #include diff --git a/base/sources/ts/iron.ts b/base/sources/iron.ts similarity index 100% rename from base/sources/ts/iron.ts rename to base/sources/iron.ts diff --git a/base/sources/ts/camera_data.ts b/base/sources/ts/camera_data.ts deleted file mode 100644 index 30a18374..00000000 --- a/base/sources/ts/camera_data.ts +++ /dev/null @@ -1,21 +0,0 @@ - -function camera_data_parse(name: string, id: string): camera_data_t { - let format: scene_t = data_get_scene_raw(name); - let raw: camera_data_t = camera_data_get_raw_by_name(format.camera_datas, id); - if (raw == null) { - iron_log("Camera data '" + id + "' not found!"); - } - return raw; -} - -function camera_data_get_raw_by_name(datas: camera_data_t[], name: string): camera_data_t { - if (name == "") { - return datas[0]; - } - for (let i: i32 = 0; i < datas.length; ++i) { - if (datas[i].name == name) { - return datas[i]; - } - } - return null; -} diff --git a/base/sources/ts/material_data.ts b/base/sources/ts/material_data.ts deleted file mode 100644 index 1e073907..00000000 --- a/base/sources/ts/material_data.ts +++ /dev/null @@ -1,74 +0,0 @@ - -let _material_data_uid_counter: i32 = 0; - -function material_data_create(raw: material_data_t, file: string = ""): material_data_t { - raw._ = {}; - raw._.uid = ++_material_data_uid_counter; // Start from 1 - - let ref: string[] = string_split(raw.shader, "/"); - let object_file: string = ""; - let data_ref: string = ""; - if (ref.length == 2) { // File reference - object_file = ref[0]; - data_ref = ref[1]; - } - else { // Local data - object_file = file; - data_ref = raw.shader; - } - - let b: shader_data_t = data_get_shader(object_file, data_ref); - raw._.shader = b; - for (let i: i32 = 0; i < raw.contexts.length; ++i) { - let c: material_context_t = raw.contexts[i]; - material_context_load(c); - } - return raw; -} - -function material_data_parse(file: string, name: string): material_data_t { - let format: scene_t = data_get_scene_raw(file); - let raw: material_data_t = material_data_get_raw_by_name(format.material_datas, name); - if (raw == null) { - iron_log("Material data '" + name + "' not found!"); - return null; - } - return material_data_create(raw, file); -} - -function material_data_get_raw_by_name(datas: material_data_t[], name: string): material_data_t { - if (name == "") { - return datas[0]; - } - for (let i: i32 = 0; i < datas.length; ++i) { - if (datas[i].name == name) { - return datas[i]; - } - } - return null; -} - -function material_data_get_context(raw: material_data_t, name: string): material_context_t { - for (let i: i32 = 0; i < raw.contexts.length; ++i) { - let c: material_context_t = raw.contexts[i]; - if (c.name == name) { - return c; - } - } - return null; -} - -function material_context_load(raw: material_context_t) { - raw._ = {}; - if (raw.bind_textures != null && raw.bind_textures.length > 0) { - raw._.textures = []; - for (let i: i32 = 0; i < raw.bind_textures.length; ++i) { - let tex: bind_tex_t = raw.bind_textures[i]; - if (tex.file == "") { // Empty texture - continue; - } - let image: gpu_texture_t = data_get_image(tex.file); - array_push(raw._.textures, image); - } - } -} diff --git a/base/sources/ts/mesh_data.ts b/base/sources/ts/mesh_data.ts deleted file mode 100644 index f76bf712..00000000 --- a/base/sources/ts/mesh_data.ts +++ /dev/null @@ -1,138 +0,0 @@ - -function mesh_data_parse(name: string, id: string): mesh_data_t { - let format: scene_t = data_get_scene_raw(name); - let raw: mesh_data_t = mesh_data_get_raw_by_name(format.mesh_datas, id); - if (raw == null) { - iron_log("Mesh data '" + id + "' not found!"); - return null; - } - - let data: mesh_data_t = mesh_data_create(raw); - return data; -} - -function mesh_data_get_raw_by_name(datas: mesh_data_t[], name: string): mesh_data_t { - if (name == "") { - return datas[0]; - } - for (let i: i32 = 0; i < datas.length; ++i) { - if (datas[i].name == name) { - return datas[i]; - } - } - return null; -} - -function mesh_data_create(raw: mesh_data_t): mesh_data_t { - raw._ = {}; - if (raw.scale_pos == 0.0) { - raw.scale_pos = 1.0; - } - if (raw.scale_tex == 0.0) { - raw.scale_tex = 1.0; - } - raw._.structure = mesh_data_get_vertex_struct(raw.vertex_arrays); - mesh_data_build(raw); - return raw; -} - -function mesh_data_get_vertex_struct(vertex_arrays: vertex_array_t[]): gpu_vertex_structure_t { - let structure: gpu_vertex_structure_t = {}; - for (let i: i32 = 0; i < vertex_arrays.length; ++i) { - gpu_vertex_struct_add(structure, vertex_arrays[i].attrib, mesh_data_get_vertex_data(vertex_arrays[i].data)); - } - return structure; -} - -function mesh_data_get_vertex_data(data: string): gpu_vertex_data_t { - if (data == "short4norm") { - return gpu_vertex_data_t.I16_4X_NORM; - } - return gpu_vertex_data_t.I16_2X_NORM; // short2norm -} - -function mesh_data_get_vertex_size(vertex_data: string): i32 { - if (vertex_data == "short4norm") { - return 4; - } - return 2; // short2norm -} - -function mesh_data_build_vertices(vertex_buffer: gpu_buffer_t, vertex_arrays: vertex_array_t[]) { - let vertices: buffer_t = gpu_lock_vertex_buffer(vertex_buffer); - let size: i32 = mesh_data_get_vertex_size(vertex_arrays[0].data); - let num_verts: i32 = vertex_arrays[0].values.length / size; - let di: i32 = -1; - for (let i: i32 = 0; i < num_verts; ++i) { - for (let va: i32 = 0; va < vertex_arrays.length; ++va) { - let l: i32 = mesh_data_get_vertex_size(vertex_arrays[va].data); - for (let o: i32 = 0; o < l; ++o) { - buffer_set_i16(vertices, ++di * 2, vertex_arrays[va].values[i * l + o]); - } - } - } - gpu_vertex_buffer_unlock(vertex_buffer); -} - -function mesh_data_build_indices(index_buffer: gpu_buffer_t, index_array: u32_array_t) { - let ia: u32_array_t = gpu_lock_index_buffer(index_buffer); - memcpy(ia.buffer, index_array.buffer, ia.length * 4); - gpu_index_buffer_unlock(index_buffer); -} - -function mesh_data_get_vertex_array(raw: mesh_data_t, name: string): vertex_array_t { - for (let i: i32 = 0; i < raw.vertex_arrays.length; ++i) { - if (raw.vertex_arrays[i].attrib == name) { - return raw.vertex_arrays[i]; - } - } - return null; -} - -function mesh_data_build(raw: mesh_data_t) { - let positions: vertex_array_t = mesh_data_get_vertex_array(raw, "pos"); - let size: i32 = mesh_data_get_vertex_size(positions.data); - raw._.vertex_buffer = gpu_create_vertex_buffer(math_floor(positions.values.length / size), raw._.structure); - mesh_data_build_vertices(raw._.vertex_buffer, raw.vertex_arrays); - - raw._.index_buffer = gpu_create_index_buffer(raw.index_array.length); - mesh_data_build_indices(raw._.index_buffer, raw.index_array); -} - -function mesh_data_calculate_aabb(raw: mesh_data_t): vec4_t { - let aabb_min: vec4_t = vec4_create(-0.01, -0.01, -0.01); - let aabb_max: vec4_t = vec4_create(0.01, 0.01, 0.01); - let aabb: vec4_t = vec4_create(); - let i: i32 = 0; - let positions: vertex_array_t = mesh_data_get_vertex_array(raw, "pos"); - while (i < positions.values.length) { - if (positions.values[i] > aabb_max.x) { - aabb_max.x = positions.values[i]; - } - if (positions.values[i + 1] > aabb_max.y) { - aabb_max.y = positions.values[i + 1]; - } - if (positions.values[i + 2] > aabb_max.z) { - aabb_max.z = positions.values[i + 2]; - } - if (positions.values[i] < aabb_min.x) { - aabb_min.x = positions.values[i]; - } - if (positions.values[i + 1] < aabb_min.y) { - aabb_min.y = positions.values[i + 1]; - } - if (positions.values[i + 2] < aabb_min.z) { - aabb_min.z = positions.values[i + 2]; - } - i += 4; - } - aabb.x = (math_abs(aabb_min.x) + math_abs(aabb_max.x)) / 32767 * raw.scale_pos; - aabb.y = (math_abs(aabb_min.y) + math_abs(aabb_max.y)) / 32767 * raw.scale_pos; - aabb.z = (math_abs(aabb_min.z) + math_abs(aabb_max.z)) / 32767 * raw.scale_pos; - return aabb; -} - -function mesh_data_delete(raw: mesh_data_t) { - gpu_delete_buffer(raw._.vertex_buffer); - gpu_delete_buffer(raw._.index_buffer); -} diff --git a/base/sources/ts/object.ts b/base/sources/ts/object.ts deleted file mode 100644 index ed31f4bd..00000000 --- a/base/sources/ts/object.ts +++ /dev/null @@ -1,91 +0,0 @@ - -type object_t = { - uid?: i32; - urandom?: f32; - raw?: obj_t; - name?: string; - transform?: transform_t; - parent?: object_t; - children?: object_t[]; - visible?: bool; // Skip render, keep updating - culled?: bool; // base_object_t was culled last frame - is_empty?: bool; - ext?: any; // mesh_object_t | camera_object_t - ext_type?: string; -}; - -let _object_uid_counter: i32 = 0; - -function object_create(is_empty: bool = true): object_t { - let raw: object_t = {}; - raw.name = ""; - raw.children = []; - raw.visible = true; - raw.culled = false; - raw.uid = _object_uid_counter++; - raw.transform = transform_create(raw); - raw.is_empty = is_empty; - if (raw.is_empty) { - array_push(scene_empties, raw); - } - return raw; -} - -function object_set_parent(raw: object_t, parent_object: object_t) { - if (parent_object == raw || parent_object == raw.parent) { - return; - } - - if (raw.parent != null) { - array_remove(raw.parent.children, raw); - raw.parent = null; // rebuild matrix without a parent - transform_build_matrix(raw.transform); - } - - if (parent_object == null) { - parent_object = _scene_scene_parent; - } - raw.parent = parent_object; - array_push(raw.parent.children, raw); -} - -function object_remove_super(raw: object_t) { - if (raw.is_empty) { - array_remove(scene_empties, raw); - } - while (raw.children.length > 0) { - object_remove(raw.children[0]); - } - if (raw.parent != null) { - array_remove(raw.parent.children, raw); - raw.parent = null; - } -} - -function object_remove(raw: object_t) { - if (raw.ext_type == "mesh_object_t") { - mesh_object_remove(raw.ext); - } - else if (raw.ext_type == "camera_object_t") { - camera_object_remove(raw.ext); - } - else { - object_remove_super(raw); - } -} - -function object_get_child(raw: object_t, name: string): object_t { - if (raw.name == name) { - return raw; - } - else { - for (let i: i32 = 0; i < raw.children.length; ++i) { - let c: object_t = raw.children[i]; - let r: object_t = object_get_child(c, name); - if (r != null) { - return r; - } - } - } - return null; -} diff --git a/base/sources/ts/scene.ts b/base/sources/ts/scene.ts index 14ae3295..6306c500 100644 --- a/base/sources/ts/scene.ts +++ b/base/sources/ts/scene.ts @@ -278,7 +278,7 @@ type scene_t = { embedded_datas?: string[]; // Preload for this scene, images only for now }; -type mesh_data_t = { +declare type mesh_data_t = { name?: string; scale_pos?: f32; // Unpack pos from (-1,1) coords scale_tex?: f32; // Unpack tex from (-1,1) coords @@ -287,20 +287,20 @@ type mesh_data_t = { _?: mesh_data_runtime_t; }; -type mesh_data_runtime_t = { +declare type mesh_data_runtime_t = { handle?: string; // Handle used to retrieve this object in Data vertex_buffer?: gpu_buffer_t; index_buffer?: gpu_buffer_t; structure?: gpu_vertex_structure_t; }; -type vertex_array_t = { +declare type vertex_array_t = { attrib?: string; data?: string; // short4norm, short2norm values?: i16_array_t; }; -type camera_data_t = { +declare type camera_data_t = { name?: string; near_plane?: f32; far_plane?: f32; @@ -310,45 +310,45 @@ type camera_data_t = { ortho?: f32_array_t; // Indicates ortho camera, left, right, bottom, top }; -type material_data_t = { +declare type material_data_t = { name?: string; shader?: string; contexts?: material_context_t[]; _?: material_data_runtime_t; }; -type material_data_runtime_t = { +declare type material_data_runtime_t = { uid?: f32; shader?: shader_data_t; }; -type material_context_t = { +declare type material_context_t = { name?: string; bind_constants?: bind_const_t[]; bind_textures?: bind_tex_t[]; _?: material_context_runtime_t; }; -type material_context_runtime_t = { +declare type material_context_runtime_t = { textures?: gpu_texture_t[]; }; -type bind_const_t = { +declare type bind_const_t = { name?: string; vec?: f32_array_t; // bool (vec[0] > 0) | i32 | f32 | vec2 | vec3 | vec4 }; -type bind_tex_t = { +declare type bind_tex_t = { name?: string; file?: string; }; -type shader_data_t = { +declare type shader_data_t = { name?: string; contexts?: shader_context_t[]; }; -type shader_context_t = { +declare type shader_context_t = { name?: string; depth_write?: bool; compare_mode?: string; @@ -372,7 +372,7 @@ type shader_context_t = { _?: shader_context_runtime_t; }; -type shader_context_runtime_t = { +declare type shader_context_runtime_t = { pipe?: gpu_pipeline_t; constants?: i32[]; tex_units?: i32[]; @@ -381,23 +381,23 @@ type shader_context_runtime_t = { fragment_shader_size?: i32; }; -type vertex_element_t = { +declare type vertex_element_t = { name?: string; data?: string; // "short4norm", "short2norm" }; -type shader_const_t = { +declare type shader_const_t = { name?: string; type?: string; link?: string; }; -type tex_unit_t = { +declare type tex_unit_t = { name?: string; link?: string; }; -type world_data_t = { +declare type world_data_t = { name?: string; color?: i32; strength?: f32; @@ -408,18 +408,18 @@ type world_data_t = { _?: world_data_runtime_t; }; -type world_data_runtime_t = { +declare type world_data_runtime_t = { envmap?: gpu_texture_t; radiance?: gpu_texture_t; radiance_mipmaps?: gpu_texture_t[]; irradiance?: f32_array_t; }; -type irradiance_t = { +declare type irradiance_t = { irradiance?: f32_array_t; // Blob with spherical harmonics, bands 0,1,2 }; -type obj_t = { +declare type obj_t = { name?: string; type?: string; // object, mesh_object, camera_object data_ref?: string; @@ -433,6 +433,6 @@ type obj_t = { _?: obj_runtime_t; }; -type obj_runtime_t = { +declare type obj_runtime_t = { _gc?: scene_t; // Link to armpack_decode result }; diff --git a/base/sources/ts/shader_data.ts b/base/sources/ts/shader_data.ts deleted file mode 100644 index be5bc819..00000000 --- a/base/sources/ts/shader_data.ts +++ /dev/null @@ -1,361 +0,0 @@ - -function shader_data_create(raw: shader_data_t): shader_data_t { - for (let i: i32 = 0; i < raw.contexts.length; ++i) { - let c: shader_context_t = raw.contexts[i]; - shader_context_load(c); - } - return raw; -} - -function shader_data_ext(): string { - /// if arm_vulkan - return ".spirv"; - /// elseif arm_metal - return ".metal"; - /// elseif arm_webgpu - return ".wgsl"; - /// else - return ".d3d11"; - /// end -} - -function shader_data_parse(file: string, name: string): shader_data_t { - let format: scene_t = data_get_scene_raw(file); - let raw: shader_data_t = shader_data_get_raw_by_name(format.shader_datas, name); - if (raw == null) { - iron_log("Shader data '" + name + "' not found!"); - return null; - } - return shader_data_create(raw); -} - -function shader_data_get_raw_by_name(datas: shader_data_t[], name: string): shader_data_t { - if (name == "") { - return datas[0]; - } - for (let i: i32 = 0; i < datas.length; ++i) { - if (datas[i].name == name) { - return datas[i]; - } - } - return null; -} - -function shader_data_delete(raw: shader_data_t) { - for (let i: i32 = 0; i < raw.contexts.length; ++i) { - let c: shader_context_t = raw.contexts[i]; - shader_context_delete(c); - } -} - -function shader_data_get_context(raw: shader_data_t, name: string): shader_context_t { - for (let i: i32 = 0; i < raw.contexts.length; ++i) { - let c: shader_context_t = raw.contexts[i]; - if (c.name == name) { - return c; - } - } - return null; -} - -function shader_context_load(raw: shader_context_t) { - if (raw._ == null) { - raw._ = {}; - } - shader_context_parse_vertex_struct(raw); - shader_context_compile(raw); -} - -function shader_context_compile(raw: shader_context_t) { - if (raw._.pipe != null) { - gpu_delete_pipeline(raw._.pipe); - } - raw._.pipe = gpu_create_pipeline(); - raw._.constants = []; - raw._.tex_units = []; - raw._.pipe.input_layout = raw._.structure; - raw._.pipe.depth_write = raw.depth_write; - raw._.pipe.depth_mode = shader_context_get_compare_mode(raw.compare_mode); - raw._.pipe.cull_mode = shader_context_get_cull_mode(raw.cull_mode); - if (raw.blend_source != null) { - raw._.pipe.blend_source = shader_context_get_blend_fac(raw.blend_source); - } - if (raw.blend_destination != null) { - raw._.pipe.blend_destination = shader_context_get_blend_fac(raw.blend_destination); - } - if (raw.alpha_blend_source != null) { - raw._.pipe.alpha_blend_source = shader_context_get_blend_fac(raw.alpha_blend_source); - } - if (raw.alpha_blend_destination != null) { - raw._.pipe.alpha_blend_destination = shader_context_get_blend_fac(raw.alpha_blend_destination); - } - if (raw.color_writes_red != null) { - for (let i: i32 = 0; i < raw.color_writes_red.length; ++i) { - ARRAY_ACCESS(raw._.pipe.color_write_mask_red, i) = raw.color_writes_red[i]; - } - } - if (raw.color_writes_green != null) { - for (let i: i32 = 0; i < raw.color_writes_green.length; ++i) { - ARRAY_ACCESS(raw._.pipe.color_write_mask_green, i) = raw.color_writes_green[i]; - } - } - if (raw.color_writes_blue != null) { - for (let i: i32 = 0; i < raw.color_writes_blue.length; ++i) { - ARRAY_ACCESS(raw._.pipe.color_write_mask_blue, i) = raw.color_writes_blue[i]; - } - } - if (raw.color_writes_alpha != null) { - for (let i: i32 = 0; i < raw.color_writes_alpha.length; ++i) { - ARRAY_ACCESS(raw._.pipe.color_write_mask_alpha, i) = raw.color_writes_alpha[i]; - } - } - if (raw.color_attachments != null) { - raw._.pipe.color_attachment_count = raw.color_attachments.length; - for (let i: i32 = 0; i < raw.color_attachments.length; ++i) { - ARRAY_ACCESS(raw._.pipe.color_attachment, i) = shader_context_get_tex_format(raw.color_attachments[i]); - } - } - if (raw.depth_attachment != null) { - raw._.pipe.depth_attachment_bits = raw.depth_attachment == "NONE" ? 0 : 32; - } - - if (raw.shader_from_source) { - raw._.pipe.vertex_shader = gpu_create_shader_from_source(raw.vertex_shader, raw._.vertex_shader_size, gpu_shader_type_t.VERTEX); - raw._.pipe.fragment_shader = gpu_create_shader_from_source(raw.fragment_shader, raw._.fragment_shader_size, gpu_shader_type_t.FRAGMENT); - if (raw._.pipe.vertex_shader == null || raw._.pipe.fragment_shader == null) { - return; - } - } - else { - /// if arm_embed - - raw._.pipe.fragment_shader = sys_get_shader(raw.fragment_shader); - raw._.pipe.vertex_shader = sys_get_shader(raw.vertex_shader); - - /// else // Load shaders manually - - let vs_buffer: buffer_t = data_get_blob(raw.vertex_shader + shader_data_ext()); - raw._.pipe.vertex_shader = gpu_create_shader(vs_buffer, gpu_shader_type_t.VERTEX); - let fs_buffer: buffer_t = data_get_blob(raw.fragment_shader + shader_data_ext()); - raw._.pipe.fragment_shader = gpu_create_shader(fs_buffer, gpu_shader_type_t.FRAGMENT); - /// end - } - - shader_context_finish_compile(raw); -} - -/// if arm_direct3d12 - -function shader_context_type_size(t: string): i32 { - if (t == "int") - return 4; - if (t == "float") - return 4; - if (t == "vec2") - return 8; - if (t == "vec3") - return 12; - if (t == "vec4") - return 16; - if (t == "mat3") - return 48; - if (t == "mat4") - return 64; - if (t == "float2") - return 8; - if (t == "float3") - return 12; - if (t == "float4") - return 16; - if (t == "float3x3") - return 48; - if (t == "float4x4") - return 64; - return 0; -} - -function shader_context_type_pad(offset: i32, size: i32): i32 { - let r: i32 = offset % 16; - if (r == 0) { - return 0; - } - if (size >= 16 || r + size > 16) { - return 16 - r; - } - return 0; -} - -/// else - -function shader_context_type_size(t: string): i32 { - if (t == "int") - return 4; - if (t == "float") - return 4; - if (t == "vec2") - return 8; - if (t == "vec3") - return 16; - if (t == "vec4") - return 16; - if (t == "mat3") - return 48; - if (t == "mat4") - return 64; - if (t == "float2") - return 8; - if (t == "float3") - return 16; - if (t == "float4") - return 16; - if (t == "float3x3") - return 48; - if (t == "float4x4") - return 64; - return 0; -} - -function shader_context_type_pad(offset: i32, size: i32): i32 { - if (size > 16) { - size = 16; - } - return (size - (offset % size)) % size; -} - -/// end - -function shader_context_finish_compile(raw: shader_context_t) { - gpu_pipeline_compile(raw._.pipe); - if (raw.constants != null) { - let offset: i32 = 0; - for (let i: i32 = 0; i < raw.constants.length; ++i) { - let c: shader_const_t = raw.constants[i]; - let size: i32 = shader_context_type_size(c.type); - offset += shader_context_type_pad(offset, size); - shader_context_add_const(raw, offset); - offset += size; - } - } - if (raw.texture_units != null) { - for (let i: i32 = 0; i < raw.texture_units.length; ++i) { - shader_context_add_tex(raw, i); - } - } -} - -function shader_context_parse_data(data: string): gpu_vertex_data_t { - if (data == "float1") { - return gpu_vertex_data_t.F32_1X; - } - else if (data == "float2") { - return gpu_vertex_data_t.F32_2X; - } - else if (data == "float3") { - return gpu_vertex_data_t.F32_3X; - } - else if (data == "float4") { - return gpu_vertex_data_t.F32_4X; - } - else if (data == "short2norm") { - return gpu_vertex_data_t.I16_2X_NORM; - } - else if (data == "short4norm") { - return gpu_vertex_data_t.I16_4X_NORM; - } - return gpu_vertex_data_t.F32_1X; -} - -function shader_context_parse_vertex_struct(raw: shader_context_t) { - let structure: gpu_vertex_structure_t = {}; - raw._.structure = structure; - - for (let i: i32 = 0; i < raw.vertex_elements.length; ++i) { - let elem: vertex_element_t = raw.vertex_elements[i]; - gpu_vertex_struct_add(raw._.structure, elem.name, shader_context_parse_data(elem.data)); - } -} - -function shader_context_delete(raw: shader_context_t) { - if (raw._.pipe.fragment_shader != null) { - gpu_shader_destroy(raw._.pipe.fragment_shader); - } - if (raw._.pipe.vertex_shader != null) { - gpu_shader_destroy(raw._.pipe.vertex_shader); - } - gpu_delete_pipeline(raw._.pipe); -} - -function shader_context_get_compare_mode(s: string): gpu_compare_mode_t { - if (s == "always") { - return gpu_compare_mode_t.ALWAYS; - } - if (s == "never") { - return gpu_compare_mode_t.NEVER; - } - if (s == "equal") { - return gpu_compare_mode_t.EQUAL; - } - return gpu_compare_mode_t.LESS; -} - -function shader_context_get_cull_mode(s: string): gpu_cull_mode_t { - if (s == "none") { - return gpu_cull_mode_t.NONE; - } - if (s == "clockwise") { - return gpu_cull_mode_t.CLOCKWISE; - } - return gpu_cull_mode_t.COUNTER_CLOCKWISE; -} - -function shader_context_get_blend_fac(s: string): gpu_blend_t { - if (s == "blend_one") { - return gpu_blend_t.ONE; - } - if (s == "blend_zero") { - return gpu_blend_t.ZERO; - } - if (s == "source_alpha") { - return gpu_blend_t.SOURCE_ALPHA; - } - if (s == "destination_alpha") { - return gpu_blend_t.DEST_ALPHA; - } - if (s == "inverse_source_alpha") { - return gpu_blend_t.INV_SOURCE_ALPHA; - } - if (s == "inverse_destination_alpha") { - return gpu_blend_t.INV_DEST_ALPHA; - } - return gpu_blend_t.ONE; -} - -function shader_context_get_tex_format(s: string): gpu_texture_format_t { - if (s == "RGBA32") { - return gpu_texture_format_t.RGBA32; - } - if (s == "RGBA64") { - return gpu_texture_format_t.RGBA64; - } - if (s == "RGBA128") { - return gpu_texture_format_t.RGBA128; - } - if (s == "R32") { - return gpu_texture_format_t.R32; - } - if (s == "R16") { - return gpu_texture_format_t.R16; - } - if (s == "R8") { - return gpu_texture_format_t.R8; - } - return gpu_texture_format_t.RGBA32; -} - -function shader_context_add_const(raw: shader_context_t, offset: i32) { - array_push(raw._.constants, offset); -} - -function shader_context_add_tex(raw: shader_context_t, i: i32) { - array_push(raw._.tex_units, i); -} diff --git a/base/sources/ts/transform.ts b/base/sources/ts/transform.ts deleted file mode 100644 index 2507b4d2..00000000 --- a/base/sources/ts/transform.ts +++ /dev/null @@ -1,148 +0,0 @@ - -type transform_t = { - world?: mat4_t; - local?: mat4_t; - loc?: vec4_t; - rot?: quat_t; - scale?: vec4_t; - scale_world?: f32; - world_unpack?: mat4_t; - dirty?: bool; - object?: object_t; - dim?: vec4_t; - radius?: f32; -}; - -function transform_create(object: object_t): transform_t { - let raw: transform_t = {}; - raw.scale_world = 1.0; - raw.object = object; - transform_reset(raw); - return raw; -} - -function transform_reset(raw: transform_t) { - raw.world = mat4_identity(); - raw.world_unpack = mat4_identity(); - raw.local = mat4_identity(); - raw.loc = vec4_create(); - raw.rot = quat_create(); - raw.scale = vec4_create(1.0, 1.0, 1.0); - raw.dim = vec4_create(2.0, 2.0, 2.0); - raw.radius = 1.0; - raw.dirty = true; -} - -function transform_update(raw: transform_t) { - if (raw.dirty) { - transform_build_matrix(raw); - } -} - -function transform_build_matrix(raw: transform_t) { - raw.local = mat4_compose(raw.loc, raw.rot, raw.scale); - - if (raw.object.parent != null) { - raw.world = mat4_mult_mat3x4(raw.local, raw.object.parent.transform.world); - } - else { - raw.world = mat4_clone(raw.local); - } - - raw.world_unpack = mat4_clone(raw.world); - if (raw.scale_world != 1.0) { - raw.world_unpack.m00 *= raw.scale_world; - raw.world_unpack.m01 *= raw.scale_world; - raw.world_unpack.m02 *= raw.scale_world; - raw.world_unpack.m03 *= raw.scale_world; - raw.world_unpack.m10 *= raw.scale_world; - raw.world_unpack.m11 *= raw.scale_world; - raw.world_unpack.m12 *= raw.scale_world; - raw.world_unpack.m13 *= raw.scale_world; - raw.world_unpack.m20 *= raw.scale_world; - raw.world_unpack.m21 *= raw.scale_world; - raw.world_unpack.m22 *= raw.scale_world; - raw.world_unpack.m23 *= raw.scale_world; - } - - transform_compute_dim(raw); - - // Update children - for (let i: i32 = 0; i < raw.object.children.length; ++i) { - let n: object_t = raw.object.children[i]; - transform_build_matrix(n.transform); - } - - raw.dirty = false; -} - -function transform_set_matrix(raw: transform_t, mat: mat4_t) { - raw.local = mat4_clone(mat); - transform_decompose(raw); - transform_build_matrix(raw); -} - -function transform_decompose(raw: transform_t) { - let dec: mat4_decomposed_t = mat4_decompose(raw.local); - raw.loc = dec.loc; - raw.rot = dec.rot; - raw.scale = dec.scl; -} - -function transform_rotate(raw: transform_t, axis: vec4_t, f: f32) { - let q: quat_t = quat_from_axis_angle(axis, f); - raw.rot = quat_mult(q, raw.rot); - transform_build_matrix(raw); -} - -function transform_move(raw: transform_t, axis: vec4_t, f: f32 = 1.0) { - raw.loc = vec4_fadd(raw.loc, axis.x * f, axis.y * f, axis.z * f); - transform_build_matrix(raw); -} - -function transform_compute_radius(raw: transform_t) { - raw.radius = math_sqrt(raw.dim.x * raw.dim.x + raw.dim.y * raw.dim.y + raw.dim.z * raw.dim.z); -} - -function transform_compute_dim(raw: transform_t) { - if (raw.object.raw == null && raw.object.ext_type == "mesh_object_t") { - let mo: mesh_object_t = raw.object.ext; - let aabb: vec4_t = mesh_data_calculate_aabb(mo.data); - let o: object_t = raw.object; - o.raw = {}; - o.raw.dimensions = f32_array_create_xyz(aabb.x, aabb.y, aabb.z); - } - - if (raw.object.raw == null || raw.object.raw.dimensions == null) { - raw.dim = vec4_create(2 * raw.scale.x, 2 * raw.scale.y, 2 * raw.scale.z); - } - else { - let d: f32_array_t = raw.object.raw.dimensions; - raw.dim = vec4_create(d[0] * raw.scale.x, d[1] * raw.scale.y, d[2] * raw.scale.z); - } - transform_compute_radius(raw); -} - -function transform_look(raw: transform_t): vec4_t { - return mat4_look(raw.world); -} - -function transform_right(raw: transform_t): vec4_t { - return mat4_right(raw.world); -} - -function transform_up(raw: transform_t): vec4_t { - return mat4_up(raw.world); -} - -function transform_world_x(raw: transform_t): f32 { - return raw.world.m30; -} - -function transform_world_y(raw: transform_t): f32 { - return raw.world.m31; -} - -function transform_world_z(raw: transform_t): f32 { - return raw.world.m32; -} diff --git a/base/sources/ts/world_data.ts b/base/sources/ts/world_data.ts deleted file mode 100644 index f33ffe70..00000000 --- a/base/sources/ts/world_data.ts +++ /dev/null @@ -1,78 +0,0 @@ - -let _world_data_empty_irr: f32_array_t = null; - -function world_data_parse(name: string, id: string): world_data_t { - let format: scene_t = data_get_scene_raw(name); - let raw: world_data_t = world_data_get_raw_by_name(format.world_datas, id); - if (raw == null) { - iron_log("World data '" + id + "' not found!"); - return null; - } - - raw._ = {}; - raw._.radiance_mipmaps = []; - - let irr: f32_array_t = world_data_set_irradiance(raw); - raw._.irradiance = irr; - if (raw.radiance != null) { - let rad: gpu_texture_t = data_get_image(raw.radiance); - raw._.radiance = rad; - while (raw._.radiance_mipmaps.length < raw.radiance_mipmaps) { - array_push(raw._.radiance_mipmaps, null); - } - let dot: i32 = string_last_index_of(raw.radiance, "."); - let ext: string = substring(raw.radiance, dot, raw.radiance.length); - let base: string = substring(raw.radiance, 0, dot); - - for (let i: i32 = 0; i < raw.radiance_mipmaps; ++i) { - let mipimg: gpu_texture_t = data_get_image(base + "_" + i + ext); - raw._.radiance_mipmaps[i] = mipimg; - } - } - - return raw; -} - -function world_data_get_raw_by_name(datas: world_data_t[], name: string): world_data_t { - if (name == "") { - return datas[0]; - } - for (let i: i32 = 0; i < datas.length; ++i) { - if (datas[i].name == name) { - return datas[i]; - } - } - return null; -} - -function world_data_get_empty_irradiance(): f32_array_t { - if (_world_data_empty_irr == null) { - _world_data_empty_irr = f32_array_create(28); - for (let i: i32 = 0; i < _world_data_empty_irr.length; ++i) { - _world_data_empty_irr[i] = 0.0; - } - } - return _world_data_empty_irr; -} - -function world_data_set_irradiance(raw: world_data_t): f32_array_t { - if (raw.irradiance == null) { - return world_data_get_empty_irradiance(); - } - else { - let b: buffer_t = data_get_blob(raw.irradiance + ".arm"); - let irradiance_parsed: irradiance_t = armpack_decode(b); - let irr: f32_array_t = f32_array_create(28); // Align to mult of 4 - 27->28 - for (let i: i32 = 0; i < 27; ++i) { - irr[i] = irradiance_parsed.irradiance[i]; - } - return irr; - } -} - -function world_data_load_envmap(raw: world_data_t) { - if (raw.envmap != null) { - let image: gpu_texture_t = data_get_image(raw.envmap); - raw._.envmap = image; - } -}