From 5ee444465ed1fc9e2712837eae06d189d8f1f7ea Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Sat, 4 Nov 2023 03:01:30 +0000 Subject: [PATCH] cgltf glb texture pulling --- scripts/editor.js | 2 +- source/engine/2dphysics.c | 2 +- source/engine/3d/model.c | 28 ++++++++----- source/engine/input.c | 2 +- source/engine/{ffi.c => jsffi.c} | 27 +++++++++++- source/engine/{ffi.h => jsffi.h} | 0 source/engine/script.c | 2 +- source/engine/texture.c | 71 ++++++++++++++++++++++++++++++++ source/engine/texture.h | 1 + source/engine/window.c | 2 +- source/engine/yugine.c | 2 +- 11 files changed, 121 insertions(+), 18 deletions(-) rename source/engine/{ffi.c => jsffi.c} (98%) rename source/engine/{ffi.h => jsffi.h} (100%) diff --git a/scripts/editor.js b/scripts/editor.js index cf3689f..981a3f4 100644 --- a/scripts/editor.js +++ b/scripts/editor.js @@ -1503,7 +1503,7 @@ var replpanel = Object.copy(inputpanel, { return [ Mum.text({str:log, anchor:[0,0], offset:[0,-300].sub(this.scrolloffset), selectable: true}), - Mum.text({str:this.value,color:Color.green, offset:[0,-290], caret: this.caret}) + Mum.text({str:this.value,color:Color.purple, offset:[0,-290], caret: this.caret}) ]; }, prevmark:-1, diff --git a/source/engine/2dphysics.c b/source/engine/2dphysics.c index 6e33aa5..8279f6b 100644 --- a/source/engine/2dphysics.c +++ b/source/engine/2dphysics.c @@ -14,7 +14,7 @@ #include "tinyspline.h" -#include "ffi.h" +#include "jsffi.h" #include "script.h" #include "log.h" diff --git a/source/engine/3d/model.c b/source/engine/3d/model.c index e29395c..231cd6c 100644 --- a/source/engine/3d/model.c +++ b/source/engine/3d/model.c @@ -115,7 +115,7 @@ uint32_t pack_int10_n2(float *norm) } struct model *MakeModel(const char *path) { - YughWarn("Making the model from %s.", path); + YughInfo("Making the model from %s.", path); cgltf_options options = {0}; cgltf_data *data = NULL; cgltf_result result = cgltf_parse_file(&options, path, &data); @@ -134,7 +134,7 @@ struct model *MakeModel(const char *path) { struct model *model = calloc(1, sizeof(*model)); /* TODO: Optimize by grouping by material. One material per draw. */ - YughWarn("Model has %d materials.", data->materials_count); + YughInfo("Model has %d materials.", data->materials_count); const char *dir = dirname(path); float vs[65535*3]; @@ -145,7 +145,7 @@ struct model *MakeModel(const char *path) { struct mesh newmesh = {0}; arrput(model->meshes,newmesh); - YughWarn("Making mesh %d. It has %d primitives.", i, mesh->primitives_count); + YughInfo("Making mesh %d. It has %d primitives.", i, mesh->primitives_count); for (int j = 0; j < mesh->primitives_count; j++) { cgltf_primitive primitive = mesh->primitives[j]; @@ -173,12 +173,16 @@ struct model *MakeModel(const char *path) { .type = SG_BUFFERTYPE_INDEXBUFFER}); } - if (primitive.material->has_pbr_metallic_roughness && primitive.material->pbr_metallic_roughness.base_color_texture.texture) { - const char *imp = seprint("%s/%s", dir, primitive.material->pbr_metallic_roughness.base_color_texture.texture->image->uri); - YughInfo("Texture is %s.", imp); - - model->meshes[j].bind.fs.images[0] = texture_pullfromfile(imp)->id; - free(imp); + if (primitive.material->has_pbr_metallic_roughness) {// && primitive.material->pbr_metallic_roughness.base_color_texture.texture) { + cgltf_image *img = primitive.material->pbr_metallic_roughness.base_color_texture.texture->image; + if (img->buffer_view) { + cgltf_buffer_view *buf = img->buffer_view; + model->meshes[j].bind.fs.images[0] = texture_fromdata(buf->buffer->data, buf->size)->id; + } else { + const char *imp = seprint("%s/%s", dir, img->uri); + model->meshes[j].bind.fs.images[0] = texture_pullfromfile(imp)->id; + free(imp); + } } else model->meshes[j].bind.fs.images[0] = texture_pullfromfile("k")->id; @@ -232,7 +236,7 @@ struct model *MakeModel(const char *path) { packed_coords[i] = pack_short_texcoord(vs[i]); model->meshes[j].bind.vertex_buffers[1] = sg_make_buffer(&(sg_buffer_desc){ - .data.ptr = vs, + .data.ptr = packed_coords, .data.size = sizeof(unsigned short) * 2 * model->meshes[j].face_count}); free(packed_coords); @@ -241,7 +245,7 @@ struct model *MakeModel(const char *path) { } if (!has_norm) { - YughWarn("Model does not have normals. Generating them."); + YughInfo("Model does not have normals. Generating them."); uint32_t norms[model->meshes[j].face_count]; @@ -272,6 +276,8 @@ struct model *MakeModel(const char *path) { } } + shput(modelhash, path, model); + return model; } diff --git a/source/engine/input.c b/source/engine/input.c index 4041a78..38ae4df 100644 --- a/source/engine/input.c +++ b/source/engine/input.c @@ -1,6 +1,6 @@ #include "input.h" -#include "ffi.h" +#include "jsffi.h" #include "font.h" #include "log.h" #include "script.h" diff --git a/source/engine/ffi.c b/source/engine/jsffi.c similarity index 98% rename from source/engine/ffi.c rename to source/engine/jsffi.c index 05a0fe8..a8fb8c6 100644 --- a/source/engine/ffi.c +++ b/source/engine/jsffi.c @@ -1,4 +1,4 @@ -#include "ffi.h" +#include "jsffi.h" #include "script.h" @@ -1668,6 +1668,29 @@ JSValue duk_cmd_points(JSContext *js, JSValueConst this, int argc, JSValueConst return JS_NULL; } +//#include "dlfcn.h" + +/*JSValue duk_cffi(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) +{ + void *fn = dlsym(dlopen(NULL,0), "puts"); + ffi_cif cif; + ffi_type *args[1]; + void *values[1]; + char *s; + ffi_arg rc; + args[0] = &ffi_type_pointer; + values[0] = &s; + + if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_sint, args) == FFI_OK) { + s = "Hello World!"; + ffi_call(&cif, fn, &rc, values); + s = "This is cool"; + ffi_call(&cif, fn, &rc, values); + } + + return JS_NULL; +} +*/ #define DUK_FUNC(NAME, ARGS) JS_SetPropertyStr(js, globalThis, #NAME, JS_NewCFunction(js, duk_##NAME, #NAME, ARGS)); void ffi_load() { @@ -1707,6 +1730,8 @@ void ffi_load() { DUK_FUNC(inflate_cpv, 3) +// DUK_FUNC(cffi,0); + DUK_FUNC(anim, 2) JS_FreeValue(js,globalThis); diff --git a/source/engine/ffi.h b/source/engine/jsffi.h similarity index 100% rename from source/engine/ffi.h rename to source/engine/jsffi.h diff --git a/source/engine/script.c b/source/engine/script.c index d1641b6..7c37d92 100644 --- a/source/engine/script.c +++ b/source/engine/script.c @@ -3,7 +3,7 @@ #include "log.h" #include "stdio.h" -#include "ffi.h" +#include "jsffi.h" #include "font.h" #include "ftw.h" diff --git a/source/engine/texture.c b/source/engine/texture.c index 5d8f176..d71c7c5 100644 --- a/source/engine/texture.c +++ b/source/engine/texture.c @@ -195,6 +195,77 @@ char *tex_get_path(struct Texture *tex) { return ""; } +struct Texture *texture_fromdata(void *raw, long size) +{ + struct Texture *tex = calloc(1, sizeof(*tex)); + tex->opts.sprite = 1; + tex->opts.mips = 0; + tex->opts.gamma = 0; + tex->opts.wrapx = 1; + tex->opts.wrapy = 1; + + int n; + void *data = stbi_load_from_memory(raw, size, &tex->width, &tex->height, &n, 4); + + if (data == NULL) { + YughError("Given raw data no valid. Loading default instead."); + return texture_notex(); + } + + unsigned int nw = next_pow2(tex->width); + unsigned int nh = next_pow2(tex->height); + + tex->data = data; + + int filter; + if (tex->opts.sprite) { + filter = SG_FILTER_NEAREST; + } else { + filter = SG_FILTER_LINEAR; + } + + sg_image_data sg_img_data; + + int mips = mip_levels(tex->width, tex->height)+1; + + YughInfo("Has %d mip levels, from wxh %dx%d, pow2 is %ux%u.", mips, tex->width, tex->height,nw,nh); + + int mipw, miph; + mipw = tex->width; + miph = tex->height; + + sg_img_data.subimage[0][0] = (sg_range){ .ptr = data, .size = mipw*miph*4 }; + + unsigned char *mipdata[mips]; + mipdata[0] = data; + + for (int i = 1; i < mips; i++) { + int w, h, mipw, miph; + mip_wh(tex->width, tex->height, &mipw, &miph, i-1); /* mipw miph are previous iteration */ + mip_wh(tex->width, tex->height, &w, &h, i); + mipdata[i] = malloc(w * h * 4); + stbir_resize_uint8(mipdata[i-1], mipw, miph, 0, mipdata[i], w, h, 0, 4); + sg_img_data.subimage[0][i] = (sg_range){ .ptr = mipdata[i], .size = w*h*4 }; + + mipw = w; + miph = h; + } + + tex->id = sg_make_image(&(sg_image_desc){ + .type = SG_IMAGETYPE_2D, + .width = tex->width, + .height = tex->height, + .usage = SG_USAGE_IMMUTABLE, + .num_mipmaps = mips, + .data = sg_img_data + }); + + for (int i = 1; i < mips; i++) + free(mipdata[i]); + + return tex; +} + struct Texture *texture_loadfromfile(const char *path) { struct Texture *new = texture_pullfromfile(path); /* diff --git a/source/engine/texture.h b/source/engine/texture.h index ebfac01..789d115 100644 --- a/source/engine/texture.h +++ b/source/engine/texture.h @@ -79,6 +79,7 @@ struct Image { struct Texture *texture_pullfromfile(const char *path); // Create texture from image struct Texture *texture_loadfromfile(const char *path); // Create texture & load to gpu +struct Texture *texture_fromdata(void *raw, long size); void texture_sync(const char *path); struct Texture *str2tex(const char *path); void tex_gpu_reload(struct Texture *tex); // gpu_free then gpu_load diff --git a/source/engine/window.c b/source/engine/window.c index ea42b4b..d351d25 100644 --- a/source/engine/window.c +++ b/source/engine/window.c @@ -6,7 +6,7 @@ #include #include #include -#include "ffi.h" +#include "jsffi.h" #include "render.h" diff --git a/source/engine/yugine.c b/source/engine/yugine.c index 1c82453..f2cd810 100644 --- a/source/engine/yugine.c +++ b/source/engine/yugine.c @@ -16,7 +16,7 @@ #include "quickjs/quickjs.h" -#include "ffi.h" +#include "jsffi.h" #include "script.h" #include "log.h"