This commit is contained in:
alessandro bason 2026-03-04 16:50:09 +01:00
parent 7f37187c92
commit 507d635433
7 changed files with 488 additions and 292 deletions

View file

@ -12,6 +12,7 @@ struct vertex_t {
vec3 pos;
vec3 norm;
vec2 tex;
vec2 lightmap;
};
typedef struct material_t material_t;
@ -282,11 +283,32 @@ struct scene_t {
int object_count;
};
#define CACHE_SIZE (64)
#define MAX_CACHE_NAME_LEN (64)
typedef struct cache_item_t cache_item_t;
struct cache_item_t {
char name[MAX_CACHE_NAME_LEN];
sg_image image;
};
cache_item_t tex_cache[CACHE_SIZE] = {0};
int tex_cache_size = 0;
sg_image obj__load_texture(arena_t scratch, cgltf_texture *texture) {
if (!texture || !texture->image) {
return (sg_image){0};
}
cgltf_image *image = texture->image;
const char *name = image->name;
for (int i = 0; i < tex_cache_size; ++i) {
if (strcmp(tex_cache[i].name, name) == 0) {
return tex_cache[i].image;
}
}
u8 *bytes = NULL;
usize size = 0;
if (image->uri) {
@ -322,6 +344,13 @@ sg_image obj__load_texture(arena_t scratch, cgltf_texture *texture) {
stbi_image_free(pixels);
cache_item_t *item = &tex_cache[tex_cache_size++];
colla_assert(tex_cache_size < CACHE_SIZE, "texture cache full");
item->image = out;
usize len = strlen(name);
memmove(item->name, name, MIN(len, MAX_CACHE_NAME_LEN));
return out;
}
@ -360,11 +389,16 @@ scene_t obj_load_gltf(arena_t scratch, strview_t filename) {
colla_assert(data->meshes_count == 1);
sg_sampler sampler = sg_make_sampler(&(sg_sampler_desc){
sg_sampler tex_sampler = sg_make_sampler(&(sg_sampler_desc){
.min_filter = SG_FILTER_NEAREST,
.mag_filter = SG_FILTER_NEAREST,
});
sg_sampler lightmap_sampler = sg_make_sampler(&(sg_sampler_desc){
.min_filter = SG_FILTER_LINEAR,
.mag_filter = SG_FILTER_LINEAR,
});
u32 missing_texture[] = {
0xFFFF00FF, 0x00000000,
0x00000000, 0xFFFF00FF,
@ -399,6 +433,7 @@ scene_t obj_load_gltf(arena_t scratch, strview_t filename) {
cgltf_material *mat = prim->material;
// diffuse texture
cgltf_texture_view texture_view = mat->pbr_metallic_roughness.base_color_texture;
sg_image image = obj__load_texture(scratch, texture_view.texture);
if (image.id == 0) {
@ -407,8 +442,20 @@ scene_t obj_load_gltf(arena_t scratch, strview_t filename) {
sg_view view = sg_make_view(&(sg_view_desc){
.texture.image = image,
});
obj->bindings.views[0] = view;
obj->bindings.samplers[0] = sampler;
obj->bindings.samplers[0] = tex_sampler;
// lightmap
sg_image lightmap = missing_img;
if (mat->emissive_texture.texture) {
lightmap = obj__load_texture(scratch, mat->emissive_texture.texture);
}
sg_view lm_view = sg_make_view(&(sg_view_desc){
.texture.image = lightmap,
});
obj->bindings.views[1] = lm_view;
obj->bindings.samplers[1] = lightmap_sampler;
for (usize a = 0; a < prim->attributes_count; ++a) {
cgltf_attribute *attr = &prim->attributes[a];
@ -429,10 +476,19 @@ scene_t obj_load_gltf(arena_t scratch, strview_t filename) {
}
break;
case cgltf_attribute_type_texcoord:
for (usize k = 0; k < acc->count; ++k) {
cgltf_accessor_read_float(acc, k, verts[k].tex.data, 2);
{
if (attr->index == 0) {
for (usize k = 0; k < acc->count; ++k) {
cgltf_accessor_read_float(acc, k, verts[k].tex.data, 2);
}
}
else {
for (usize k = 0; k < acc->count; ++k) {
cgltf_accessor_read_float(acc, k, verts[k].lightmap.data, 2);
}
}
break;
}
default: break;
}