summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorTyler Jessilynn Bezera <[email protected]>2020-02-22 01:17:30 -0800
committerGitHub <[email protected]>2020-02-22 10:17:30 +0100
commite7fdf8a13d88520379620f45ff43550bd75a546f (patch)
tree346006fcc35e51cb9a6adab2b7d2db8e7ba04aa3 /src
parenta750bcceec53c5a9c0c273ee9f0e9e792e928bd5 (diff)
downloadraylib-e7fdf8a13d88520379620f45ff43550bd75a546f.tar.gz
raylib-e7fdf8a13d88520379620f45ff43550bd75a546f.zip
Expand GLTF Model support (#1108)
* Update GLTF support to include loading color for albdeo (saved in the color value of the materialmap), support occlussion and emmission maps.. as well as some quality of life updates. * clean up to use single image
Diffstat (limited to 'src')
-rw-r--r--src/models.c87
1 files changed, 48 insertions, 39 deletions
diff --git a/src/models.c b/src/models.c
index 1a3ae3ed..6d95441f 100644
--- a/src/models.c
+++ b/src/models.c
@@ -3377,9 +3377,9 @@ static unsigned char *DecodeBase64(char *input, int *size)
}
// Load texture from cgltf_image
-static Texture LoadTextureFromCgltfImage(cgltf_image *image, const char *texPath, Color tint)
+static Image LoadImageFromCgltfImage(cgltf_image *image, const char *texPath, Color tint)
{
- Texture texture = { 0 };
+ Image rimage = { 0 };
if (image->uri)
{
@@ -3406,22 +3406,18 @@ static Texture LoadTextureFromCgltfImage(cgltf_image *image, const char *texPath
int w, h;
unsigned char *raw = stbi_load_from_memory(data, size, &w, &h, NULL, 4);
- Image rimage = LoadImagePro(raw, w, h, UNCOMPRESSED_R8G8B8A8);
+ rimage = LoadImagePro(raw, w, h, UNCOMPRESSED_R8G8B8A8);
// TODO: Tint shouldn't be applied here!
ImageColorTint(&rimage, tint);
- texture = LoadTextureFromImage(rimage);
- UnloadImage(rimage);
}
}
else
{
- Image rimage = LoadImage(TextFormat("%s/%s", texPath, image->uri));
+ rimage = LoadImage(TextFormat("%s/%s", texPath, image->uri));
// TODO: Tint shouldn't be applied here!
ImageColorTint(&rimage, tint);
- texture = LoadTextureFromImage(rimage);
- UnloadImage(rimage);
}
}
else if (image->buffer_view)
@@ -3440,41 +3436,36 @@ static Texture LoadTextureFromCgltfImage(cgltf_image *image, const char *texPath
unsigned char *raw = stbi_load_from_memory(data, image->buffer_view->size, &w, &h, NULL, 4);
free(data);
- Image rimage = LoadImagePro(raw, w, h, UNCOMPRESSED_R8G8B8A8);
+ rimage = LoadImagePro(raw, w, h, UNCOMPRESSED_R8G8B8A8);
free(raw);
// TODO: Tint shouldn't be applied here!
ImageColorTint(&rimage, tint);
- texture = LoadTextureFromImage(rimage);
- UnloadImage(rimage);
}
else
{
- Image rimage = LoadImageEx(&tint, 1, 1);
- texture = LoadTextureFromImage(rimage);
- UnloadImage(rimage);
+ rimage = LoadImageEx(&tint, 1, 1);
}
- return texture;
+ return rimage;
}
-// Load glTF mesh data
+// LoadGLTF loads in model data from given filename, supporting both .gltf and .glb
static Model LoadGLTF(const char *fileName)
{
/***********************************************************************************
- Function implemented by Wilhem Barbier (@wbrbr)
+ Function implemented by Wilhem Barbier(@wbrbr), with modifications by Tyler Bezera(@gamerfiend)
Features:
- Supports .gltf and .glb files
- Supports embedded (base64) or external textures
- - Loads the albedo/diffuse texture (other maps could be added)
+ - Loads all raylib supported material textures, values and colors
- Supports multiple mesh per model and multiple primitives per model
Some restrictions (not exhaustive):
- Triangle-only meshes
- Not supported node hierarchies or transforms
- - Only loads the diffuse texture... but not too hard to support other maps (normal, roughness/metalness...)
- Only supports unsigned short indices (no byte/unsigned int)
- Only supports float for texture coordinates (no byte/unsigned short)
@@ -3547,44 +3538,62 @@ static Model LoadGLTF(const char *fileName)
//Ensure material follows raylib support for PBR (metallic/roughness flow)
if (data->materials[i].has_pbr_metallic_roughness)
{
- float roughness = data->materials[i].pbr_metallic_roughness.roughness_factor;
- float metallic = data->materials[i].pbr_metallic_roughness.metallic_factor;
+ tint.r = (unsigned char)(data->materials[i].pbr_metallic_roughness.base_color_factor[0] * 255);
+ tint.g = (unsigned char)(data->materials[i].pbr_metallic_roughness.base_color_factor[1] * 255);
+ tint.b = (unsigned char)(data->materials[i].pbr_metallic_roughness.base_color_factor[2] * 255);
+ tint.a = (unsigned char)(data->materials[i].pbr_metallic_roughness.base_color_factor[3] * 255);
- // NOTE: Material name not used for the moment
- //if (model.materials[i].name && data->materials[i].name) strcpy(model.materials[i].name, data->materials[i].name);
-
- // TODO: REview: shouldn't these be *255 ???
- tint.r = (unsigned char)(data->materials[i].pbr_metallic_roughness.base_color_factor[0]*255);
- tint.g = (unsigned char)(data->materials[i].pbr_metallic_roughness.base_color_factor[1]*255);
- tint.b = (unsigned char)(data->materials[i].pbr_metallic_roughness.base_color_factor[2]*255);
- tint.a = (unsigned char)(data->materials[i].pbr_metallic_roughness.base_color_factor[3]*255);
-
- model.materials[i].maps[MAP_ROUGHNESS].color = tint;
+ model.materials[i].maps[MAP_ALBEDO].color = tint;
if (data->materials[i].pbr_metallic_roughness.base_color_texture.texture)
{
- model.materials[i].maps[MAP_ALBEDO].texture = LoadTextureFromCgltfImage(data->materials[i].pbr_metallic_roughness.base_color_texture.texture->image, texPath, tint);
+ Image albedo = LoadImageFromCgltfImage(data->materials[i].pbr_metallic_roughness.base_color_texture.texture->image, texPath, tint);
+ model.materials[i].maps[MAP_ALBEDO].texture = LoadTextureFromImage(albedo);
+ UnloadImage(albedo);
}
- // NOTE: Tint isn't need for other textures.. pass null or clear?
- // Just set as white, multiplying by white has no effect
+ //Set tint to white after it's been used by Albedo
tint = WHITE;
if (data->materials[i].pbr_metallic_roughness.metallic_roughness_texture.texture)
{
- model.materials[i].maps[MAP_ROUGHNESS].texture = LoadTextureFromCgltfImage(data->materials[i].pbr_metallic_roughness.metallic_roughness_texture.texture->image, texPath, tint);
+ Image metallicRoughness = LoadImageFromCgltfImage(data->materials[i].pbr_metallic_roughness.metallic_roughness_texture.texture->image, texPath, tint);
+ model.materials[i].maps[MAP_ROUGHNESS].texture = LoadTextureFromImage(metallicRoughness);
+
+ float roughness = data->materials[i].pbr_metallic_roughness.roughness_factor;
+ model.materials[i].maps[MAP_ROUGHNESS].value = roughness;
+
+ float metallic = data->materials[i].pbr_metallic_roughness.metallic_factor;
+ model.materials[i].maps[MAP_METALNESS].value = metallic;
+
+ UnloadImage(metallicRoughness);
}
- model.materials[i].maps[MAP_ROUGHNESS].value = roughness;
- model.materials[i].maps[MAP_METALNESS].value = metallic;
+
+
if (data->materials[i].normal_texture.texture)
{
- model.materials[i].maps[MAP_NORMAL].texture = LoadTextureFromCgltfImage(data->materials[i].normal_texture.texture->image, texPath, tint);
+ Image normalImage = LoadImageFromCgltfImage(data->materials[i].normal_texture.texture->image, texPath, tint);
+ model.materials[i].maps[MAP_NORMAL].texture = LoadTextureFromImage(normalImage);
+ UnloadImage(normalImage);
}
if (data->materials[i].occlusion_texture.texture)
{
- model.materials[i].maps[MAP_OCCLUSION].texture = LoadTextureFromCgltfImage(data->materials[i].occlusion_texture.texture->image, texPath, tint);
+ Image occulsionImage = LoadImageFromCgltfImage(data->materials[i].occlusion_texture.texture->image, texPath, tint);
+ model.materials[i].maps[MAP_OCCLUSION].texture = LoadTextureFromImage(occulsionImage);
+ UnloadImage(occulsionImage);
+ }
+
+ if (data->materials[i].emissive_texture.texture)
+ {
+ Image emissiveImage = LoadImageFromCgltfImage(data->materials[i].emissive_texture.texture->image, texPath, tint);
+ model.materials[i].maps[MAP_EMISSION].texture = LoadTextureFromImage(emissiveImage);
+ tint.r = (unsigned char)(data->materials[i].emissive_factor[0] * 255);
+ tint.g = (unsigned char)(data->materials[i].emissive_factor[1] * 255);
+ tint.b = (unsigned char)(data->materials[i].emissive_factor[2] * 255);
+ model.materials[i].maps[MAP_EMISSION].color = tint;
+ UnloadImage(emissiveImage);
}
}
}