From dee651069c1ec2addfd38a925fab59c758fffb6b Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 6 Apr 2015 23:33:13 -0700 Subject: [PATCH 1/3] adding support for color attribute in FBX, and displaying it correctly --- libraries/fbx/src/FBXReader.cpp | 59 ++++++++++++++++++++++++++++ libraries/render-utils/src/model.slf | 3 +- libraries/render-utils/src/model.slv | 3 +- 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index 1073bc5c31..92ede537d1 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -458,6 +458,18 @@ FBXNode parseFBX(QIODevice* device) { return top; } +QVector createVec4Vector(const QVector& doubleVector) { + QVector values; + for (const double* it = doubleVector.constData(), *end = it + (doubleVector.size() / 4 * 4); it != end; ) { + float x = *it++; + float y = *it++; + float z = *it++; + float w = *it++; + values.append(glm::vec4(x, y, z, w)); + } + return values; +} + QVector createVec3Vector(const QVector& doubleVector) { QVector values; for (const double* it = doubleVector.constData(), *end = it + (doubleVector.size() / 3 * 3); it != end; ) { @@ -739,6 +751,11 @@ public: bool normalsByVertex; QVector normals; QVector normalIndices; + + bool colorsByVertex; + QVector colors; + QVector colorIndices; + QVector texCoords; QVector texCoordIndices; @@ -776,6 +793,23 @@ void appendIndex(MeshData& data, QVector& indices, int index) { } } + + glm::vec4 color; + bool hasColors = (data.colors.size() > 1); + if (hasColors) { + int colorIndex = data.colorsByVertex ? vertexIndex : index; + if (data.colorIndices.isEmpty()) { + if (colorIndex < data.colors.size()) { + color = data.colors.at(colorIndex); + } + } else if (colorIndex < data.colorIndices.size()) { + colorIndex = data.colorIndices.at(colorIndex); + if (colorIndex >= 0 && colorIndex < data.colors.size()) { + color = data.colors.at(colorIndex); + } + } + } + if (data.texCoordIndices.isEmpty()) { if (index < data.texCoords.size()) { vertex.texCoord = data.texCoords.at(index); @@ -810,6 +844,9 @@ void appendIndex(MeshData& data, QVector& indices, int index) { data.extracted.mesh.vertices.append(position); data.extracted.mesh.normals.append(normal); data.extracted.mesh.texCoords.append(vertex.texCoord); + if (hasColors) { + data.extracted.mesh.colors.append(glm::vec3(color)); + } if (hasMoreTexcoords) { data.extracted.mesh.texCoords1.append(vertex.texCoord1); } @@ -852,6 +889,28 @@ ExtractedMesh extractMesh(const FBXNode& object, unsigned int& meshIndex) { // hack to work around wacky Makehuman exports data.normalsByVertex = true; } + } else if (child.name == "LayerElementColor") { + data.colorsByVertex = false; + bool indexToDirect = false; + foreach (const FBXNode& subdata, child.children) { + if (subdata.name == "Colors") { + data.colors = createVec4Vector(getDoubleVector(subdata)); + + } else if (subdata.name == "ColorsIndex") { + data.colorIndices = getIntVector(subdata); + + } else if (subdata.name == "MappingInformationType" && subdata.properties.at(0) == "ByVertice") { + data.colorsByVertex = true; + + } else if (subdata.name == "ReferenceInformationType" && subdata.properties.at(0) == "IndexToDirect") { + indexToDirect = true; + } + } + if (indexToDirect && data.normalIndices.isEmpty()) { + // hack to work around wacky Makehuman exports + data.colorsByVertex = true; + } + } else if (child.name == "LayerElementUV") { if (child.properties.at(0).toInt() == 0) { AttributeData attrib; diff --git a/libraries/render-utils/src/model.slf b/libraries/render-utils/src/model.slf index be465ed908..15b64144bf 100755 --- a/libraries/render-utils/src/model.slf +++ b/libraries/render-utils/src/model.slf @@ -19,6 +19,7 @@ uniform sampler2D diffuseMap; // the interpolated normal +varying vec3 vertexColor; varying vec4 normal; void main(void) { @@ -30,7 +31,7 @@ void main(void) { packDeferredFragment( normalize(normal.xyz), evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a), - getMaterialDiffuse(mat) * diffuse.rgb, + getMaterialDiffuse(mat) * diffuse.rgb * vertexColor, getMaterialSpecular(mat), getMaterialShininess(mat)); } diff --git a/libraries/render-utils/src/model.slv b/libraries/render-utils/src/model.slv index 21c9238273..ca959b4e6c 100755 --- a/libraries/render-utils/src/model.slv +++ b/libraries/render-utils/src/model.slv @@ -21,12 +21,13 @@ uniform mat4 texcoordMatrices[MAX_TEXCOORDS]; // the interpolated normal +varying vec3 vertexColor; varying vec4 normal; void main(void) { // pass along the diffuse color - gl_FrontColor = gl_Color; + vertexColor = gl_Color.xyz; // and the texture coordinates gl_TexCoord[0] = texcoordMatrices[0] * vec4(gl_MultiTexCoord0.xy, 0.0, 1.0); From 88afb3cedccc69c2ac9cdef60d006dc76688efcf Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 7 Apr 2015 10:04:51 -0700 Subject: [PATCH 2/3] solution to the color attribute case --- libraries/render-utils/src/Model.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 7c8bc3b35c..9f4230a0f3 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -2504,7 +2504,7 @@ int Model::renderMeshesFromList(QVector& list, gpu::Batch& batch, RenderMod } if (mesh.colors.isEmpty()) { - GLBATCH(glColor4f)(0.0f, 1.0f, 0.0f, 1.0f); + GLBATCH(glColor4f)(1.0f, 1.0f, 1.0f, 1.0f); } qint64 offset = 0; From ad9129b552e7d86f5b06a9f7a3801ca61e7fc053 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 7 Apr 2015 14:26:45 -0700 Subject: [PATCH 3/3] Fixing all the shaders for entities to work correctly with the now supported color attribute field --- libraries/render-utils/src/model.slf | 6 ++++-- libraries/render-utils/src/model.slv | 6 +++--- libraries/render-utils/src/model_lightmap.slf | 4 +++- libraries/render-utils/src/model_lightmap.slv | 5 ++++- libraries/render-utils/src/model_lightmap_normal_map.slf | 4 +++- libraries/render-utils/src/model_lightmap_normal_map.slv | 4 +++- .../render-utils/src/model_lightmap_normal_specular_map.slf | 5 ++++- libraries/render-utils/src/model_lightmap_specular_map.slf | 4 +++- libraries/render-utils/src/model_normal_map.slf | 4 +++- libraries/render-utils/src/model_normal_map.slv | 4 +++- libraries/render-utils/src/model_normal_specular_map.slf | 4 +++- libraries/render-utils/src/model_specular_map.slf | 4 +++- libraries/render-utils/src/model_translucent.slf | 4 +++- libraries/render-utils/src/skin_model.slv | 4 +++- libraries/render-utils/src/skin_model_normal_map.slv | 4 +++- 15 files changed, 48 insertions(+), 18 deletions(-) diff --git a/libraries/render-utils/src/model.slf b/libraries/render-utils/src/model.slf index 15b64144bf..adf80d01bf 100755 --- a/libraries/render-utils/src/model.slf +++ b/libraries/render-utils/src/model.slf @@ -19,9 +19,11 @@ uniform sampler2D diffuseMap; // the interpolated normal -varying vec3 vertexColor; varying vec4 normal; +varying vec3 color; + + void main(void) { // Fetch diffuse map vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st); @@ -31,7 +33,7 @@ void main(void) { packDeferredFragment( normalize(normal.xyz), evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a), - getMaterialDiffuse(mat) * diffuse.rgb * vertexColor, + getMaterialDiffuse(mat) * diffuse.rgb * color, getMaterialSpecular(mat), getMaterialShininess(mat)); } diff --git a/libraries/render-utils/src/model.slv b/libraries/render-utils/src/model.slv index ca959b4e6c..f4511da944 100755 --- a/libraries/render-utils/src/model.slv +++ b/libraries/render-utils/src/model.slv @@ -19,15 +19,15 @@ const int MAX_TEXCOORDS = 2; uniform mat4 texcoordMatrices[MAX_TEXCOORDS]; - // the interpolated normal -varying vec3 vertexColor; varying vec4 normal; +varying vec3 color; + void main(void) { // pass along the diffuse color - vertexColor = gl_Color.xyz; + color = gl_Color.xyz; // and the texture coordinates gl_TexCoord[0] = texcoordMatrices[0] * vec4(gl_MultiTexCoord0.xy, 0.0, 1.0); diff --git a/libraries/render-utils/src/model_lightmap.slf b/libraries/render-utils/src/model_lightmap.slf index 9db31bf1ad..b7660da16d 100755 --- a/libraries/render-utils/src/model_lightmap.slf +++ b/libraries/render-utils/src/model_lightmap.slf @@ -26,6 +26,8 @@ uniform vec2 emissiveParams; // the interpolated normal varying vec4 normal; +varying vec3 color; + // the interpolated texcoord1 varying vec2 interpolatedTexcoord1; @@ -39,7 +41,7 @@ void main(void) { packDeferredFragmentLightmap( normalize(normal.xyz), evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a), - getMaterialDiffuse(mat) * diffuse.rgb, + getMaterialDiffuse(mat) * diffuse.rgb * color, getMaterialSpecular(mat), getMaterialShininess(mat), (vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb)); diff --git a/libraries/render-utils/src/model_lightmap.slv b/libraries/render-utils/src/model_lightmap.slv index f24ba4e53d..56b34a5aa8 100755 --- a/libraries/render-utils/src/model_lightmap.slv +++ b/libraries/render-utils/src/model_lightmap.slv @@ -28,9 +28,12 @@ varying vec4 normal; // the interpolated texcoord1 varying vec2 interpolatedTexcoord1; +varying vec3 color; + + void main(void) { // pass along the diffuse color - gl_FrontColor = gl_Color; + color = gl_Color.xyz; // and the texture coordinates gl_TexCoord[0] = texcoordMatrices[0] * vec4(gl_MultiTexCoord0.xy, 0.0, 1.0); diff --git a/libraries/render-utils/src/model_lightmap_normal_map.slf b/libraries/render-utils/src/model_lightmap_normal_map.slf index a7b6494ee5..7120fd61de 100755 --- a/libraries/render-utils/src/model_lightmap_normal_map.slf +++ b/libraries/render-utils/src/model_lightmap_normal_map.slf @@ -34,6 +34,8 @@ varying vec4 interpolatedTangent; varying vec2 interpolatedTexcoord1; +varying vec3 color; + void main(void) { // compute the view normal from the various bits vec3 normalizedNormal = normalize(vec3(interpolatedNormal)); @@ -52,7 +54,7 @@ void main(void) { packDeferredFragmentLightmap( normalize(viewNormal.xyz), evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a), - getMaterialDiffuse(mat) * diffuse.rgb, + getMaterialDiffuse(mat) * diffuse.rgb * color, getMaterialSpecular(mat), getMaterialShininess(mat), (vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb)); diff --git a/libraries/render-utils/src/model_lightmap_normal_map.slv b/libraries/render-utils/src/model_lightmap_normal_map.slv index a1413b1530..bfa8bc2cc2 100755 --- a/libraries/render-utils/src/model_lightmap_normal_map.slv +++ b/libraries/render-utils/src/model_lightmap_normal_map.slv @@ -34,13 +34,15 @@ varying vec4 interpolatedTangent; // the interpolated texcoord1 varying vec2 interpolatedTexcoord1; +varying vec3 color; + void main(void) { // transform and store the normal and tangent for interpolation //interpolatedNormal = gl_ModelViewMatrix * vec4(gl_Normal, 0.0); //interpolatedTangent = gl_ModelViewMatrix * vec4(tangent, 0.0); // pass along the diffuse color - gl_FrontColor = gl_Color; + color = gl_Color.xyz; // and the texture coordinates gl_TexCoord[0] = texcoordMatrices[0] * vec4(gl_MultiTexCoord0.xy, 0.0, 1.0); diff --git a/libraries/render-utils/src/model_lightmap_normal_specular_map.slf b/libraries/render-utils/src/model_lightmap_normal_specular_map.slf index e5daae4160..2c57c14803 100755 --- a/libraries/render-utils/src/model_lightmap_normal_specular_map.slf +++ b/libraries/render-utils/src/model_lightmap_normal_specular_map.slf @@ -37,6 +37,9 @@ varying vec4 interpolatedTangent; varying vec2 interpolatedTexcoord1; +varying vec3 color; + + void main(void) { // compute the view normal from the various bits vec3 normalizedNormal = normalize(vec3(interpolatedNormal)); @@ -56,7 +59,7 @@ void main(void) { packDeferredFragmentLightmap( normalize(viewNormal.xyz), evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a), - getMaterialDiffuse(mat) * diffuse.rgb, + getMaterialDiffuse(mat) * diffuse.rgb * color, specular, // no use of getMaterialSpecular(mat) getMaterialShininess(mat), (vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb)); diff --git a/libraries/render-utils/src/model_lightmap_specular_map.slf b/libraries/render-utils/src/model_lightmap_specular_map.slf index 820ded5cad..e4bb682601 100755 --- a/libraries/render-utils/src/model_lightmap_specular_map.slf +++ b/libraries/render-utils/src/model_lightmap_specular_map.slf @@ -31,6 +31,8 @@ varying vec4 normal; varying vec2 interpolatedTexcoord1; +varying vec3 color; + void main(void) { // set the diffuse, normal, specular data vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st); @@ -42,7 +44,7 @@ void main(void) { packDeferredFragmentLightmap( normalize(normal.xyz), evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a), - getMaterialDiffuse(mat) * diffuse.rgb, + getMaterialDiffuse(mat) * diffuse.rgb * color, specular, // no use of getMaterialSpecular(mat) getMaterialShininess(mat), (vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb)); diff --git a/libraries/render-utils/src/model_normal_map.slf b/libraries/render-utils/src/model_normal_map.slf index 6a74ddaca0..5a4bc0e1bb 100755 --- a/libraries/render-utils/src/model_normal_map.slf +++ b/libraries/render-utils/src/model_normal_map.slf @@ -28,6 +28,8 @@ varying vec4 interpolatedNormal; // the interpolated tangent varying vec4 interpolatedTangent; +varying vec3 color; + void main(void) { // compute the view normal from the various bits vec3 normalizedNormal = normalize(vec3(interpolatedNormal)); @@ -44,7 +46,7 @@ void main(void) { packDeferredFragment( normalize(viewNormal.xyz), evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a), - getMaterialDiffuse(mat) * diffuse.rgb, + getMaterialDiffuse(mat) * diffuse.rgb * color, getMaterialSpecular(mat), getMaterialShininess(mat)); } diff --git a/libraries/render-utils/src/model_normal_map.slv b/libraries/render-utils/src/model_normal_map.slv index 9983310b52..e702b446b8 100755 --- a/libraries/render-utils/src/model_normal_map.slv +++ b/libraries/render-utils/src/model_normal_map.slv @@ -29,13 +29,15 @@ varying vec4 interpolatedNormal; // the interpolated tangent varying vec4 interpolatedTangent; +varying vec3 color; + void main(void) { // transform and store the normal and tangent for interpolation //interpolatedNormal = gl_ModelViewMatrix * vec4(gl_Normal, 0.0); //interpolatedTangent = gl_ModelViewMatrix * vec4(tangent, 0.0); // pass along the diffuse color - gl_FrontColor = gl_Color; + color = gl_Color.xyz; // and the texture coordinates gl_TexCoord[0] = texcoordMatrices[0] * vec4(gl_MultiTexCoord0.xy, 0.0, 1.0); diff --git a/libraries/render-utils/src/model_normal_specular_map.slf b/libraries/render-utils/src/model_normal_specular_map.slf index 4d70e659e6..0fc021a31d 100755 --- a/libraries/render-utils/src/model_normal_specular_map.slf +++ b/libraries/render-utils/src/model_normal_specular_map.slf @@ -31,6 +31,8 @@ varying vec4 interpolatedNormal; // the interpolated tangent varying vec4 interpolatedTangent; +varying vec3 color; + void main(void) { // compute the view normal from the various bits vec3 normalizedNormal = normalize(vec3(interpolatedNormal)); @@ -49,7 +51,7 @@ void main(void) { packDeferredFragment( normalize(viewNormal.xyz), evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a), - getMaterialDiffuse(mat) * diffuse.rgb, + getMaterialDiffuse(mat) * diffuse.rgb * color, specular, //getMaterialSpecular(mat), getMaterialShininess(mat)); } diff --git a/libraries/render-utils/src/model_specular_map.slf b/libraries/render-utils/src/model_specular_map.slf index e50d2c452d..a0203d74af 100755 --- a/libraries/render-utils/src/model_specular_map.slf +++ b/libraries/render-utils/src/model_specular_map.slf @@ -25,6 +25,8 @@ uniform sampler2D specularMap; // the interpolated normal varying vec4 normal; +varying vec3 color; + void main(void) { // set the diffuse, normal, specular data vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st); @@ -35,7 +37,7 @@ void main(void) { packDeferredFragment( normalize(normal.xyz), evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a), - getMaterialDiffuse(mat) * diffuse.rgb, + getMaterialDiffuse(mat) * diffuse.rgb * color, specular, //getMaterialSpecular(mat), getMaterialShininess(mat)); } diff --git a/libraries/render-utils/src/model_translucent.slf b/libraries/render-utils/src/model_translucent.slf index 91592e07de..9b8eb97f70 100755 --- a/libraries/render-utils/src/model_translucent.slf +++ b/libraries/render-utils/src/model_translucent.slf @@ -21,6 +21,8 @@ uniform sampler2D diffuseMap; varying vec4 normal; +varying vec3 color; + void main(void) { // Fetch diffuse map @@ -31,7 +33,7 @@ void main(void) { packDeferredFragmentTranslucent( normalize(normal.xyz), getMaterialOpacity(mat) * diffuse.a, - getMaterialDiffuse(mat) * diffuse.rgb, + getMaterialDiffuse(mat) * diffuse.rgb * color, getMaterialSpecular(mat), getMaterialShininess(mat)); diff --git a/libraries/render-utils/src/skin_model.slv b/libraries/render-utils/src/skin_model.slv index f65d5a8bdc..f475cbd1f5 100755 --- a/libraries/render-utils/src/skin_model.slv +++ b/libraries/render-utils/src/skin_model.slv @@ -28,6 +28,8 @@ attribute vec4 clusterWeights; // the interpolated normal varying vec4 normal; +varying vec3 color; + void main(void) { vec4 position = vec4(0.0, 0.0, 0.0, 0.0); normal = vec4(0.0, 0.0, 0.0, 0.0); @@ -39,7 +41,7 @@ void main(void) { } // pass along the diffuse color - gl_FrontColor = gl_Color; + color = gl_Color.xyz; // and the texture coordinates gl_TexCoord[0] = texcoordMatrices[0] * vec4(gl_MultiTexCoord0.xy, 0.0, 1.0); diff --git a/libraries/render-utils/src/skin_model_normal_map.slv b/libraries/render-utils/src/skin_model_normal_map.slv index 19e0c041f0..bbc8f81d12 100755 --- a/libraries/render-utils/src/skin_model_normal_map.slv +++ b/libraries/render-utils/src/skin_model_normal_map.slv @@ -34,6 +34,8 @@ varying vec4 interpolatedNormal; // the interpolated tangent varying vec4 interpolatedTangent; +varying vec3 color; + void main(void) { vec4 interpolatedPosition = vec4(0.0, 0.0, 0.0, 0.0); interpolatedNormal = vec4(0.0, 0.0, 0.0, 0.0); @@ -47,7 +49,7 @@ void main(void) { } // pass along the diffuse color - gl_FrontColor = gl_Color; + color = gl_Color.xyz; // and the texture coordinates gl_TexCoord[0] = texcoordMatrices[0] * vec4(gl_MultiTexCoord0.xy, 0.0, 1.0);