aboutsummaryrefslogtreecommitdiff
path: root/src/asset
diff options
context:
space:
mode:
Diffstat (limited to 'src/asset')
-rw-r--r--src/asset/model.c111
-rw-r--r--src/asset/texture.c32
2 files changed, 83 insertions, 60 deletions
diff --git a/src/asset/model.c b/src/asset/model.c
index 25f2780..402b2e1 100644
--- a/src/asset/model.c
+++ b/src/asset/model.c
@@ -578,11 +578,10 @@ static bool load_buffers(
578 const cgltf_buffer* buffer = &data->buffers[i]; 578 const cgltf_buffer* buffer = &data->buffers[i];
579 assert(buffer->data); 579 assert(buffer->data);
580 buffers[i] = gfx_make_buffer( 580 buffers[i] = gfx_make_buffer(
581 gfxcore, &(BufferDesc){ 581 gfxcore, &(BufferDesc){.usage = BufferStatic,
582 .usage = BufferStatic, 582 .type = BufferUntyped,
583 .type = BufferUntyped, 583 .data.data = buffer->data,
584 .data.data = buffer->data, 584 .data.count = buffer->size});
585 .data.count = buffer->size});
586 if (!buffers[i]) { 585 if (!buffers[i]) {
587 return false; 586 return false;
588 } 587 }
@@ -604,11 +603,10 @@ static bool load_tangent_buffers(
604 const cgltfTangentBuffer* buffer = &cgltf_tangent_buffers[i]; 603 const cgltfTangentBuffer* buffer = &cgltf_tangent_buffers[i];
605 assert(buffer->data); 604 assert(buffer->data);
606 tangent_buffers[i] = gfx_make_buffer( 605 tangent_buffers[i] = gfx_make_buffer(
607 gfxcore, &(BufferDesc){ 606 gfxcore, &(BufferDesc){.usage = BufferStatic,
608 .usage = BufferStatic, 607 .type = BufferUntyped,
609 .type = BufferUntyped, 608 .data.data = buffer->data,
610 .data.data = buffer->data, 609 .data.count = buffer->size_bytes});
611 .data.count = buffer->size_bytes});
612 if (!tangent_buffers[i]) { 610 if (!tangent_buffers[i]) {
613 return false; 611 return false;
614 } 612 }
@@ -682,14 +680,13 @@ static void load_textures_lazy(
682 mstring fullpath = 680 mstring fullpath =
683 mstring_concat_path(mstring_make(directory), mstring_make(image->uri)); 681 mstring_concat_path(mstring_make(directory), mstring_make(image->uri));
684 682
685 load_texture_cmds[i] = (LoadTextureCmd){ 683 load_texture_cmds[i] = (LoadTextureCmd){.origin = AssetFromFile,
686 .origin = AssetFromFile, 684 .type = LoadTexture,
687 .type = LoadTexture, 685 .colour_space = LinearColourSpace,
688 .colour_space = sRGB, 686 .filtering = filtering,
689 .filtering = filtering, 687 .wrap = wrap,
690 .wrap = wrap, 688 .mipmaps = mipmaps,
691 .mipmaps = mipmaps, 689 .data.texture.filepath = fullpath};
692 .data.texture.filepath = fullpath};
693 } 690 }
694} 691}
695 692
@@ -717,8 +714,12 @@ static bool load_texture_and_uniform(
717 // not be used as albedo and vice versa. 714 // not be used as albedo and vice versa.
718 if (!textures[texture_index]) { 715 if (!textures[texture_index]) {
719 LoadTextureCmd* cmd = &load_texture_cmds[texture_index]; 716 LoadTextureCmd* cmd = &load_texture_cmds[texture_index];
720 // TODO: Check for colour textures and default to LinearColourSpace instead. 717 // Albedo and emissive use sRGB. Other textures use a linear colour space.
721 if (texture_type == NormalMap) { 718 // See the notes on the spec.
719 if ((texture_type == BaseColorTexture) ||
720 (texture_type == EmissiveTexture)) {
721 cmd->colour_space = sRGB;
722 } else {
722 cmd->colour_space = LinearColourSpace; 723 cmd->colour_space = LinearColourSpace;
723 } 724 }
724 725
@@ -778,22 +779,22 @@ static bool load_materials(
778 .value.vec4 = vec4_from_array(pbr->base_color_factor)}; 779 .value.vec4 = vec4_from_array(pbr->base_color_factor)};
779 780
780 assert(next_uniform < GFX_MAX_UNIFORMS_PER_MATERIAL); 781 assert(next_uniform < GFX_MAX_UNIFORMS_PER_MATERIAL);
781 desc.uniforms[next_uniform++] = (ShaderUniform){ 782 desc.uniforms[next_uniform++] =
782 .name = sstring_make(UNIFORM_METALLIC_FACTOR), 783 (ShaderUniform){.name = sstring_make(UNIFORM_METALLIC_FACTOR),
783 .type = UniformFloat, 784 .type = UniformFloat,
784 .value.scalar = pbr->metallic_factor}; 785 .value.scalar = pbr->metallic_factor};
785 786
786 assert(next_uniform < GFX_MAX_UNIFORMS_PER_MATERIAL); 787 assert(next_uniform < GFX_MAX_UNIFORMS_PER_MATERIAL);
787 desc.uniforms[next_uniform++] = (ShaderUniform){ 788 desc.uniforms[next_uniform++] =
788 .name = sstring_make(UNIFORM_ROUGHNESS_FACTOR), 789 (ShaderUniform){.name = sstring_make(UNIFORM_ROUGHNESS_FACTOR),
789 .type = UniformFloat, 790 .type = UniformFloat,
790 .value.scalar = pbr->roughness_factor}; 791 .value.scalar = pbr->roughness_factor};
791 792
792 assert(next_uniform < GFX_MAX_UNIFORMS_PER_MATERIAL); 793 assert(next_uniform < GFX_MAX_UNIFORMS_PER_MATERIAL);
793 desc.uniforms[next_uniform++] = (ShaderUniform){ 794 desc.uniforms[next_uniform++] =
794 .name = sstring_make(UNIFORM_EMISSIVE_FACTOR), 795 (ShaderUniform){.name = sstring_make(UNIFORM_EMISSIVE_FACTOR),
795 .type = UniformVec3, 796 .type = UniformVec3,
796 .value.vec3 = vec3_from_array(mat->emissive_factor)}; 797 .value.vec3 = vec3_from_array(mat->emissive_factor)};
797 798
798 if (pbr->base_color_texture.texture) { 799 if (pbr->base_color_texture.texture) {
799 if (!load_texture_and_uniform( 800 if (!load_texture_and_uniform(
@@ -854,28 +855,28 @@ static Material* make_default_material() {
854 MaterialDesc desc = (MaterialDesc){0}; 855 MaterialDesc desc = (MaterialDesc){0};
855 856
856 assert(desc.num_uniforms < GFX_MAX_UNIFORMS_PER_MATERIAL); 857 assert(desc.num_uniforms < GFX_MAX_UNIFORMS_PER_MATERIAL);
857 desc.uniforms[desc.num_uniforms++] = (ShaderUniform){ 858 desc.uniforms[desc.num_uniforms++] =
858 .name = sstring_make(UNIFORM_BASE_COLOR_FACTOR), 859 (ShaderUniform){.name = sstring_make(UNIFORM_BASE_COLOR_FACTOR),
859 .type = UniformVec4, 860 .type = UniformVec4,
860 .value.vec4 = vec4_make(1, 1, 1, 1)}; 861 .value.vec4 = vec4_make(1, 1, 1, 1)};
861 862
862 assert(desc.num_uniforms < GFX_MAX_UNIFORMS_PER_MATERIAL); 863 assert(desc.num_uniforms < GFX_MAX_UNIFORMS_PER_MATERIAL);
863 desc.uniforms[desc.num_uniforms++] = (ShaderUniform){ 864 desc.uniforms[desc.num_uniforms++] =
864 .name = sstring_make(UNIFORM_METALLIC_FACTOR), 865 (ShaderUniform){.name = sstring_make(UNIFORM_METALLIC_FACTOR),
865 .type = UniformFloat, 866 .type = UniformFloat,
866 .value.scalar = 0}; 867 .value.scalar = 0};
867 868
868 assert(desc.num_uniforms < GFX_MAX_UNIFORMS_PER_MATERIAL); 869 assert(desc.num_uniforms < GFX_MAX_UNIFORMS_PER_MATERIAL);
869 desc.uniforms[desc.num_uniforms++] = (ShaderUniform){ 870 desc.uniforms[desc.num_uniforms++] =
870 .name = sstring_make(UNIFORM_ROUGHNESS_FACTOR), 871 (ShaderUniform){.name = sstring_make(UNIFORM_ROUGHNESS_FACTOR),
871 .type = UniformFloat, 872 .type = UniformFloat,
872 .value.scalar = 1}; 873 .value.scalar = 1};
873 874
874 assert(desc.num_uniforms < GFX_MAX_UNIFORMS_PER_MATERIAL); 875 assert(desc.num_uniforms < GFX_MAX_UNIFORMS_PER_MATERIAL);
875 desc.uniforms[desc.num_uniforms++] = (ShaderUniform){ 876 desc.uniforms[desc.num_uniforms++] =
876 .name = sstring_make(UNIFORM_EMISSIVE_FACTOR), 877 (ShaderUniform){.name = sstring_make(UNIFORM_EMISSIVE_FACTOR),
877 .type = UniformVec3, 878 .type = UniformVec3,
878 .value.vec3 = vec3_make(0, 0, 0)}; 879 .value.vec3 = vec3_make(0, 0, 0)};
879 880
880 return gfx_make_material(&desc); 881 return gfx_make_material(&desc);
881} 882}
@@ -1192,10 +1193,10 @@ static bool load_meshes(
1192 shader ? shader : make_shader_permutation(gfxcore, perm); 1193 shader ? shader : make_shader_permutation(gfxcore, perm);
1193 assert(mesh_shader); 1194 assert(mesh_shader);
1194 1195
1195 meshes[next_mesh] = gfx_make_mesh(&(MeshDesc){ 1196 meshes[next_mesh] =
1196 .geometry = geometries[next_mesh], 1197 gfx_make_mesh(&(MeshDesc){.geometry = geometries[next_mesh],
1197 .material = material, 1198 .material = material,
1198 .shader = mesh_shader}); 1199 .shader = mesh_shader});
1199 1200
1200 if (!meshes[next_mesh]) { 1201 if (!meshes[next_mesh]) {
1201 return false; 1202 return false;
@@ -1432,9 +1433,9 @@ static void load_animations(
1432 const cgltf_animation* animation = &data->animations[a]; 1433 const cgltf_animation* animation = &data->animations[a];
1433 AnimationDesc* animation_desc = &anima_desc->animations[a]; 1434 AnimationDesc* animation_desc = &anima_desc->animations[a];
1434 1435
1435 *animation_desc = (AnimationDesc){ 1436 *animation_desc =
1436 .name = sstring_make(animation->name), 1437 (AnimationDesc){.name = sstring_make(animation->name),
1437 .num_channels = animation->channels_count}; 1438 .num_channels = animation->channels_count};
1438 1439
1439 assert(animation->channels_count <= GFX_MAX_NUM_CHANNELS); 1440 assert(animation->channels_count <= GFX_MAX_NUM_CHANNELS);
1440 for (cgltf_size c = 0; c < animation->channels_count; ++c) { 1441 for (cgltf_size c = 0; c < animation->channels_count; ++c) {
diff --git a/src/asset/texture.c b/src/asset/texture.c
index c790394..fb423cc 100644
--- a/src/asset/texture.c
+++ b/src/asset/texture.c
@@ -49,7 +49,7 @@ Texture* gfx_texture_load(GfxCore* gfxcore, const LoadTextureCmd* cmd) {
49 assert(cmd->origin == AssetFromFile || cmd->origin == AssetFromMemory); 49 assert(cmd->origin == AssetFromFile || cmd->origin == AssetFromMemory);
50 assert(cmd->type == LoadTexture || cmd->type == LoadCubemap); 50 assert(cmd->type == LoadTexture || cmd->type == LoadCubemap);
51 51
52 int width, height, components, old_components; 52 int width, height, components;
53 unsigned char* pixels[6] = {0}; 53 unsigned char* pixels[6] = {0};
54 54
55 switch (cmd->origin) { 55 switch (cmd->origin) {
@@ -64,7 +64,8 @@ Texture* gfx_texture_load(GfxCore* gfxcore, const LoadTextureCmd* cmd) {
64 } 64 }
65 break; 65 break;
66 } 66 }
67 case LoadCubemap: 67 case LoadCubemap: {
68 int old_components = 0;
68 for (int i = 0; i < 6; ++i) { 69 for (int i = 0; i < 6; ++i) {
69 // Flip +Y and -Y textures vertically. 70 // Flip +Y and -Y textures vertically.
70 stbi_set_flip_vertically_on_load(((i == 2) || (i == 3)) ? 1 : 0); 71 stbi_set_flip_vertically_on_load(((i == 2) || (i == 3)) ? 1 : 0);
@@ -76,9 +77,10 @@ Texture* gfx_texture_load(GfxCore* gfxcore, const LoadTextureCmd* cmd) {
76 log_error("Failed to load texture file: %s", filepath); 77 log_error("Failed to load texture file: %s", filepath);
77 break; 78 break;
78 } 79 }
79 if (i > 0 && components != old_components) { 80 if ((i > 0) && (components != old_components)) {
80 log_error("All textures in a cubemap must have the same number of " 81 log_error(
81 "components"); 82 "All textures in a cubemap must have the same number of "
83 "components");
82 break; 84 break;
83 } 85 }
84 if ((i != 2) && (i != 3)) { 86 if ((i != 2) && (i != 3)) {
@@ -89,6 +91,7 @@ Texture* gfx_texture_load(GfxCore* gfxcore, const LoadTextureCmd* cmd) {
89 } 91 }
90 break; 92 break;
91 } 93 }
94 }
92 break; 95 break;
93 case AssetFromMemory: 96 case AssetFromMemory:
94 // TODO: Load textures from memory. 97 // TODO: Load textures from memory.
@@ -122,6 +125,25 @@ Texture* gfx_texture_load(GfxCore* gfxcore, const LoadTextureCmd* cmd) {
122 } 125 }
123 126
124 switch (components) { 127 switch (components) {
128 case 1:
129 switch (cmd->colour_space) {
130 case LinearColourSpace:
131 desc.format = TextureR8;
132 break;
133 case sRGB:
134 // TODO: Gamma single-channel textures are not implemented yet.
135 // The caller should convert the single-channel to RGB and pass it down
136 // as sRGB. This is why the ChronographWatch currently appears red on the
137 // back.
138 log_error("Gamma colour space is not supported for 1-channel textures");
139 // return 0;
140 desc.format = TextureR8;
141 break;
142 default:
143 log_error("Unsupported texture colour space: %d", cmd->colour_space);
144 return 0;
145 }
146 break;
125 case 3: 147 case 3:
126 switch (cmd->colour_space) { 148 switch (cmd->colour_space) {
127 case LinearColourSpace: 149 case LinearColourSpace: