cgltf glb texture pulling

This commit is contained in:
John Alanbrook 2023-11-04 03:01:30 +00:00
parent 366a20e7ed
commit 5ee444465e
11 changed files with 121 additions and 18 deletions

View file

@ -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,

View file

@ -14,7 +14,7 @@
#include "tinyspline.h"
#include "ffi.h"
#include "jsffi.h"
#include "script.h"
#include "log.h"

View file

@ -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;
}

View file

@ -1,6 +1,6 @@
#include "input.h"
#include "ffi.h"
#include "jsffi.h"
#include "font.h"
#include "log.h"
#include "script.h"

View file

@ -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);

View file

@ -3,7 +3,7 @@
#include "log.h"
#include "stdio.h"
#include "ffi.h"
#include "jsffi.h"
#include "font.h"
#include "ftw.h"

View file

@ -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);
/*

View file

@ -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

View file

@ -6,7 +6,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ffi.h"
#include "jsffi.h"
#include "render.h"

View file

@ -16,7 +16,7 @@
#include "quickjs/quickjs.h"
#include "ffi.h"
#include "jsffi.h"
#include "script.h"
#include "log.h"