diff options
Diffstat (limited to 'src/asset')
| -rw-r--r-- | src/asset/model.c | 75 |
1 files changed, 48 insertions, 27 deletions
diff --git a/src/asset/model.c b/src/asset/model.c index 2ee3cd1..a97d20e 100644 --- a/src/asset/model.c +++ b/src/asset/model.c | |||
| @@ -138,6 +138,7 @@ | |||
| 138 | #define DEFINE_HAS_NORMAL_MAP "HAS_NORMAL_MAP" | 138 | #define DEFINE_HAS_NORMAL_MAP "HAS_NORMAL_MAP" |
| 139 | #define DEFINE_HAS_OCCLUSION_MAP "HAS_OCCLUSION_MAP" | 139 | #define DEFINE_HAS_OCCLUSION_MAP "HAS_OCCLUSION_MAP" |
| 140 | #define DEFINE_HAS_EMISSIVE_MAP "HAS_EMISSIVE_MAP" | 140 | #define DEFINE_HAS_EMISSIVE_MAP "HAS_EMISSIVE_MAP" |
| 141 | #define DEFINE_HAS_TRANSPARENCY "HAS_TRANSPARENCY" | ||
| 141 | #define DEFINE_HAS_JOINTS "HAS_JOINTS" | 142 | #define DEFINE_HAS_JOINTS "HAS_JOINTS" |
| 142 | #define DEFINE_MAX_JOINTS "MAX_JOINTS" | 143 | #define DEFINE_MAX_JOINTS "MAX_JOINTS" |
| 143 | 144 | ||
| @@ -166,6 +167,8 @@ typedef struct MeshPermutation { | |||
| 166 | bool has_normal_map : 1; | 167 | bool has_normal_map : 1; |
| 167 | bool has_occlusion_map : 1; | 168 | bool has_occlusion_map : 1; |
| 168 | bool has_emissive_map : 1; | 169 | bool has_emissive_map : 1; |
| 170 | // Material. | ||
| 171 | bool has_transparency : 1; | ||
| 169 | }; | 172 | }; |
| 170 | int32_t all; | 173 | int32_t all; |
| 171 | }; | 174 | }; |
| @@ -192,6 +195,7 @@ static size_t make_defines( | |||
| 192 | check(has_normal_map, DEFINE_HAS_NORMAL_MAP); | 195 | check(has_normal_map, DEFINE_HAS_NORMAL_MAP); |
| 193 | check(has_occlusion_map, DEFINE_HAS_OCCLUSION_MAP); | 196 | check(has_occlusion_map, DEFINE_HAS_OCCLUSION_MAP); |
| 194 | check(has_emissive_map, DEFINE_HAS_EMISSIVE_MAP); | 197 | check(has_emissive_map, DEFINE_HAS_EMISSIVE_MAP); |
| 198 | check(has_transparency, DEFINE_HAS_TRANSPARENCY); | ||
| 195 | 199 | ||
| 196 | if (perm.has_joints) { | 200 | if (perm.has_joints) { |
| 197 | defines[next].name = sstring_make(DEFINE_MAX_JOINTS); | 201 | defines[next].name = sstring_make(DEFINE_MAX_JOINTS); |
| @@ -208,12 +212,12 @@ static ShaderProgram* make_shader_permutation( | |||
| 208 | LOGD( | 212 | LOGD( |
| 209 | "Compiling Cook-Torrance shader permutation: texcoords: %d, normals: " | 213 | "Compiling Cook-Torrance shader permutation: texcoords: %d, normals: " |
| 210 | "%d, tangents: %d, joints: %d, weights: %d, albedo map: %d, " | 214 | "%d, tangents: %d, joints: %d, weights: %d, albedo map: %d, " |
| 211 | "metallic-roughness map: " | 215 | "metallic-roughness map: %d, normal map: %d, AO map: %d, emissive map: " |
| 212 | "%d, normal " | 216 | "%d, has transparency: %d", |
| 213 | "map: %d, AO map: %d, emissive map: %d", | ||
| 214 | perm.has_texcoords, perm.has_normals, perm.has_tangents, perm.has_joints, | 217 | perm.has_texcoords, perm.has_normals, perm.has_tangents, perm.has_joints, |
| 215 | perm.has_weights, perm.has_albedo_map, perm.has_metallic_roughness_map, | 218 | perm.has_weights, perm.has_albedo_map, perm.has_metallic_roughness_map, |
| 216 | perm.has_normal_map, perm.has_occlusion_map, perm.has_emissive_map); | 219 | perm.has_normal_map, perm.has_occlusion_map, perm.has_emissive_map, |
| 220 | perm.has_transparency); | ||
| 217 | 221 | ||
| 218 | ShaderCompilerDefine defines[GFX_MAX_SHADER_COMPILER_DEFINES]; | 222 | ShaderCompilerDefine defines[GFX_MAX_SHADER_COMPILER_DEFINES]; |
| 219 | const size_t num_defines = make_defines(perm, defines); | 223 | const size_t num_defines = make_defines(perm, defines); |
| @@ -742,6 +746,19 @@ static bool load_texture_and_uniform( | |||
| 742 | return true; | 746 | return true; |
| 743 | } | 747 | } |
| 744 | 748 | ||
| 749 | static AlphaMode to_gfx_alpha_mode(cgltf_alpha_mode mode) { | ||
| 750 | switch (mode) { | ||
| 751 | case cgltf_alpha_mode_opaque: | ||
| 752 | return Opaque; | ||
| 753 | case cgltf_alpha_mode_mask: | ||
| 754 | return Mask; | ||
| 755 | case cgltf_alpha_mode_blend: | ||
| 756 | return Blend; | ||
| 757 | } | ||
| 758 | FAIL("unhandled alpha mode"); | ||
| 759 | return Opaque; | ||
| 760 | } | ||
| 761 | |||
| 745 | /// Load all materials from the glTF scene. | 762 | /// Load all materials from the glTF scene. |
| 746 | /// | 763 | /// |
| 747 | /// Return an array of Materials such that the index of each descriptor matches | 764 | /// Return an array of Materials such that the index of each descriptor matches |
| @@ -770,27 +787,27 @@ static bool load_materials( | |||
| 770 | 787 | ||
| 771 | assert(next_uniform < GFX_MAX_UNIFORMS_PER_MATERIAL); | 788 | assert(next_uniform < GFX_MAX_UNIFORMS_PER_MATERIAL); |
| 772 | desc.uniforms[next_uniform++] = (ShaderUniform){ | 789 | desc.uniforms[next_uniform++] = (ShaderUniform){ |
| 773 | .name = sstring_make(UNIFORM_BASE_COLOR_FACTOR), | 790 | .name = sstring_make(UNIFORM_BASE_COLOR_FACTOR), |
| 774 | .type = UniformVec4, | 791 | .type = UniformVec4, |
| 775 | .value.vec4 = vec4_from_array(pbr->base_color_factor)}; | 792 | .value.uniform_vec4 = vec4_from_array(pbr->base_color_factor)}; |
| 776 | 793 | ||
| 777 | assert(next_uniform < GFX_MAX_UNIFORMS_PER_MATERIAL); | 794 | assert(next_uniform < GFX_MAX_UNIFORMS_PER_MATERIAL); |
| 778 | desc.uniforms[next_uniform++] = | 795 | desc.uniforms[next_uniform++] = |
| 779 | (ShaderUniform){.name = sstring_make(UNIFORM_METALLIC_FACTOR), | 796 | (ShaderUniform){.name = sstring_make(UNIFORM_METALLIC_FACTOR), |
| 780 | .type = UniformFloat, | 797 | .type = UniformFloat, |
| 781 | .value.scalar = pbr->metallic_factor}; | 798 | .value.uniform_float = pbr->metallic_factor}; |
| 782 | 799 | ||
| 783 | assert(next_uniform < GFX_MAX_UNIFORMS_PER_MATERIAL); | 800 | assert(next_uniform < GFX_MAX_UNIFORMS_PER_MATERIAL); |
| 784 | desc.uniforms[next_uniform++] = | 801 | desc.uniforms[next_uniform++] = |
| 785 | (ShaderUniform){.name = sstring_make(UNIFORM_ROUGHNESS_FACTOR), | 802 | (ShaderUniform){.name = sstring_make(UNIFORM_ROUGHNESS_FACTOR), |
| 786 | .type = UniformFloat, | 803 | .type = UniformFloat, |
| 787 | .value.scalar = pbr->roughness_factor}; | 804 | .value.uniform_float = pbr->roughness_factor}; |
| 788 | 805 | ||
| 789 | assert(next_uniform < GFX_MAX_UNIFORMS_PER_MATERIAL); | 806 | assert(next_uniform < GFX_MAX_UNIFORMS_PER_MATERIAL); |
| 790 | desc.uniforms[next_uniform++] = | 807 | desc.uniforms[next_uniform++] = (ShaderUniform){ |
| 791 | (ShaderUniform){.name = sstring_make(UNIFORM_EMISSIVE_FACTOR), | 808 | .name = sstring_make(UNIFORM_EMISSIVE_FACTOR), |
| 792 | .type = UniformVec3, | 809 | .type = UniformVec3, |
| 793 | .value.vec3 = vec3_from_array(mat->emissive_factor)}; | 810 | .value.uniform_vec3 = vec3_from_array(mat->emissive_factor)}; |
| 794 | 811 | ||
| 795 | if (pbr->base_color_texture.texture) { | 812 | if (pbr->base_color_texture.texture) { |
| 796 | if (!load_texture_and_uniform( | 813 | if (!load_texture_and_uniform( |
| @@ -837,6 +854,9 @@ static bool load_materials( | |||
| 837 | assert(next_uniform < GFX_MAX_UNIFORMS_PER_MATERIAL); | 854 | assert(next_uniform < GFX_MAX_UNIFORMS_PER_MATERIAL); |
| 838 | desc.num_uniforms = next_uniform; | 855 | desc.num_uniforms = next_uniform; |
| 839 | 856 | ||
| 857 | desc.alpha_mode = to_gfx_alpha_mode(mat->alpha_mode); | ||
| 858 | desc.alpha_cutoff = mat->alpha_cutoff; | ||
| 859 | |||
| 840 | materials[i] = gfx_make_material(&desc); | 860 | materials[i] = gfx_make_material(&desc); |
| 841 | if (!materials[i]) { | 861 | if (!materials[i]) { |
| 842 | return false; | 862 | return false; |
| @@ -852,27 +872,27 @@ static Material* make_default_material() { | |||
| 852 | 872 | ||
| 853 | assert(desc.num_uniforms < GFX_MAX_UNIFORMS_PER_MATERIAL); | 873 | assert(desc.num_uniforms < GFX_MAX_UNIFORMS_PER_MATERIAL); |
| 854 | desc.uniforms[desc.num_uniforms++] = | 874 | desc.uniforms[desc.num_uniforms++] = |
| 855 | (ShaderUniform){.name = sstring_make(UNIFORM_BASE_COLOR_FACTOR), | 875 | (ShaderUniform){.name = sstring_make(UNIFORM_BASE_COLOR_FACTOR), |
| 856 | .type = UniformVec4, | 876 | .type = UniformVec4, |
| 857 | .value.vec4 = vec4_make(1, 1, 1, 1)}; | 877 | .value.uniform_vec4 = vec4_make(1, 1, 1, 1)}; |
| 858 | 878 | ||
| 859 | assert(desc.num_uniforms < GFX_MAX_UNIFORMS_PER_MATERIAL); | 879 | assert(desc.num_uniforms < GFX_MAX_UNIFORMS_PER_MATERIAL); |
| 860 | desc.uniforms[desc.num_uniforms++] = | 880 | desc.uniforms[desc.num_uniforms++] = |
| 861 | (ShaderUniform){.name = sstring_make(UNIFORM_METALLIC_FACTOR), | 881 | (ShaderUniform){.name = sstring_make(UNIFORM_METALLIC_FACTOR), |
| 862 | .type = UniformFloat, | 882 | .type = UniformFloat, |
| 863 | .value.scalar = 0}; | 883 | .value.uniform_float = 0}; |
| 864 | 884 | ||
| 865 | assert(desc.num_uniforms < GFX_MAX_UNIFORMS_PER_MATERIAL); | 885 | assert(desc.num_uniforms < GFX_MAX_UNIFORMS_PER_MATERIAL); |
| 866 | desc.uniforms[desc.num_uniforms++] = | 886 | desc.uniforms[desc.num_uniforms++] = |
| 867 | (ShaderUniform){.name = sstring_make(UNIFORM_ROUGHNESS_FACTOR), | 887 | (ShaderUniform){.name = sstring_make(UNIFORM_ROUGHNESS_FACTOR), |
| 868 | .type = UniformFloat, | 888 | .type = UniformFloat, |
| 869 | .value.scalar = 1}; | 889 | .value.uniform_float = 1}; |
| 870 | 890 | ||
| 871 | assert(desc.num_uniforms < GFX_MAX_UNIFORMS_PER_MATERIAL); | 891 | assert(desc.num_uniforms < GFX_MAX_UNIFORMS_PER_MATERIAL); |
| 872 | desc.uniforms[desc.num_uniforms++] = | 892 | desc.uniforms[desc.num_uniforms++] = |
| 873 | (ShaderUniform){.name = sstring_make(UNIFORM_EMISSIVE_FACTOR), | 893 | (ShaderUniform){.name = sstring_make(UNIFORM_EMISSIVE_FACTOR), |
| 874 | .type = UniformVec3, | 894 | .type = UniformVec3, |
| 875 | .value.vec3 = vec3_make(0, 0, 0)}; | 895 | .value.uniform_vec3 = vec3_make(0, 0, 0)}; |
| 876 | 896 | ||
| 877 | return gfx_make_material(&desc); | 897 | return gfx_make_material(&desc); |
| 878 | } | 898 | } |
| @@ -950,6 +970,7 @@ static bool load_meshes( | |||
| 950 | perm.has_normal_map = mat->normal_texture.texture != 0; | 970 | perm.has_normal_map = mat->normal_texture.texture != 0; |
| 951 | perm.has_occlusion_map = mat->occlusion_texture.texture != 0; | 971 | perm.has_occlusion_map = mat->occlusion_texture.texture != 0; |
| 952 | perm.has_emissive_map = mat->emissive_texture.texture != 0; | 972 | perm.has_emissive_map = mat->emissive_texture.texture != 0; |
| 973 | perm.has_transparency = mat->alpha_mode != cgltf_alpha_mode_opaque; | ||
| 953 | 974 | ||
| 954 | if (mat->has_pbr_metallic_roughness) { | 975 | if (mat->has_pbr_metallic_roughness) { |
| 955 | const cgltf_pbr_metallic_roughness* pbr = | 976 | const cgltf_pbr_metallic_roughness* pbr = |
