Browse Source

Improved vertex attribs support for models

Ray 9 years ago
parent
commit
f7d4951165
3 changed files with 45 additions and 16 deletions
  1. 1 1
      src/models.c
  2. 8 6
      src/raylib.h
  3. 36 9
      src/rlgl.c

+ 1 - 1
src/models.c

@@ -695,7 +695,7 @@ void UnloadModel(Model model)
     // Unload mesh data
     free(model.mesh.vertices);
     free(model.mesh.texcoords);
-    free(model.mesh.normals);
+    if (model.mesh.normals != NULL) free(model.mesh.normals);
     if (model.mesh.colors != NULL) free(model.mesh.colors);
     if (model.mesh.tangents != NULL) free(model.mesh.tangents);
     if (model.mesh.texcoords2 != NULL) free(model.mesh.texcoords2);

+ 8 - 6
src/raylib.h

@@ -369,12 +369,12 @@ typedef struct BoundingBox {
 // Vertex data definning a mesh
 typedef struct Mesh {
     int vertexCount;            // num vertices
-    float *vertices;            // vertex position (XYZ - 3 components per vertex)
-    float *texcoords;           // vertex texture coordinates (UV - 2 components per vertex)
-    float *texcoords2;          // vertex second texture coordinates (useful for lightmaps)
-    float *normals;             // vertex normals (XYZ - 3 components per vertex)
-    float *tangents;            // vertex tangents (XYZ - 3 components per vertex)
-    unsigned char *colors;      // vertex colors (RGBA - 4 components per vertex)
+    float *vertices;            // vertex position (XYZ - 3 components per vertex) (shader-location = 0)
+    float *texcoords;           // vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1)
+    float *texcoords2;          // vertex second texture coordinates (useful for lightmaps) (shader-location = 5)
+    float *normals;             // vertex normals (XYZ - 3 components per vertex) (shader-location = 2)
+    float *tangents;            // vertex tangents (XYZ - 3 components per vertex) (shader-location = 4)
+    unsigned char *colors;      // vertex colors (RGBA - 4 components per vertex) (shader-location = 3)
     
     BoundingBox bounds;         // mesh limits defined by min and max points
     
@@ -391,6 +391,8 @@ typedef struct Shader {
     int texcoordLoc;      // Texcoord attribute location point (default-location = 1)
     int normalLoc;        // Normal attribute location point (default-location = 2)
     int colorLoc;         // Color attibute location point (default-location = 3)
+    int tangentLoc;       // Tangent attribute location point (default-location = 4)
+    int texcoord2Loc;     // Texcoord2 attribute location point (default-location = 5)
 
     // Uniform locations
     int mvpLoc;           // ModelView-Projection matrix uniform location point (vertex shader)

+ 36 - 9
src/rlgl.c

@@ -1084,12 +1084,13 @@ void rlglDrawEx(Mesh mesh, Material material, Matrix transform, bool wires)
     // NOTE: On OpenGL 1.1 we use Vertex Arrays to draw model
     glEnableClientState(GL_VERTEX_ARRAY);                   // Enable vertex array
     glEnableClientState(GL_TEXTURE_COORD_ARRAY);            // Enable texture coords array
-    glEnableClientState(GL_NORMAL_ARRAY);                   // Enable normals array
+    if (mesh.normals != NULL) glEnableClientState(GL_NORMAL_ARRAY);     // Enable normals array
+    if (mesh.colors != NULL) glEnableClientState(GL_COLOR_ARRAY);       // Enable colors array          
 
     glVertexPointer(3, GL_FLOAT, 0, mesh.vertices);         // Pointer to vertex coords array
     glTexCoordPointer(2, GL_FLOAT, 0, mesh.texcoords);      // Pointer to texture coords array
-    glNormalPointer(GL_FLOAT, 0, mesh.normals);             // Pointer to normals array
-    //glColorPointer(4, GL_UNSIGNED_BYTE, 0, mesh.colors);   // Pointer to colors array (NOT USED)
+    if (mesh.normals != NULL) glNormalPointer(GL_FLOAT, 0, mesh.normals);           // Pointer to normals array
+    if (mesh.colors != NULL) glColorPointer(4, GL_UNSIGNED_BYTE, 0, mesh.colors);   // Pointer to colors array
 
     rlPushMatrix();
         rlMultMatrixf(MatrixToFloat(transform));
@@ -1099,7 +1100,8 @@ void rlglDrawEx(Mesh mesh, Material material, Matrix transform, bool wires)
 
     glDisableClientState(GL_VERTEX_ARRAY);                  // Disable vertex array
     glDisableClientState(GL_TEXTURE_COORD_ARRAY);           // Disable texture coords array
-    glDisableClientState(GL_NORMAL_ARRAY);                  // Disable normals array
+    if (mesh.normals != NULL) glDisableClientState(GL_NORMAL_ARRAY);    // Disable normals array
+    if (mesh.colors != NULL) glDisableClientState(GL_NORMAL_ARRAY);     // Disable colors array
 
     glDisable(GL_TEXTURE_2D);
     glBindTexture(GL_TEXTURE_2D, 0);
@@ -1170,7 +1172,29 @@ void rlglDrawEx(Mesh mesh, Material material, Matrix transform, bool wires)
             glEnableVertexAttribArray(material.shader.normalLoc);
         }
         
-        // TODO: Bind mesh VBO data: colors, tangents, texcoords2 (if available)
+        // Bind mesh VBO data: vertex colors (shader-location = 3, if available) , tangents, texcoords2 (if available)
+        if (material.shader.colorLoc != -1)
+        {
+            glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[3]);
+            glVertexAttribPointer(material.shader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);
+            glEnableVertexAttribArray(material.shader.colorLoc);
+        }
+        
+        // Bind mesh VBO data: vertex tangents (shader-location = 4, if available)
+        if (material.shader.tangentLoc != -1)
+        {
+            glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[4]);
+            glVertexAttribPointer(material.shader.tangentLoc, 3, GL_FLOAT, 0, 0, 0);
+            glEnableVertexAttribArray(material.shader.tangentLoc);
+        }
+        
+        // Bind mesh VBO data: vertex texcoords2 (shader-location = 5, if available)
+        if (material.shader.texcoord2Loc != -1)
+        {
+            glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[5]);
+            glVertexAttribPointer(material.shader.texcoord2Loc, 2, GL_FLOAT, 0, 0, 0);
+            glEnableVertexAttribArray(material.shader.texcoord2Loc);
+        }
     }
 
     // Draw call!
@@ -1640,16 +1664,15 @@ void rlglGenerateMipmaps(Texture2D texture)
 }
 
 // Upload vertex data into a VAO (if supported) and VBO
-// TODO: Consider attributes: color, texcoords2, tangents (if available)
 void rlglLoadMesh(Mesh *mesh)
 {
     mesh->vaoId = 0;        // Vertex Array Object
     mesh->vboId[0] = 0;     // Vertex positions VBO
     mesh->vboId[1] = 0;     // Vertex texcoords VBO
     mesh->vboId[2] = 0;     // Vertex normals VBO
-    mesh->vboId[3] = 0;     // Vertex color VBO
-    mesh->vboId[4] = 0;     // Vertex tangent VBO
-    mesh->vboId[5] = 0;     // Vertex texcoord2 VBO
+    mesh->vboId[3] = 0;     // Vertex colors VBO
+    mesh->vboId[4] = 0;     // Vertex tangents VBO
+    mesh->vboId[5] = 0;     // Vertex texcoords2 VBO
     
 
 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
@@ -2314,12 +2337,16 @@ static void LoadDefaultShaderLocations(Shader *shader)
     //          vertex texcoord location = 1
     //          vertex normal location = 2
     //          vertex color location = 3
+    //          vertex tangent location = 4
+    //          vertex texcoord2 location = 5
     
     // Get handles to GLSL input attibute locations
     shader->vertexLoc = glGetAttribLocation(shader->id, "vertexPosition");
     shader->texcoordLoc = glGetAttribLocation(shader->id, "vertexTexCoord");
     shader->normalLoc = glGetAttribLocation(shader->id, "vertexNormal");
     shader->colorLoc = glGetAttribLocation(shader->id, "vertexColor");
+    shader->tangentLoc = glGetAttribLocation(shader->id, "vertexTangent");
+    shader->texcoord2Loc = glGetAttribLocation(shader->id, "vertexTexCoord2");
 
     // Get handles to GLSL uniform locations (vertex shader)
     shader->mvpLoc  = glGetUniformLocation(shader->id, "mvpMatrix");