@ -2385,8 +2385,15 @@ void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rota
for ( int i = 0 ; i < model . meshCount ; i + + )
{
model . materials [ model . meshMaterial [ i ] ] . maps [ MAP_DIFFUSE ] . color = tint ;
Color c = model . materials [ model . meshMaterial [ i ] ] . maps [ MAP_DIFFUSE ] . color ;
Color s = c ;
c . r = ( ( c . r / 255 ) * ( tint . r / 255 ) ) * 255 ;
c . g = ( ( c . g / 255 ) * ( tint . g / 255 ) ) * 255 ;
c . b = ( ( c . b / 255 ) * ( tint . b / 255 ) ) * 255 ;
c . a = ( ( c . a / 255 ) * ( tint . a / 255 ) ) * 255 ;
model . materials [ model . meshMaterial [ i ] ] . maps [ MAP_DIFFUSE ] . color = c ;
rlDrawMesh ( model . meshes [ i ] , model . materials [ model . meshMaterial [ i ] ] , model . transform ) ;
model . materials [ model . meshMaterial [ i ] ] . maps [ MAP_DIFFUSE ] . color = s ;
}
}
@ -3344,6 +3351,92 @@ static unsigned char *DecodeBase64(char *input, int *size)
return buf ;
}
/ / static Texture LoadTextureFromCGLTFTextureView ( cgltf_texture_view * view , Color tint , char * texPath )
static Texture LoadTextureFromCGLTFTextureView ( cgltf_image * image , Color tint , const char * texPath )
{
Texture texture = { 0 } ;
/ / cgltf_image * image = view - > texture - > image ;
if ( image - > uri )
{
if ( ( strlen ( image - > uri ) > 5 ) & &
( image - > uri [ 0 ] = = ' d ' ) & &
( image - > uri [ 1 ] = = ' a ' ) & &
( image - > uri [ 2 ] = = ' t ' ) & &
( image - > uri [ 3 ] = = ' a ' ) & &
( image - > uri [ 4 ] = = ' : ' ) )
{
/ / Data URI
/ / Format : data : < mediatype > ; base64 , < data >
/ / Find the comma
int i = 0 ;
while ( ( image - > uri [ i ] ! = ' , ' ) & & ( image - > uri [ i ] ! = 0 ) )
i + + ;
if ( image - > uri [ i ] = = 0 )
TraceLog ( LOG_WARNING , " Invalid data URI " ) ;
else
{
int size ;
unsigned char * data = DecodeBase64 ( image - > uri + i + 1 , & size ) ;
int w , h ;
unsigned char * raw = stbi_load_from_memory ( data , size , & w , & h , NULL , 4 ) ;
Image rimage = LoadImagePro ( raw , w , h , UNCOMPRESSED_R8G8B8A8 ) ;
ImageColorTint ( & rimage , tint ) ;
texture = LoadTextureFromImage ( rimage ) ;
UnloadImage ( rimage ) ;
}
}
else
{
char * textureName = image - > uri ;
char * texturePath = RL_MALLOC ( strlen ( texPath ) + strlen ( textureName ) + 2 ) ;
strcpy ( texturePath , texPath ) ;
strcat ( texturePath , " / " ) ;
strcat ( texturePath , textureName ) ;
Image rimage = LoadImage ( texturePath ) ;
ImageColorTint ( & rimage , tint ) ;
texture = LoadTextureFromImage ( rimage ) ;
UnloadImage ( rimage ) ;
RL_FREE ( texturePath ) ;
}
}
else if ( image - > buffer_view )
{
unsigned char * data = RL_MALLOC ( image - > buffer_view - > size ) ;
int n = image - > buffer_view - > offset ;
int stride = image - > buffer_view - > stride ? image - > buffer_view - > stride : 1 ;
for ( int i = 0 ; i < image - > buffer_view - > size ; i + + )
{
data [ i ] = ( ( unsigned char * ) image - > buffer_view - > buffer - > data ) [ n ] ;
n + = stride ;
}
int w , h ;
unsigned char * raw = stbi_load_from_memory ( data , image - > buffer_view - > size , & w , & h , NULL , 4 ) ;
Image rimage = LoadImagePro ( raw , w , h , UNCOMPRESSED_R8G8B8A8 ) ;
ImageColorTint ( & rimage , tint ) ;
texture = LoadTextureFromImage ( rimage ) ;
UnloadImage ( rimage ) ;
free ( raw ) ;
free ( data ) ;
}
else
{
Image rimage = LoadImageEx ( & tint , 1 , 1 ) ;
texture = LoadTextureFromImage ( rimage ) ;
UnloadImage ( rimage ) ;
}
return texture ;
}
/ / Load glTF mesh data
static Model LoadGLTF ( const char * fileName )
{
@ -3426,106 +3519,49 @@ static Model LoadGLTF(const char *fileName)
for ( int i = 0 ; i < model . meshCount ; i + + ) model . meshes [ i ] . vboId = ( unsigned int * ) RL_CALLOC ( MAX_MESH_VBO , sizeof ( unsigned int ) ) ;
/ / For each material
for ( int i = 0 ; i < model . materialCount - 1 ; i + + )
{
Color tint = WHITE ;
Texture2D texture = { 0 } ;
model . materials [ i ] = LoadMaterialDefault ( ) ;
Color tint = ( Color ) { 255 , 255 , 255 , 255 } ;
const char * texPath = GetDirectoryPath ( fileName ) ;
if ( data - > materials [ i ] . has_pbr_metallic_roughness )
{
tint . r = ( unsigned char ) ( data - > materials [ i ] . pbr_metallic_roughness . base_color_factor [ 0 ] * 255.99f ) ;
tint . g = ( unsigned char ) ( data - > materials [ i ] . pbr_metallic_roughness . base_color_factor [ 1 ] * 255.99f ) ;
tint . b = ( unsigned char ) ( data - > materials [ i ] . pbr_metallic_roughness . base_color_factor [ 2 ] * 255.99f ) ;
tint . a = ( unsigned char ) ( data - > materials [ i ] . pbr_metallic_roughness . base_color_factor [ 3 ] * 255.99f ) ;
}
else
{
tint . r = 1.0f ;
tint . g = 1.0f ;
tint . b = 1.0f ;
tint . a = 1.0f ;
}
/ / 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 ;
if ( data - > materials [ i ] . has_pbr_metallic_roughness )
{
cgltf_image * img = data - > materials [ i ] . pbr_metallic_roughness . base_color_texture . texture - > image ;
if ( img - > uri )
{
if ( ( strlen ( img - > uri ) > 5 ) & &
( img - > uri [ 0 ] = = ' d ' ) & &
( img - > uri [ 1 ] = = ' a ' ) & &
( img - > uri [ 2 ] = = ' t ' ) & &
( img - > uri [ 3 ] = = ' a ' ) & &
( img - > uri [ 4 ] = = ' : ' ) )
{
/ / Data URI
/ / Format : data : < mediatype > ; base64 , < data >
/ / Find the comma
int i = 0 ;
while ( ( img - > uri [ i ] ! = ' , ' ) & & ( img - > uri [ i ] ! = 0 ) ) i + + ;
if ( model . materials [ i ] . name & & data - > materials [ i ] . name ) {
strcpy ( model . materials [ i ] . name , data - > materials [ i ] . name ) ;
}
if ( img - > uri [ i ] = = 0 ) TraceLog ( LOG_WARNING , " [%s] Invalid data URI " , fileName ) ;
else
{
int size ;
unsigned char * data = DecodeBase64 ( img - > uri + i + 1 , & size ) ;
/ / 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 ) ;
int w , h ;
unsigned char * raw = stbi_load_from_memory ( data , size , & w , & h , NULL , 4 ) ;
model . materials [ i ] . maps [ MAP_ROUGHNESS ] . color = tint ;
Image image = LoadImagePro ( raw , w , h , UNCOMPRESSED_R8G8B8A8 ) ;
ImageColorTint ( & image , tint ) ;
texture = LoadTextureFromImage ( image ) ;
UnloadImage ( image ) ;
}
}
else
{
char * textureName = img - > uri ;
char * texturePath = RL_MALLOC ( strlen ( texPath ) + strlen ( textureName ) + 2 ) ;
strcpy ( texturePath , texPath ) ;
strcat ( texturePath , " / " ) ;
strcat ( texturePath , textureName ) ;
Image image = LoadImage ( texturePath ) ;
ImageColorTint ( & image , tint ) ;
texture = LoadTextureFromImage ( image ) ;
UnloadImage ( image ) ;
RL_FREE ( texturePath ) ;
}
if ( data - > materials [ i ] . pbr_metallic_roughness . base_color_texture . texture ) {
model . materials [ i ] . maps [ MAP_ALBEDO ] . texture = LoadTextureFromCGLTFTextureView ( data - > materials [ i ] . pbr_metallic_roughness . base_color_texture . texture - > image , tint , texPath ) ;
}
else if ( img - > buffer_view )
{
unsigned char * data = RL_MALLOC ( img - > buffer_view - > size ) ;
int n = img - > buffer_view - > offset ;
int stride = img - > buffer_view - > stride ? img - > buffer_view - > stride : 1 ;
for ( int i = 0 ; i < img - > buffer_view - > size ; i + + )
{
data [ i ] = ( ( unsigned char * ) img - > buffer_view - > buffer - > data ) [ n ] ;
n + = stride ;
}
/ / tint isn ' t need for other textures . . pass null or clear ? ( try full white because of mixing ( multiplying * white has no effect ) )
tint = ( Color ) { 255 , 255 , 255 , 255 } ;
int w , h ;
unsigned char * raw = stbi_load_from_memory ( data , img - > buffer_view - > size , & w , & h , NULL , 4 ) ;
if ( data - > materials [ i ] . pbr_metallic_roughness . metallic_roughness_texture . texture ) {
model . materials [ i ] . maps [ MAP_ROUGHNESS ] . texture = LoadTextureFromCGLTFTextureView ( data - > materials [ i ] . pbr_metallic_roughness . metallic_roughness_texture . texture - > image , tint , texPath ) ;
}
model . materials [ i ] . maps [ MAP_ROUGHNESS ] . value = roughness ;
model . materials [ i ] . maps [ MAP_METALNESS ] . value = metallic ;
Image image = LoadImagePro ( raw , w , h , UNCOMPRESSED_R8G8B8A8 ) ;
ImageColorTint ( & image , tint ) ;
texture = LoadTextureFromImage ( image ) ;
UnloadImage ( image ) ;
if ( data - > materials [ i ] . normal_texture . texture ) {
model . materials [ i ] . maps [ MAP_NORMAL ] . texture = LoadTextureFromCGLTFTextureView ( data - > materials [ i ] . normal_texture . texture - > image , tint , texPath ) ;
}
else
{
Image image = LoadImageEx ( & tint , 1 , 1 ) ;
texture = LoadTextureFromImage ( image ) ;
UnloadImage ( image ) ;
if ( data - > materials [ i ] . occlusion_texture . texture ) {
model . materials [ i ] . maps [ MAP_OCCLUSION ] . texture = LoadTextureFromCGLTFTextureView ( data - > materials [ i ] . occlusion_texture . texture - > image , tint , texPath ) ;
}
model . materials [ i ] = LoadMaterialDefault ( ) ;
model . materials [ i ] . maps [ MAP_DIFFUSE ] . texture = texture ;
}
}