Implement vertex color attribute for GLTF and IQM (#1790)

Added a simple cube with vertex colors for testing both.
This commit is contained in:
Hristo Stamenov 2021-05-26 21:23:13 +03:00 committed by GitHub
parent c5ef96272f
commit 470574517a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 58 additions and 3 deletions

View File

@ -21,7 +21,7 @@
#include <stdlib.h>
#define MAX_MODELS 6
#define MAX_MODELS 7
int main(void)
{
@ -30,7 +30,7 @@ int main(void)
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [models] example - model animation");
InitWindow(screenWidth, screenHeight, "raylib [models] example - model");
// Define the camera to look into our 3d world
Camera camera = { 0 };
@ -48,6 +48,7 @@ int main(void)
model[3] = LoadModel("resources/gltf/BoxAnimated.glb");
model[4] = LoadModel("resources/gltf/AnimatedTriangle.gltf");
model[5] = LoadModel("resources/gltf/AnimatedMorphCube.glb");
model[6] = LoadModel("resources/gltf/vertex_colored_object.glb");
int currentModel = 0;

View File

@ -3458,7 +3458,7 @@ static Model LoadIQM(const char *fileName)
IQM_TANGENT = 3, // NOTE: Tangents unused by default
IQM_BLENDINDEXES = 4,
IQM_BLENDWEIGHTS = 5,
IQM_COLOR = 6, // NOTE: Vertex colors unused by default
IQM_COLOR = 6,
IQM_CUSTOM = 0x10 // NOTE: Custom vertex values unused by default
};
@ -3474,6 +3474,7 @@ static Model LoadIQM(const char *fileName)
float *text = NULL;
char *blendi = NULL;
unsigned char *blendw = NULL;
unsigned char *color = NULL;
// In case file can not be read, return an empty model
if (fileDataPtr == NULL) return model;
@ -3662,6 +3663,25 @@ static Model LoadIQM(const char *fileName)
}
}
} break;
case IQM_COLOR:
{
color = RL_MALLOC(iqmHeader->num_vertexes*4*sizeof(unsigned char));
//fseek(iqmFile, va[i].offset, SEEK_SET);
//fread(blendw, iqmHeader->num_vertexes*4*sizeof(unsigned char), 1, iqmFile);
memcpy(color, fileDataPtr + va[i].offset, iqmHeader->num_vertexes*4*sizeof(unsigned char));
for (unsigned int m = 0; m < iqmHeader->num_meshes; m++)
{
model.meshes[m].colors = RL_CALLOC(model.meshes[m].vertexCount*4, sizeof(unsigned char));
int vCounter = 0;
for (unsigned int i = imesh[m].first_vertex*4; i < (imesh[m].first_vertex + imesh[m].num_vertexes)*4; i++)
{
model.meshes[m].colors[vCounter] = color[i];
vCounter++;
}
}
} break;
}
}
@ -4301,6 +4321,40 @@ static Model LoadGLTF(const char *fileName)
TRACELOG(LOG_WARNING, "MODEL: [%s] glTF normals must be float or int", fileName);
}
}
else if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_color)
{
cgltf_accessor *acc = data->meshes[i].primitives[p].attributes[j].data;
model.meshes[primitiveIndex].colors = RL_MALLOC(acc->count*4*sizeof(unsigned char));
if (acc->component_type == cgltf_component_type_r_8u)
{
for (int a = 0; a < acc->count; a++)
{
GLTFReadValue(acc, a, model.meshes[primitiveIndex].colors + (a*4), 4, sizeof(unsigned char));
}
}
if (acc->component_type == cgltf_component_type_r_16u)
{
TRACELOG(LOG_WARNING, "MODEL: [%s] converting glTF colors to unsigned char", fileName);
for (int a = 0; a < acc->count; a++)
{
unsigned short readValue[4];
for (int a = 0; a < acc->count; a++)
{
GLTFReadValue(acc, a, readValue, 4, sizeof(unsigned short));
// 257 = 65535/255
model.meshes[primitiveIndex].colors[(a*4) + 0] = (unsigned char)(readValue[0] / 257);
model.meshes[primitiveIndex].colors[(a*4) + 1] = (unsigned char)(readValue[1] / 257);
model.meshes[primitiveIndex].colors[(a*4) + 2] = (unsigned char)(readValue[2] / 257);
model.meshes[primitiveIndex].colors[(a*4) + 3] = (unsigned char)(readValue[3] / 257);
}
}
}
else
{
TRACELOG(LOG_WARNING, "MODEL: [%s] glTF colors must be uchar or ushort", fileName);
}
}
}
cgltf_accessor *acc = data->meshes[i].primitives[p].indices;