Przeglądaj źródła

Added support for multiple UV sets in encoder for both Collada and FBX.
Fixed lightmapping support in colored and textured unlit shaders.

Steve Grenier 13 lat temu
rodzic
commit
a111e201c7

+ 45 - 40
gameplay-encoder/src/DAESceneEncoder.cpp

@@ -1611,7 +1611,7 @@ Mesh* DAESceneEncoder::loadMesh(const domMesh* meshElement, const std::string& g
     }
     mesh = new Mesh();
     mesh->setId(geometryId.c_str());
-    
+
     std::vector<DAEPolygonInput*> polygonInputs;
 
     // Quickly just go through each triangles array and make sure they have the same number of inputs
@@ -1819,7 +1819,7 @@ Mesh* DAESceneEncoder::loadMesh(const domMesh* meshElement, const std::string& g
                                 break;
                             case 'b':
                             case 'B':
-                                vertex.diffuse.z = (float)source.get(index + i); // blue
+                                vertex.diffuse.z = (float)source.get(index+ i ); // blue
                                 break;
                             case 'a':
                             case 'A':
@@ -1849,34 +1849,43 @@ Mesh* DAESceneEncoder::loadMesh(const domMesh* meshElement, const std::string& g
                 break;
 
             case TEXCOORD0:
-                vertex.hasTexCoord = true;
-                if (polygonInputs[k]->accessor)
-                {
-                    // TODO: This assumes (s, t) are first
-                    unsigned int stride = (unsigned int)polygonInputs[k]->accessor->getStride();
-                    if (polyIndexInt < 0)
-                    {
-                        unsigned int i = (unsigned int)((int)polygonInputs[k]->accessor->getCount()) + polyIndexInt;
-                        vertex.texCoord.x = (float)source.get(i * stride);
-                        vertex.texCoord.y = (float)source.get(i * stride + 1);
-                    }
-                    else
-                    {
-                        vertex.texCoord.x = (float)source.get(polyIndex * stride);
-                        vertex.texCoord.y = (float)source.get(polyIndex * stride + 1);
-                    }
-                }
-                else
+            case TEXCOORD1:
+            case TEXCOORD2:
+            case TEXCOORD3:
+            case TEXCOORD4:
+            case TEXCOORD5:
+            case TEXCOORD6:
+            case TEXCOORD7:
                 {
-                    vertex.texCoord.x = (float)source.get(polyIndex * 2);
-                    vertex.texCoord.y = (float)source.get(polyIndex * 2 + 1);
+                    unsigned int index = polygonInputs[k]->type - TEXCOORD0;
+                    //for (unsigned int i = 0; i < uvSetCount; ++i)
+                    //{
+                        vertex.hasTexCoord[index] = true;
+                        if (polygonInputs[k]->accessor)
+                        {
+                            // TODO: This assumes (s, t) are first
+                            unsigned int stride = (unsigned int)polygonInputs[k]->accessor->getStride();
+                            if (polyIndexInt < 0)
+                            {
+                                unsigned int i = (unsigned int)((int)polygonInputs[k]->accessor->getCount()) + polyIndexInt;
+                                vertex.texCoord[index].x = (float)source.get(i * stride);
+                                vertex.texCoord[index].y = (float)source.get(i * stride + 1);
+                            }
+                            else
+                            {
+                                vertex.texCoord[index].x = (float)source.get(polyIndex * stride);
+                                vertex.texCoord[index].y = (float)source.get(polyIndex * stride + 1);
+                            }
+                        }
+                        else
+                        {
+                            vertex.texCoord[index].x = (float)source.get(polyIndex * 2);
+                            vertex.texCoord[index].y = (float)source.get(polyIndex * 2 + 1);
+                        }
+                    //}
                 }
                 break;
 
-            case TEXCOORD1:
-                // TODO
-                break;
-
             default:
                 break;
             }
@@ -1909,13 +1918,6 @@ Mesh* DAESceneEncoder::loadMesh(const domMesh* meshElement, const std::string& g
         // Add our new subset for the mesh.
         mesh->addMeshPart(subset);
     }
-    
-    bool hasNormals = mesh->vertices[0].hasNormal;
-    bool hasDiffuses = mesh->vertices[0].hasDiffuse;
-    bool hasTangents = mesh->vertices[0].hasTangent;
-    bool hasBinormals = mesh->vertices[0].hasBinormal;
-    bool hasTexCoords = mesh->vertices[0].hasTexCoord;
-    bool hasWeights = mesh->vertices[0].hasWeights;
 
     // The order that the vertex elements are add to the list matters.
     // It should be the same order as how the Vertex data is written.
@@ -1924,32 +1926,35 @@ Mesh* DAESceneEncoder::loadMesh(const domMesh* meshElement, const std::string& g
     mesh->addVetexAttribute(POSITION, Vertex::POSITION_COUNT);
     
     // Normals
-    if (hasNormals)
+    if (mesh->vertices[0].hasNormal)
     {
         mesh->addVetexAttribute(NORMAL, Vertex::NORMAL_COUNT);
     }
     // Tangents
-    if (hasTangents)
+    if (mesh->vertices[0].hasTangent)
     {
         mesh->addVetexAttribute(TANGENT, Vertex::TANGENT_COUNT);
     }
     // Binormals
-    if (hasBinormals)
+    if (mesh->vertices[0].hasBinormal)
     {
         mesh->addVetexAttribute(BINORMAL, Vertex::BINORMAL_COUNT);
     }
     // Texture Coordinates
-    if (hasTexCoords)
+    for (unsigned int i = 0; i < MAX_UV_SETS; ++i)
     {
-        mesh->addVetexAttribute(TEXCOORD0, Vertex::TEXCOORD_COUNT);
+        if (mesh->vertices[0].hasTexCoord[i])
+        {
+            mesh->addVetexAttribute(TEXCOORD0 + i, Vertex::TEXCOORD_COUNT);
+        }
     }
     // Diffuse Color
-    if (hasDiffuses)
+    if (mesh->vertices[0].hasDiffuse)
     {
         mesh->addVetexAttribute(COLOR, Vertex::DIFFUSE_COUNT);
     }
     // Skinning BlendWeights BlendIndices
-    if (hasWeights)
+    if (mesh->vertices[0].hasWeights)
     {
         mesh->addVetexAttribute(BLENDWEIGHTS, Vertex::BLEND_WEIGHTS_COUNT);
         mesh->addVetexAttribute(BLENDINDICES, Vertex::BLEND_INDICES_COUNT);

+ 60 - 49
gameplay-encoder/src/FBXSceneEncoder.cpp

@@ -30,11 +30,14 @@ static float getFieldOfView(FbxCamera* fbxCamera);
  * Loads the texture coordinates from given mesh's polygon part into the vertex.
  * 
  * @param fbxMesh The mesh to get the polygon from.
- * @param polyIndex The index of the polygon.
- * @param posInPoly The position in the polygon.
+ * @param uvs The UV list to load tex coords from.
+ * @param uvSetIndex The UV set index of the uvs.
+ * @param polyIndex The index of the polygon in the mesh.
+ * @param posInPoly The position of the vertex in the polygon.
+ * @param meshVertexIndex The index of the vertex in the mesh.
  * @param vertex The vertex to copy the texture coordinates to.
  */
-static void loadTextureCoords(FbxMesh* fbxMesh, int polyIndex, int posInPoly, Vertex* vertex);
+static void loadTextureCoords(FbxMesh* fbxMesh, const FbxGeometryElementUV* uvs, int uvSetIndex, int polyIndex, int posInPoly, int meshVertexIndex, Vertex* vertex);
 
 /**
  * Loads the normal from the mesh and adds it to the given vertex.
@@ -851,6 +854,11 @@ Mesh* FBXSceneEncoder::loadMesh(FbxMesh* fbxMesh)
     std::vector<std::vector<Vector2> > weights;
     bool hasSkin = loadBlendWeights(fbxMesh, weights);
     
+    // Get list of uv sets for mesh
+    FbxStringList uvSetNameList;
+    fbxMesh->GetUVSetNames(uvSetNameList);
+    const int uvSetCount = uvSetNameList.GetCount();
+
     int vertexIndex = 0;
     FbxVector4* controlPoints = fbxMesh->GetControlPoints();
     const int polygonCount = fbxMesh->GetPolygonCount();
@@ -867,7 +875,15 @@ Mesh* FBXSceneEncoder::loadMesh(FbxMesh* fbxMesh)
             vertex.position.y = (float)position[1];
             vertex.position.z = (float)position[2];
 
-            loadTextureCoords(fbxMesh, polyIndex, posInPoly, &vertex);
+            // Load tex coords for all uv sets
+            for (int uvSetIndex = 0; uvSetIndex < uvSetCount; ++uvSetIndex)
+            {
+                const FbxGeometryElementUV* uvElement = fbxMesh->GetElementUV(uvSetNameList.GetStringAt(uvSetIndex));
+                if (uvElement)
+                    loadTextureCoords(fbxMesh, uvElement, uvSetIndex, polyIndex, posInPoly, vertexIndex, &vertex);
+            }
+
+            // Load other data
             loadNormal(fbxMesh, vertexIndex, controlPointIndex, &vertex);
             loadTangent(fbxMesh, vertexIndex, &vertex);
             loadBinormal(fbxMesh, vertexIndex, &vertex);
@@ -931,9 +947,12 @@ Mesh* FBXSceneEncoder::loadMesh(FbxMesh* fbxMesh)
         mesh->addVetexAttribute(BINORMAL, Vertex::BINORMAL_COUNT);
     }
     // Texture Coordinates
-    if (vertex.hasTexCoord)
+    for (unsigned int i = 0; i < MAX_UV_SETS; ++i)
     {
-        mesh->addVetexAttribute(TEXCOORD0, Vertex::TEXCOORD_COUNT);
+        if (vertex.hasTexCoord[i])
+        {
+            mesh->addVetexAttribute(TEXCOORD0 + i, Vertex::TEXCOORD_COUNT);
+        }
     }
     // Diffuse Color
     if (vertex.hasDiffuse)
@@ -1061,54 +1080,46 @@ float getFieldOfView(FbxCamera* fbxCamera)
     return (float)fieldOfViewY;
 }
 
-void loadTextureCoords(FbxMesh* fbxMesh, int polyIndex, int posInPoly, Vertex* vertex)
+void loadTextureCoords(FbxMesh* fbxMesh, const FbxGeometryElementUV* uvs, int uvSetIndex, int polyIndex, int posInPoly, int meshVertexIndex, Vertex* vertex)
 {
     assert(fbxMesh && polyIndex >=0 && posInPoly >= 0);
-    if (fbxMesh->GetElementUVCount() > 0)
+
+    const bool useIndex = uvs->GetReferenceMode() != FbxGeometryElement::eDirect;
+    const int indexCount = useIndex ? uvs->GetIndexArray().GetCount() : 0;
+    int uvIndex = -1;
+
+    switch (uvs->GetMappingMode())
     {
-        // Get only the first UV coordinates.
-        FbxGeometryElementUV* uv = fbxMesh->GetElementUV(0);
-        switch (uv->GetMappingMode())
+    case FbxGeometryElement::eByControlPoint:
         {
-        case FbxGeometryElement::eByControlPoint:
-            switch (uv->GetReferenceMode())
-            {
-            case FbxGeometryElement::eDirect:
-                vertex->hasTexCoord = true;
-                vertex->texCoord.x = (float)uv->GetDirectArray().GetAt(polyIndex)[0];
-                vertex->texCoord.y = (float)uv->GetDirectArray().GetAt(polyIndex)[1];
-                break;
-            case FbxGeometryElement::eIndexToDirect:
-                {
-                    int id = uv->GetIndexArray().GetAt(polyIndex);
-                    vertex->hasTexCoord = true;
-                    vertex->texCoord.x = (float)uv->GetDirectArray().GetAt(id)[0];
-                    vertex->texCoord.y = (float)uv->GetDirectArray().GetAt(id)[1];
-                }
-                break;
-            default:
-                break;
-            }
-            break;
-        case FbxGeometryElement::eByPolygonVertex:
-            {
-                int lTextureUVIndex = fbxMesh->GetTextureUVIndex(polyIndex, posInPoly);
-                switch (uv->GetReferenceMode())
-                {
-                case FbxGeometryElement::eDirect:
-                case FbxGeometryElement::eIndexToDirect:
-                    vertex->hasTexCoord = true;
-                    vertex->texCoord.x = (float)uv->GetDirectArray().GetAt(lTextureUVIndex)[0];
-                    vertex->texCoord.y = (float)uv->GetDirectArray().GetAt(lTextureUVIndex)[1];
-                    break;
-                default:
-                    break;
-                }
-            }
-            break;
-        default:
-            break;
+            // Get the index of the current vertex in control points array
+            int polyVertIndex = fbxMesh->GetPolygonVertex(polyIndex, posInPoly);
+
+            // The UV index depends on the reference mode
+            uvIndex = useIndex ? uvs->GetIndexArray().GetAt(polyVertIndex) : polyVertIndex;
         }
+        break;
+
+    case FbxGeometryElement::eByPolygonVertex:
+        if (meshVertexIndex < indexCount)
+        {
+            uvIndex = useIndex ? uvs->GetIndexArray().GetAt(meshVertexIndex) : meshVertexIndex;
+        }
+        break;
+
+    default:
+        // Only support eByPolygonVertex and eByControlPoint mappings
+        break;
+    }
+
+    vertex->hasTexCoord[uvSetIndex] = true;
+
+    // Store UV information in vertex
+    if (uvIndex != -1)
+    {
+        FbxVector2 uvValue = uvs->GetDirectArray().GetAt(uvIndex);
+        vertex->texCoord[uvSetIndex].x = (float)uvValue[0];
+        vertex->texCoord[uvSetIndex].y = (float)uvValue[1];
     }
 }
 

+ 19 - 8
gameplay-encoder/src/Vertex.cpp

@@ -5,8 +5,10 @@ namespace gameplay
 {
 
 Vertex::Vertex(void)
-    : hasNormal(false), hasTangent(false), hasBinormal(false), hasTexCoord(false), hasDiffuse(false), hasWeights(false)
+    : hasNormal(false), hasTangent(false), hasBinormal(false), hasDiffuse(false), hasWeights(false)
 {
+    for (unsigned int i = 0; i < MAX_UV_SETS; ++i)
+        hasTexCoord[i] = false;
 }
 
 Vertex::~Vertex(void)
@@ -22,8 +24,11 @@ unsigned int Vertex::byteSize() const
         count += TANGENT_COUNT;
     if (hasBinormal)
         count += BINORMAL_COUNT;
-    if (hasTexCoord)
-        count += TEXCOORD_COUNT;
+    for (unsigned int i = 0; i < MAX_UV_SETS; ++i)
+    {
+        if (hasTexCoord[i])
+            count += TEXCOORD_COUNT;
+    }
     if (hasWeights)
         count += BLEND_WEIGHTS_COUNT + BLEND_INDICES_COUNT;
     if (hasDiffuse)
@@ -46,9 +51,12 @@ void Vertex::writeBinary(FILE* file) const
     {
         writeVectorBinary(binormal, file);
     }
-    if (hasTexCoord)
+    for (unsigned int i = 0; i < MAX_UV_SETS; ++i)
     {
-        writeVectorBinary(texCoord, file);
+        if (hasTexCoord[i])
+        {
+            writeVectorBinary(texCoord[i], file);
+        }
     }
     if (hasDiffuse)
     {
@@ -80,10 +88,13 @@ void Vertex::writeText(FILE* file) const
         write("// binormal\n", file);
         writeVectorText(binormal, file);
     }
-    if (hasTexCoord)
+    for (unsigned int i = 0; i < MAX_UV_SETS; ++i)
     {
-        write("// texCoord\n", file);
-        writeVectorText(texCoord, file);
+        if (hasTexCoord[i])
+        {
+            write("// texCoord\n", file);
+            writeVectorText(texCoord[i], file);
+        }
     }
     if (hasDiffuse)
     {

+ 21 - 12
gameplay-encoder/src/Vertex.h

@@ -6,6 +6,9 @@
 #include "Vector3.h"
 #include "Vector4.h"
 
+// Maximum number of supported UV sets
+#define MAX_UV_SETS 8
+
 namespace gameplay
 {
 
@@ -36,13 +39,13 @@ public:
     Vector3 normal;
     Vector3 tangent;
     Vector3 binormal;
-    Vector2 texCoord;
+    Vector2 texCoord[MAX_UV_SETS];
     Vector4 diffuse;
 
     Vector4 blendWeights;
     Vector4 blendIndices;
 
-    bool hasNormal, hasTangent, hasBinormal, hasTexCoord, hasDiffuse, hasWeights;
+    bool hasNormal, hasTangent, hasBinormal, hasTexCoord[MAX_UV_SETS], hasDiffuse, hasWeights;
 
     inline bool operator<(const Vertex& v) const
     {
@@ -54,23 +57,24 @@ public:
                 {
                     if (binormal == v.binormal)
                     {
-                        if (texCoord == v.texCoord)
+                        if (diffuse == v.diffuse)
                         {
-                            if (diffuse == v.diffuse)
+                            if (blendWeights == v.blendWeights)
                             {
-                                if (blendWeights == v.blendWeights)
+                                if (blendIndices == v.blendIndices)
                                 {
-                                    if (blendIndices == v.blendIndices)
+                                    for (unsigned int i = 0; i < MAX_UV_SETS; ++i)
                                     {
-                                        return false;
+                                        if (!(texCoord[i] == v.texCoord[i]))
+                                            return texCoord[i] < v.texCoord[i];
                                     }
-                                    return blendIndices < v.blendIndices;
+                                    return false;
                                 }
-                                return blendWeights < v.blendWeights;
+                                return blendIndices < v.blendIndices;
                             }
-                            return diffuse < v.diffuse;
+                            return blendWeights < v.blendWeights;
                         }
-                        return texCoord < v.texCoord;
+                        return diffuse < v.diffuse;
                     }
                     return binormal < v.binormal;
                 }
@@ -83,7 +87,12 @@ public:
 
     inline bool operator==(const Vertex& v) const
     {
-        return position==v.position && normal==v.normal && tangent==v.tangent && binormal==v.binormal && texCoord==v.texCoord &&
+        for (unsigned int i = 0; i < MAX_UV_SETS; ++i)
+        {
+            if (!(texCoord[i] == v.texCoord[i]))
+                return false;
+        }
+        return position==v.position && normal==v.normal && tangent==v.tangent && binormal==v.binormal &&
             diffuse==v.diffuse && blendWeights==v.blendWeights && blendIndices==v.blendIndices;
     }
 

+ 4 - 1
gameplay/res/shaders/colored-unlit.frag

@@ -6,6 +6,9 @@ precision highp float;
 #if defined(VERTEX_COLOR)
 varying vec3 v_color;						// Input Vertex color ( r g b )
 #endif
+#if defined(TEXTURE_LIGHTMAP)
+varying vec2 v_texCoord;
+#endif
 
 // Uniforms
 uniform vec4 u_diffuseColor;               	// Diffuse color
@@ -30,7 +33,7 @@ void main()
     #endif
 	#if defined(TEXTURE_LIGHTMAP)
 	vec4 lightColor = texture2D(u_lightmapTexture, v_texCoord);
-	gl_FragColor.a *= lightColor.a;
+	gl_FragColor.rgb *= lightColor.rgb;
 	#endif
 	// Global color modulation
 	#if defined(MODULATE_COLOR)

+ 16 - 2
gameplay/res/shaders/colored-unlit.vert

@@ -1,14 +1,23 @@
 // Inputs
 attribute vec4 a_position;									// Vertex Position							(x, y, z, w)
+#if defined(TEXTURE_LIGHTMAP)
+attribute vec2 a_texCoord;                                  // Texture Coordinate (for lightmapping)
+#endif
 #if defined(SKINNING)
 attribute vec4 a_blendWeights;								// Vertex blend weight, up to 4				(0, 1, 2, 3) 
 attribute vec4 a_blendIndices;								// Vertex blend index int u_matrixPalette	(0, 1, 2, 3)
 #endif
 #if defined(VERTEX_COLOR)
 attribute vec3 a_color;										// Vertex Color								(r, g, b)
-varying vec3 v_color;										// Output Vertex color						(r, g, b)
 #endif
 
+// Outputs
+#if defined(TEXTURE_LIGHTMAP)
+varying vec2 v_texCoord;                                    // Output Texture Coordinate
+#endif
+#if defined(VERTEX_COLOR)
+varying vec3 v_color;										// Output Vertex color						(r, g, b)
+#endif
 
 // Uniforms
 uniform mat4 u_worldViewProjectionMatrix;					// Matrix to transform a position to clip space.
@@ -32,8 +41,13 @@ void main()
     // Transform position to clip space.a
     gl_Position = u_worldViewProjectionMatrix *  position;
     
+    // Pass lightmap tex coord to fragment shader
+    #if defined(TEXTURE_LIGHTMAP)
+    v_texCoord0 = a_texCoord0;
+    #endif
+
      // Pass on vertex color to fragment shader
     #if defined(VERTEX_COLOR)
 	v_color = a_color;
     #endif
-}
+}

+ 11 - 4
gameplay/res/shaders/textured-unlit.frag

@@ -15,16 +15,23 @@ uniform float u_modulateAlpha;              // Modulation alpha
 #endif
 
 // Inputs
-varying vec2 v_texCoord;                	// Texture coordinate(u, v)
+varying vec2 v_texCoord0;                	// Texture coordinate(u, v)
+#if defined(TEXCOORD1)
+varying vec2 v_texCoord1;                   // Second tex coord for multi-texturing
+#endif
 
 // Fragment Program
 void main()
 {
     // Sample the texture for the color
-    gl_FragColor = texture2D(u_diffuseTexture, v_texCoord);
+    gl_FragColor = texture2D(u_diffuseTexture, v_texCoord0);
 	#if defined(TEXTURE_LIGHTMAP)
-	vec4 lightColor = texture2D(u_lightmapTexture, v_texCoord);
-	gl_FragColor.a *= lightColor.a;
+    #if defined(TEXCOORD1)
+    vec4 lightColor = texture2D(u_lightmapTexture, v_texCoord1);
+    #else
+    vec4 lightColor = texture2D(u_lightmapTexture, v_texCoord0);
+    #endif
+    gl_FragColor.rgb *= lightColor.rgb;
 	#endif
 	// Global color modulation
 	#if defined(MODULATE_COLOR)

+ 12 - 3
gameplay/res/shaders/textured-unlit.vert

@@ -1,6 +1,9 @@
 // Inputs
 attribute vec4 a_position;									// Vertex Position							(x, y, z, w)
-attribute vec2 a_texCoord;									// Vertex Texture Coordinate				(u, v)
+attribute vec2 a_texCoord0;									// Vertex Texture Coordinate				(u, v)
+#if defined(TEXCOORD1)
+attribute vec2 a_texCoord1;                                 // Second tex coord for multi-texturing
+#endif
 #if defined(SKINNING)
 attribute vec4 a_blendWeights;								// Vertex blend weight, up to 4				(0, 1, 2, 3) 
 attribute vec4 a_blendIndices;								// Vertex blend index int u_matrixPalette	(0, 1, 2, 3)
@@ -19,7 +22,10 @@ uniform vec2 u_textureOffset;								// Texture offset
 #endif
 
 // Outputs
-varying vec2 v_texCoord;									// Texture Coordinate
+varying vec2 v_texCoord0;									// Texture Coordinate
+#if defined(TEXCOORD1)
+varying vec2 v_texCoord1;                                   // Second tex coord for multi-texturing
+#endif
 
 // Vertex attribute accessors
 #if defined(SKINNING)
@@ -38,7 +44,10 @@ void main()
     gl_Position = u_worldViewProjectionMatrix * position;
 
     // Texture transformation.
-    v_texCoord = a_texCoord;
+    v_texCoord0 = a_texCoord0;
+    #if defined(TEXCOORD1)
+    v_texCoord1 = a_texCoord1;
+    #endif
     #if defined(TEXTURE_REPEAT)
     v_texCoord *= u_textureRepeat;
     #endif

+ 7 - 5
gameplay/src/VertexAttributeBinding.cpp

@@ -171,15 +171,17 @@ VertexAttributeBinding* VertexAttributeBinding::create(Mesh* mesh, const VertexF
             attrib = effect->getVertexAttribute(VERTEX_ATTRIBUTE_BLENDINDICES_NAME);
             break;
         case VertexFormat::TEXCOORD0:
-            attrib = effect->getVertexAttribute(VERTEX_ATTRIBUTE_TEXCOORD_PREFIX_NAME);
-            // Try adding a "0" after the texcoord attrib name (flexible name for this case).
+            if ((attrib = effect->getVertexAttribute(VERTEX_ATTRIBUTE_TEXCOORD_PREFIX_NAME)) != -1)
+                break;
+
+            /*// Try adding a "0" after the texcoord attrib name (flexible name for this case).
             if (attrib == -1)
             {
                 name = VERTEX_ATTRIBUTE_TEXCOORD_PREFIX_NAME;
-                name += "0";
+                name += '0';
                 attrib = effect->getVertexAttribute(name.c_str());
             }
-            break; 
+            break;*/
         case VertexFormat::TEXCOORD1:
         case VertexFormat::TEXCOORD2:
         case VertexFormat::TEXCOORD3:
@@ -188,7 +190,7 @@ VertexAttributeBinding* VertexAttributeBinding::create(Mesh* mesh, const VertexF
         case VertexFormat::TEXCOORD6:
         case VertexFormat::TEXCOORD7:
             name = VERTEX_ATTRIBUTE_TEXCOORD_PREFIX_NAME;
-            name += (e.usage - VertexFormat::TEXCOORD0);
+            name += '0' + (e.usage - VertexFormat::TEXCOORD0);
             attrib = effect->getVertexAttribute(name.c_str());
             break;
         default: