Redesigned shader/material system

This redesign is intended to add support for PBR materials
This commit is contained in:
Ray 2017-06-27 00:44:22 +02:00
parent c46abd34d4
commit 32fc3608ea
5 changed files with 245 additions and 174 deletions

View File

@ -38,7 +38,7 @@ int main()
"resources/shaders/glsl330/grayscale.fs"); // Load model shader "resources/shaders/glsl330/grayscale.fs"); // Load model shader
dwarf.material.shader = shader; // Set shader effect to 3d model dwarf.material.shader = shader; // Set shader effect to 3d model
dwarf.material.texDiffuse = texture; // Bind texture to model dwarf.material.maps[TEXMAP_DIFFUSE].tex = texture; // Bind texture to model
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position

View File

@ -720,15 +720,16 @@ Material LoadDefaultMaterial(void)
Material material = { 0 }; Material material = { 0 };
material.shader = GetDefaultShader(); material.shader = GetDefaultShader();
material.texDiffuse = GetDefaultTexture(); // White texture (1x1 pixel) material.maps[TEXMAP_DIFFUSE].tex = GetDefaultTexture(); // White texture (1x1 pixel)
//material.texNormal; // NOTE: By default, not set //material.maps[TEXMAP_NORMAL].tex; // NOTE: By default, not set
//material.texSpecular; // NOTE: By default, not set //material.maps[TEXMAP_SPECULAR].tex; // NOTE: By default, not set
material.colDiffuse = WHITE; // Diffuse color material.maps[TEXMAP_DIFFUSE].color = WHITE; // Diffuse color
material.colAmbient = WHITE; // Ambient color //material.colAmbient = WHITE; // Ambient color
material.colSpecular = WHITE; // Specular color material.maps[TEXMAP_SPECULAR].color = WHITE; // Specular color
material.glossiness = 100.0f; // Glossiness level //material.glossiness = 100.0f; // Glossiness level
//material.params[PARAM_GLOSSINES] = 100.0f; // Glossiness level
return material; return material;
} }
@ -736,9 +737,9 @@ Material LoadDefaultMaterial(void)
// Unload material from memory // Unload material from memory
void UnloadMaterial(Material material) void UnloadMaterial(Material material)
{ {
rlDeleteTextures(material.texDiffuse.id); rlDeleteTextures(material.maps[TEXMAP_DIFFUSE].tex.id);
rlDeleteTextures(material.texNormal.id); rlDeleteTextures(material.maps[TEXMAP_NORMAL].tex.id);
rlDeleteTextures(material.texSpecular.id); rlDeleteTextures(material.maps[TEXMAP_SPECULAR].tex.id);
} }
// Generate a mesh from heightmap // Generate a mesh from heightmap
@ -1225,7 +1226,7 @@ void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rota
//Matrix matModel = MatrixMultiply(model.transform, matTransform); // Transform to world-space coordinates //Matrix matModel = MatrixMultiply(model.transform, matTransform); // Transform to world-space coordinates
model.transform = MatrixMultiply(model.transform, matTransform); model.transform = MatrixMultiply(model.transform, matTransform);
model.material.colDiffuse = tint; // TODO: Multiply tint color by diffuse color? model.material.maps[TEXMAP_DIFFUSE].color = tint; // TODO: Multiply tint color by diffuse color?
rlglDrawMesh(model.mesh, model.material, model.transform); rlglDrawMesh(model.mesh, model.material, model.transform);
} }
@ -1979,23 +1980,24 @@ static Material LoadMTL(const char *fileName)
case 'a': // Ka float float float Ambient color (RGB) case 'a': // Ka float float float Ambient color (RGB)
{ {
sscanf(buffer, "Ka %f %f %f", &color.x, &color.y, &color.z); sscanf(buffer, "Ka %f %f %f", &color.x, &color.y, &color.z);
material.colAmbient.r = (unsigned char)(color.x*255); // TODO: Support ambient color
material.colAmbient.g = (unsigned char)(color.y*255); //material.colAmbient.r = (unsigned char)(color.x*255);
material.colAmbient.b = (unsigned char)(color.z*255); //material.colAmbient.g = (unsigned char)(color.y*255);
//material.colAmbient.b = (unsigned char)(color.z*255);
} break; } break;
case 'd': // Kd float float float Diffuse color (RGB) case 'd': // Kd float float float Diffuse color (RGB)
{ {
sscanf(buffer, "Kd %f %f %f", &color.x, &color.y, &color.z); sscanf(buffer, "Kd %f %f %f", &color.x, &color.y, &color.z);
material.colDiffuse.r = (unsigned char)(color.x*255); material.maps[TEXMAP_DIFFUSE].color.r = (unsigned char)(color.x*255);
material.colDiffuse.g = (unsigned char)(color.y*255); material.maps[TEXMAP_DIFFUSE].color.g = (unsigned char)(color.y*255);
material.colDiffuse.b = (unsigned char)(color.z*255); material.maps[TEXMAP_DIFFUSE].color.b = (unsigned char)(color.z*255);
} break; } break;
case 's': // Ks float float float Specular color (RGB) case 's': // Ks float float float Specular color (RGB)
{ {
sscanf(buffer, "Ks %f %f %f", &color.x, &color.y, &color.z); sscanf(buffer, "Ks %f %f %f", &color.x, &color.y, &color.z);
material.colSpecular.r = (unsigned char)(color.x*255); material.maps[TEXMAP_SPECULAR].color.r = (unsigned char)(color.x*255);
material.colSpecular.g = (unsigned char)(color.y*255); material.maps[TEXMAP_SPECULAR].color.g = (unsigned char)(color.y*255);
material.colSpecular.b = (unsigned char)(color.z*255); material.maps[TEXMAP_SPECULAR].color.b = (unsigned char)(color.z*255);
} break; } break;
case 'e': // Ke float float float Emmisive color (RGB) case 'e': // Ke float float float Emmisive color (RGB)
{ {
@ -2011,7 +2013,7 @@ static Material LoadMTL(const char *fileName)
int shininess = 0; int shininess = 0;
sscanf(buffer, "Ns %i", &shininess); sscanf(buffer, "Ns %i", &shininess);
material.glossiness = (float)shininess; //material.params[PARAM_GLOSSINES] = (float)shininess;
} }
else if (buffer[1] == 'i') // Ni int Refraction index. else if (buffer[1] == 'i') // Ni int Refraction index.
{ {
@ -2027,12 +2029,12 @@ static Material LoadMTL(const char *fileName)
if (buffer[5] == 'd') // map_Kd string Diffuse color texture map. if (buffer[5] == 'd') // map_Kd string Diffuse color texture map.
{ {
result = sscanf(buffer, "map_Kd %s", mapFileName); result = sscanf(buffer, "map_Kd %s", mapFileName);
if (result != EOF) material.texDiffuse = LoadTexture(mapFileName); if (result != EOF) material.maps[TEXMAP_DIFFUSE].tex = LoadTexture(mapFileName);
} }
else if (buffer[5] == 's') // map_Ks string Specular color texture map. else if (buffer[5] == 's') // map_Ks string Specular color texture map.
{ {
result = sscanf(buffer, "map_Ks %s", mapFileName); result = sscanf(buffer, "map_Ks %s", mapFileName);
if (result != EOF) material.texSpecular = LoadTexture(mapFileName); if (result != EOF) material.maps[TEXMAP_SPECULAR].tex = LoadTexture(mapFileName);
} }
else if (buffer[5] == 'a') // map_Ka string Ambient color texture map. else if (buffer[5] == 'a') // map_Ka string Ambient color texture map.
{ {
@ -2042,12 +2044,12 @@ static Material LoadMTL(const char *fileName)
case 'B': // map_Bump string Bump texture map. case 'B': // map_Bump string Bump texture map.
{ {
result = sscanf(buffer, "map_Bump %s", mapFileName); result = sscanf(buffer, "map_Bump %s", mapFileName);
if (result != EOF) material.texNormal = LoadTexture(mapFileName); if (result != EOF) material.maps[TEXMAP_NORMAL].tex = LoadTexture(mapFileName);
} break; } break;
case 'b': // map_bump string Bump texture map. case 'b': // map_bump string Bump texture map.
{ {
result = sscanf(buffer, "map_bump %s", mapFileName); result = sscanf(buffer, "map_bump %s", mapFileName);
if (result != EOF) material.texNormal = LoadTexture(mapFileName); if (result != EOF) material.maps[TEXMAP_NORMAL].tex = LoadTexture(mapFileName);
} break; } break;
case 'd': // map_d string Opacity texture map. case 'd': // map_d string Opacity texture map.
{ {
@ -2062,7 +2064,7 @@ static Material LoadMTL(const char *fileName)
{ {
float alpha = 1.0f; float alpha = 1.0f;
sscanf(buffer, "d %f", &alpha); sscanf(buffer, "d %f", &alpha);
material.colDiffuse.a = (unsigned char)(alpha*255); material.maps[TEXMAP_DIFFUSE].color.a = (unsigned char)(alpha*255);
} }
else if (buffer[1] == 'i') // disp string Displacement map else if (buffer[1] == 'i') // disp string Displacement map
{ {
@ -2072,13 +2074,13 @@ static Material LoadMTL(const char *fileName)
case 'b': // bump string Bump texture map case 'b': // bump string Bump texture map
{ {
result = sscanf(buffer, "bump %s", mapFileName); result = sscanf(buffer, "bump %s", mapFileName);
if (result != EOF) material.texNormal = LoadTexture(mapFileName); if (result != EOF) material.maps[TEXMAP_NORMAL].tex = LoadTexture(mapFileName);
} break; } break;
case 'T': // Tr float Transparency Tr (alpha). Tr is inverse of d case 'T': // Tr float Transparency Tr (alpha). Tr is inverse of d
{ {
float ialpha = 0.0f; float ialpha = 0.0f;
sscanf(buffer, "Tr %f", &ialpha); sscanf(buffer, "Tr %f", &ialpha);
material.colDiffuse.a = (unsigned char)((1.0f - ialpha)*255); material.maps[TEXMAP_DIFFUSE].color.a = (unsigned char)((1.0f - ialpha)*255);
} break; } break;
case 'r': // refl string Reflection texture map case 'r': // refl string Reflection texture map

View File

@ -291,6 +291,11 @@
#define MAGENTA CLITERAL{ 255, 0, 255, 255 } // Magenta #define MAGENTA CLITERAL{ 255, 0, 255, 255 } // Magenta
#define RAYWHITE CLITERAL{ 245, 245, 245, 255 } // My own White (raylib logo) #define RAYWHITE CLITERAL{ 245, 245, 245, 255 } // My own White (raylib logo)
// Shader and material limits
#define MAX_SHADER_LOCATIONS 32
#define MAX_MATERIAL_TEXTURE_MAPS 8
#define MAX_MATERIAL_PARAMS 8
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Structures Definition // Structures Definition
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -420,43 +425,24 @@ typedef struct Mesh {
unsigned int vboId[7]; // OpenGL Vertex Buffer Objects id (7 types of vertex data) unsigned int vboId[7]; // OpenGL Vertex Buffer Objects id (7 types of vertex data)
} Mesh; } Mesh;
// Shader type (generic shader) // Shader type (generic)
typedef struct Shader { typedef struct Shader {
unsigned int id; // Shader program id unsigned int id; // Shader program id
int locs[MAX_SHADER_LOCATIONS]; // Initialized on LoadShader(), set to MAX_SHADER_LOCATIONS
// Vertex attributes locations (default locations)
int vertexLoc; // Vertex attribute location point (default-location = 0)
int texcoordLoc; // Texcoord attribute location point (default-location = 1)
int texcoord2Loc; // Texcoord2 attribute location point (default-location = 5)
int normalLoc; // Normal attribute location point (default-location = 2)
int tangentLoc; // Tangent attribute location point (default-location = 4)
int colorLoc; // Color attibute location point (default-location = 3)
// Uniform locations
int mvpLoc; // ModelView-Projection matrix uniform location point (vertex shader)
int colDiffuseLoc; // Diffuse color uniform location point (fragment shader)
int colAmbientLoc; // Ambient color uniform location point (fragment shader)
int colSpecularLoc; // Specular color uniform location point (fragment shader)
// Texture map locations (generic for any kind of map)
int mapTexture0Loc; // Map texture uniform location point (default-texture-unit = 0)
int mapTexture1Loc; // Map texture uniform location point (default-texture-unit = 1)
int mapTexture2Loc; // Map texture uniform location point (default-texture-unit = 2)
} Shader; } Shader;
// Material type // Material texture map
typedef struct TextureMap {
Texture2D tex;
Color color;
float value;
} TextureMap;
// Material type (generic)
typedef struct Material { typedef struct Material {
Shader shader; // Standard shader (supports 3 map textures) Shader shader;
TextureMap maps[MAX_MATERIAL_TEXTURE_MAPS]; // Initialized on LoadMaterial*(), set to MAX_MATERIAL_TEXTURE_MAPS
Texture2D texDiffuse; // Diffuse texture (binded to shader mapTexture0Loc) float *params; // Initialized on LoadMaterial*(), set to MAX_MATERIAL_PARAMS
Texture2D texNormal; // Normal texture (binded to shader mapTexture1Loc)
Texture2D texSpecular; // Specular texture (binded to shader mapTexture2Loc)
Color colDiffuse; // Diffuse color
Color colAmbient; // Ambient color
Color colSpecular; // Specular color
float glossiness; // Glossiness level (Ranges from 0 to 1000)
} Material; } Material;
// Model type // Model type
@ -540,6 +526,58 @@ typedef enum {
OTHER OTHER
} LogType; } LogType;
typedef enum {
LOC_VERTEX_POSITION = 0,
LOC_VERTEX_TEXCOORD01,
LOC_VERTEX_TEXCOORD02,
LOC_VERTEX_TEXCOORD03,
LOC_VERTEX_TEXCOORD04,
LOC_VERTEX_NORMAL,
LOC_VERTEX_TANGENT,
LOC_VERTEX_COLOR,
LOC_MATRIX_MVP,
LOC_MATRIX_VIEW,
LOC_MATRIX_PROJECTION,
LOC_TEXTURE_MAP01,
LOC_TEXTURE_MAP02,
LOC_TEXTURE_MAP03,
LOC_TEXTURE_MAP04,
LOC_TEXTURE_MAP05,
LOC_TEXTURE_MAP06,
LOC_TEXTURE_MAP07,
LOC_TEXTURE_MAP08,
LOC_TEXTURE_COLOR01,
LOC_TEXTURE_COLOR02,
LOC_TEXTURE_COLOR03,
LOC_TEXTURE_COLOR04,
LOC_TEXTURE_COLOR05,
LOC_TEXTURE_COLOR06,
LOC_TEXTURE_COLOR07,
LOC_TEXTURE_COLOR08
} ShaderLocationIndex;
typedef enum {
TEXMAP_DIFFUSE = 0,
TEXMAP_SPECULAR = 1,
TEXMAP_NORMAL = 2,
} TexmapBasicIndex;
typedef enum {
TEXMAP_ALBEDO = 0,
TEXMAP_METALNESS = 1,
TEXMAP_ROUGHNESS = 3,
TEXMAP_OCCLUSION,
TEXMAP_EMISSION,
TEXMAP_HEIGHT
} TexmapPBRIndex;
typedef enum {
TEXMAP_CUBEMAP = 8,
TEXMAP_IRRADIANCE,
TEXMAP_PREFILTER,
TEXMAP_BRDF,
} TexmapEnvIndex;
// Texture formats // Texture formats
// NOTE: Support depends on OpenGL version and platform // NOTE: Support depends on OpenGL version and platform
typedef enum { typedef enum {

View File

@ -1912,7 +1912,7 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform)
{ {
#if defined(GRAPHICS_API_OPENGL_11) #if defined(GRAPHICS_API_OPENGL_11)
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, material.texDiffuse.id); glBindTexture(GL_TEXTURE_2D, material.maps[TEXMAP_DIFFUSE].tex.id);
// NOTE: On OpenGL 1.1 we use Vertex Arrays to draw model // NOTE: On OpenGL 1.1 we use Vertex Arrays to draw model
glEnableClientState(GL_VERTEX_ARRAY); // Enable vertex array glEnableClientState(GL_VERTEX_ARRAY); // Enable vertex array
@ -1946,13 +1946,13 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform)
glUseProgram(material.shader.id); glUseProgram(material.shader.id);
// Upload to shader material.colDiffuse // Upload to shader material.colDiffuse
glUniform4f(material.shader.colDiffuseLoc, (float)material.colDiffuse.r/255, (float)material.colDiffuse.g/255, (float)material.colDiffuse.b/255, (float)material.colDiffuse.a/255); glUniform4f(material.shader.locs[LOC_TEXTURE_COLOR01], (float)material.maps[TEXMAP_DIFFUSE].color.r/255, (float)material.maps[TEXMAP_DIFFUSE].color.g/255, (float)material.maps[TEXMAP_DIFFUSE].color.b/255, (float)material.maps[TEXMAP_DIFFUSE].color.a/255);
// Upload to shader material.colAmbient (if available) // TODO: Upload to shader material.colAmbient (if available)
if (material.shader.colAmbientLoc != -1) glUniform4f(material.shader.colAmbientLoc, (float)material.colAmbient.r/255, (float)material.colAmbient.g/255, (float)material.colAmbient.b/255, (float)material.colAmbient.a/255); //if (material.shader.locs[LOC_TEXTURE_COLOR02] != -1) glUniform4f(material.shader.locs[LOC_TEXTURE_COLOR02], (float)material.colAmbient.r/255, (float)material.colAmbient.g/255, (float)material.colAmbient.b/255, (float)material.colAmbient.a/255);
// Upload to shader material.colSpecular (if available) // Upload to shader material.colSpecular (if available)
if (material.shader.colSpecularLoc != -1) glUniform4f(material.shader.colSpecularLoc, (float)material.colSpecular.r/255, (float)material.colSpecular.g/255, (float)material.colSpecular.b/255, (float)material.colSpecular.a/255); if (material.shader.locs[LOC_TEXTURE_COLOR03] != -1) glUniform4f(material.shader.locs[LOC_TEXTURE_COLOR03], (float)material.maps[TEXMAP_SPECULAR].color.r/255, (float)material.maps[TEXMAP_SPECULAR].color.g/255, (float)material.maps[TEXMAP_SPECULAR].color.b/255, (float)material.maps[TEXMAP_SPECULAR].color.a/255);
// At this point the modelview matrix just contains the view matrix (camera) // At this point the modelview matrix just contains the view matrix (camera)
// That's because Begin3dMode() sets it an no model-drawing function modifies it, all use rlPushMatrix() and rlPopMatrix() // That's because Begin3dMode() sets it an no model-drawing function modifies it, all use rlPushMatrix() and rlPopMatrix()
@ -1984,34 +1984,34 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform)
int viewDirLoc = glGetUniformLocation(material.shader.id, "viewDir"); int viewDirLoc = glGetUniformLocation(material.shader.id, "viewDir");
if (viewDirLoc != -1) glUniform3f(viewDirLoc, matView.m8, matView.m9, matView.m10); if (viewDirLoc != -1) glUniform3f(viewDirLoc, matView.m8, matView.m9, matView.m10);
// Check if glossiness is located in shader and upload value // TODO: Check if glossiness is located in shader and upload value
int glossinessLoc = glGetUniformLocation(material.shader.id, "glossiness"); int glossinessLoc = glGetUniformLocation(material.shader.id, "glossiness");
if (glossinessLoc != -1) glUniform1f(glossinessLoc, material.glossiness); //if (glossinessLoc != -1) glUniform1f(glossinessLoc, material.glossiness);
} }
// Set shader textures (diffuse, normal, specular) // Set shader textures (diffuse, normal, specular)
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, material.texDiffuse.id); glBindTexture(GL_TEXTURE_2D, material.maps[TEXMAP_DIFFUSE].tex.id);
glUniform1i(material.shader.mapTexture0Loc, 0); // Diffuse texture fits in active texture unit 0 glUniform1i(material.shader.locs[LOC_TEXTURE_MAP01], 0); // Diffuse texture fits in active texture unit 0
if ((material.texNormal.id != 0) && (material.shader.mapTexture1Loc != -1)) if ((material.maps[TEXMAP_NORMAL].tex.id != 0) && (material.shader.locs[LOC_TEXTURE_MAP01] != -1))
{ {
// Upload to shader specular map flag // Upload to shader specular map flag
glUniform1i(glGetUniformLocation(material.shader.id, "useNormal"), 1); glUniform1i(glGetUniformLocation(material.shader.id, "useNormal"), 1);
glActiveTexture(GL_TEXTURE1); glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, material.texNormal.id); glBindTexture(GL_TEXTURE_2D, material.maps[TEXMAP_NORMAL].tex.id);
glUniform1i(material.shader.mapTexture1Loc, 1); // Normal texture fits in active texture unit 1 glUniform1i(material.shader.locs[LOC_TEXTURE_MAP01], 1); // Normal texture fits in active texture unit 1
} }
if ((material.texSpecular.id != 0) && (material.shader.mapTexture2Loc != -1)) if ((material.maps[TEXMAP_SPECULAR].tex.id != 0) && (material.shader.locs[LOC_TEXTURE_MAP02] != -1))
{ {
// Upload to shader specular map flag // Upload to shader specular map flag
glUniform1i(glGetUniformLocation(material.shader.id, "useSpecular"), 1); glUniform1i(glGetUniformLocation(material.shader.id, "useSpecular"), 1);
glActiveTexture(GL_TEXTURE2); glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, material.texSpecular.id); glBindTexture(GL_TEXTURE_2D, material.maps[TEXMAP_SPECULAR].tex.id);
glUniform1i(material.shader.mapTexture2Loc, 2); // Specular texture fits in active texture unit 2 glUniform1i(material.shader.locs[LOC_TEXTURE_MAP02], 2); // Specular texture fits in active texture unit 2
} }
if (vaoSupported) if (vaoSupported)
@ -2022,54 +2022,54 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform)
{ {
// Bind mesh VBO data: vertex position (shader-location = 0) // Bind mesh VBO data: vertex position (shader-location = 0)
glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[0]); glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[0]);
glVertexAttribPointer(material.shader.vertexLoc, 3, GL_FLOAT, 0, 0, 0); glVertexAttribPointer(material.shader.locs[LOC_VERTEX_POSITION], 3, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(material.shader.vertexLoc); glEnableVertexAttribArray(material.shader.locs[LOC_VERTEX_POSITION]);
// Bind mesh VBO data: vertex texcoords (shader-location = 1) // Bind mesh VBO data: vertex texcoords (shader-location = 1)
glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[1]); glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[1]);
glVertexAttribPointer(material.shader.texcoordLoc, 2, GL_FLOAT, 0, 0, 0); glVertexAttribPointer(material.shader.locs[LOC_VERTEX_TEXCOORD01], 2, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(material.shader.texcoordLoc); glEnableVertexAttribArray(material.shader.locs[LOC_VERTEX_TEXCOORD01]);
// Bind mesh VBO data: vertex normals (shader-location = 2, if available) // Bind mesh VBO data: vertex normals (shader-location = 2, if available)
if (material.shader.normalLoc != -1) if (material.shader.locs[LOC_VERTEX_NORMAL] != -1)
{ {
glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[2]); glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[2]);
glVertexAttribPointer(material.shader.normalLoc, 3, GL_FLOAT, 0, 0, 0); glVertexAttribPointer(material.shader.locs[LOC_VERTEX_NORMAL], 3, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(material.shader.normalLoc); glEnableVertexAttribArray(material.shader.locs[LOC_VERTEX_NORMAL]);
} }
// Bind mesh VBO data: vertex colors (shader-location = 3, if available) // Bind mesh VBO data: vertex colors (shader-location = 3, if available)
if (material.shader.colorLoc != -1) if (material.shader.locs[LOC_VERTEX_COLOR] != -1)
{ {
if (mesh.vboId[3] != 0) if (mesh.vboId[3] != 0)
{ {
glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[3]); glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[3]);
glVertexAttribPointer(material.shader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0); glVertexAttribPointer(material.shader.locs[LOC_VERTEX_COLOR], 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);
glEnableVertexAttribArray(material.shader.colorLoc); glEnableVertexAttribArray(material.shader.locs[LOC_VERTEX_COLOR]);
} }
else else
{ {
// Set default value for unused attribute // Set default value for unused attribute
// NOTE: Required when using default shader and no VAO support // NOTE: Required when using default shader and no VAO support
glVertexAttrib4f(material.shader.colorLoc, 1.0f, 1.0f, 1.0f, 1.0f); glVertexAttrib4f(material.shader.locs[LOC_VERTEX_COLOR], 1.0f, 1.0f, 1.0f, 1.0f);
glDisableVertexAttribArray(material.shader.colorLoc); glDisableVertexAttribArray(material.shader.locs[LOC_VERTEX_COLOR]);
} }
} }
// Bind mesh VBO data: vertex tangents (shader-location = 4, if available) // Bind mesh VBO data: vertex tangents (shader-location = 4, if available)
if (material.shader.tangentLoc != -1) if (material.shader.locs[LOC_VERTEX_TANGENT] != -1)
{ {
glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[4]); glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[4]);
glVertexAttribPointer(material.shader.tangentLoc, 3, GL_FLOAT, 0, 0, 0); glVertexAttribPointer(material.shader.locs[LOC_VERTEX_TANGENT], 3, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(material.shader.tangentLoc); glEnableVertexAttribArray(material.shader.locs[LOC_VERTEX_TANGENT]);
} }
// Bind mesh VBO data: vertex texcoords2 (shader-location = 5, if available) // Bind mesh VBO data: vertex texcoords2 (shader-location = 5, if available)
if (material.shader.texcoord2Loc != -1) if (material.shader.locs[LOC_VERTEX_TEXCOORD02] != -1)
{ {
glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[5]); glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[5]);
glVertexAttribPointer(material.shader.texcoord2Loc, 2, GL_FLOAT, 0, 0, 0); glVertexAttribPointer(material.shader.locs[LOC_VERTEX_TEXCOORD02], 2, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(material.shader.texcoord2Loc); glEnableVertexAttribArray(material.shader.locs[LOC_VERTEX_TEXCOORD02]);
} }
if (mesh.indices != NULL) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quads.vboId[3]); if (mesh.indices != NULL) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quads.vboId[3]);
@ -2091,20 +2091,20 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform)
Matrix matMVP = MatrixMultiply(modelview, projection); // Transform to screen-space coordinates Matrix matMVP = MatrixMultiply(modelview, projection); // Transform to screen-space coordinates
// Send combined model-view-projection matrix to shader // Send combined model-view-projection matrix to shader
glUniformMatrix4fv(material.shader.mvpLoc, 1, false, MatrixToFloat(matMVP)); glUniformMatrix4fv(material.shader.locs[LOC_MATRIX_MVP], 1, false, MatrixToFloat(matMVP));
// Draw call! // Draw call!
if (mesh.indices != NULL) glDrawElements(GL_TRIANGLES, mesh.triangleCount*3, GL_UNSIGNED_SHORT, 0); // Indexed vertices draw if (mesh.indices != NULL) glDrawElements(GL_TRIANGLES, mesh.triangleCount*3, GL_UNSIGNED_SHORT, 0); // Indexed vertices draw
else glDrawArrays(GL_TRIANGLES, 0, mesh.vertexCount); else glDrawArrays(GL_TRIANGLES, 0, mesh.vertexCount);
} }
if (material.texNormal.id != 0) if (material.maps[TEXMAP_NORMAL].tex.id != 0)
{ {
glActiveTexture(GL_TEXTURE1); glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
} }
if (material.texSpecular.id != 0) if (material.maps[TEXMAP_SPECULAR].tex.id != 0)
{ {
glActiveTexture(GL_TEXTURE2); glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
@ -3036,24 +3036,24 @@ static void LoadDefaultShaderLocations(Shader *shader)
// vertex texcoord2 location = 5 // vertex texcoord2 location = 5
// Get handles to GLSL input attibute locations // Get handles to GLSL input attibute locations
shader->vertexLoc = glGetAttribLocation(shader->id, DEFAULT_ATTRIB_POSITION_NAME); shader->locs[LOC_VERTEX_POSITION] = glGetAttribLocation(shader->id, DEFAULT_ATTRIB_POSITION_NAME);
shader->texcoordLoc = glGetAttribLocation(shader->id, DEFAULT_ATTRIB_TEXCOORD_NAME); shader->locs[LOC_VERTEX_TEXCOORD01] = glGetAttribLocation(shader->id, DEFAULT_ATTRIB_TEXCOORD_NAME);
shader->texcoord2Loc = glGetAttribLocation(shader->id, DEFAULT_ATTRIB_TEXCOORD2_NAME); shader->locs[LOC_VERTEX_TEXCOORD02] = glGetAttribLocation(shader->id, DEFAULT_ATTRIB_TEXCOORD2_NAME);
shader->normalLoc = glGetAttribLocation(shader->id, DEFAULT_ATTRIB_NORMAL_NAME); shader->locs[LOC_VERTEX_NORMAL] = glGetAttribLocation(shader->id, DEFAULT_ATTRIB_NORMAL_NAME);
shader->tangentLoc = glGetAttribLocation(shader->id, DEFAULT_ATTRIB_TANGENT_NAME); shader->locs[LOC_VERTEX_TANGENT] = glGetAttribLocation(shader->id, DEFAULT_ATTRIB_TANGENT_NAME);
shader->colorLoc = glGetAttribLocation(shader->id, DEFAULT_ATTRIB_COLOR_NAME); shader->locs[LOC_VERTEX_COLOR] = glGetAttribLocation(shader->id, DEFAULT_ATTRIB_COLOR_NAME);
// Get handles to GLSL uniform locations (vertex shader) // Get handles to GLSL uniform locations (vertex shader)
shader->mvpLoc = glGetUniformLocation(shader->id, "mvpMatrix"); shader->locs[LOC_MATRIX_MVP] = glGetUniformLocation(shader->id, "mvpMatrix");
// Get handles to GLSL uniform locations (fragment shader) // Get handles to GLSL uniform locations (fragment shader)
shader->colDiffuseLoc = glGetUniformLocation(shader->id, "colDiffuse"); shader->locs[LOC_TEXTURE_COLOR01] = glGetUniformLocation(shader->id, "colDiffuse");
shader->colAmbientLoc = glGetUniformLocation(shader->id, "colAmbient"); shader->locs[LOC_TEXTURE_COLOR02] = glGetUniformLocation(shader->id, "colAmbient");
shader->colSpecularLoc = glGetUniformLocation(shader->id, "colSpecular"); shader->locs[LOC_TEXTURE_COLOR03] = glGetUniformLocation(shader->id, "colSpecular");
shader->mapTexture0Loc = glGetUniformLocation(shader->id, "texture0"); shader->locs[LOC_TEXTURE_MAP01] = glGetUniformLocation(shader->id, "texture0");
shader->mapTexture1Loc = glGetUniformLocation(shader->id, "texture1"); shader->locs[LOC_TEXTURE_MAP02] = glGetUniformLocation(shader->id, "texture1");
shader->mapTexture2Loc = glGetUniformLocation(shader->id, "texture2"); shader->locs[LOC_TEXTURE_MAP03] = glGetUniformLocation(shader->id, "texture2");
// TODO: Try to find all expected/recognized shader locations (predefined names, must be documented) // TODO: Try to find all expected/recognized shader locations (predefined names, must be documented)
} }
@ -3155,15 +3155,15 @@ static void LoadDefaultBuffers(void)
glGenBuffers(2, &lines.vboId[0]); glGenBuffers(2, &lines.vboId[0]);
glBindBuffer(GL_ARRAY_BUFFER, lines.vboId[0]); glBindBuffer(GL_ARRAY_BUFFER, lines.vboId[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*2*MAX_LINES_BATCH, lines.vertices, GL_DYNAMIC_DRAW); glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*2*MAX_LINES_BATCH, lines.vertices, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(currentShader.vertexLoc); glEnableVertexAttribArray(currentShader.locs[LOC_VERTEX_POSITION]);
glVertexAttribPointer(currentShader.vertexLoc, 3, GL_FLOAT, 0, 0, 0); glVertexAttribPointer(currentShader.locs[LOC_VERTEX_POSITION], 3, GL_FLOAT, 0, 0, 0);
// Vertex color buffer (shader-location = 3) // Vertex color buffer (shader-location = 3)
glGenBuffers(2, &lines.vboId[1]); glGenBuffers(2, &lines.vboId[1]);
glBindBuffer(GL_ARRAY_BUFFER, lines.vboId[1]); glBindBuffer(GL_ARRAY_BUFFER, lines.vboId[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(unsigned char)*4*2*MAX_LINES_BATCH, lines.colors, GL_DYNAMIC_DRAW); glBufferData(GL_ARRAY_BUFFER, sizeof(unsigned char)*4*2*MAX_LINES_BATCH, lines.colors, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(currentShader.colorLoc); glEnableVertexAttribArray(currentShader.locs[LOC_VERTEX_COLOR]);
glVertexAttribPointer(currentShader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0); glVertexAttribPointer(currentShader.locs[LOC_VERTEX_COLOR], 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);
if (vaoSupported) TraceLog(INFO, "[VAO ID %i] Default buffers VAO initialized successfully (lines)", lines.vaoId); if (vaoSupported) TraceLog(INFO, "[VAO ID %i] Default buffers VAO initialized successfully (lines)", lines.vaoId);
else TraceLog(INFO, "[VBO ID %i][VBO ID %i] Default buffers VBOs initialized successfully (lines)", lines.vboId[0], lines.vboId[1]); else TraceLog(INFO, "[VBO ID %i][VBO ID %i] Default buffers VBOs initialized successfully (lines)", lines.vboId[0], lines.vboId[1]);
@ -3181,15 +3181,15 @@ static void LoadDefaultBuffers(void)
glGenBuffers(1, &triangles.vboId[0]); glGenBuffers(1, &triangles.vboId[0]);
glBindBuffer(GL_ARRAY_BUFFER, triangles.vboId[0]); glBindBuffer(GL_ARRAY_BUFFER, triangles.vboId[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*3*MAX_TRIANGLES_BATCH, triangles.vertices, GL_DYNAMIC_DRAW); glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*3*MAX_TRIANGLES_BATCH, triangles.vertices, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(currentShader.vertexLoc); glEnableVertexAttribArray(currentShader.locs[LOC_VERTEX_POSITION]);
glVertexAttribPointer(currentShader.vertexLoc, 3, GL_FLOAT, 0, 0, 0); glVertexAttribPointer(currentShader.locs[LOC_VERTEX_POSITION], 3, GL_FLOAT, 0, 0, 0);
// Vertex color buffer (shader-location = 3) // Vertex color buffer (shader-location = 3)
glGenBuffers(1, &triangles.vboId[1]); glGenBuffers(1, &triangles.vboId[1]);
glBindBuffer(GL_ARRAY_BUFFER, triangles.vboId[1]); glBindBuffer(GL_ARRAY_BUFFER, triangles.vboId[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(unsigned char)*4*3*MAX_TRIANGLES_BATCH, triangles.colors, GL_DYNAMIC_DRAW); glBufferData(GL_ARRAY_BUFFER, sizeof(unsigned char)*4*3*MAX_TRIANGLES_BATCH, triangles.colors, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(currentShader.colorLoc); glEnableVertexAttribArray(currentShader.locs[LOC_VERTEX_COLOR]);
glVertexAttribPointer(currentShader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0); glVertexAttribPointer(currentShader.locs[LOC_VERTEX_COLOR], 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);
if (vaoSupported) TraceLog(INFO, "[VAO ID %i] Default buffers VAO initialized successfully (triangles)", triangles.vaoId); if (vaoSupported) TraceLog(INFO, "[VAO ID %i] Default buffers VAO initialized successfully (triangles)", triangles.vaoId);
else TraceLog(INFO, "[VBO ID %i][VBO ID %i] Default buffers VBOs initialized successfully (triangles)", triangles.vboId[0], triangles.vboId[1]); else TraceLog(INFO, "[VBO ID %i][VBO ID %i] Default buffers VBOs initialized successfully (triangles)", triangles.vboId[0], triangles.vboId[1]);
@ -3207,22 +3207,22 @@ static void LoadDefaultBuffers(void)
glGenBuffers(1, &quads.vboId[0]); glGenBuffers(1, &quads.vboId[0]);
glBindBuffer(GL_ARRAY_BUFFER, quads.vboId[0]); glBindBuffer(GL_ARRAY_BUFFER, quads.vboId[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*4*MAX_QUADS_BATCH, quads.vertices, GL_DYNAMIC_DRAW); glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*4*MAX_QUADS_BATCH, quads.vertices, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(currentShader.vertexLoc); glEnableVertexAttribArray(currentShader.locs[LOC_VERTEX_POSITION]);
glVertexAttribPointer(currentShader.vertexLoc, 3, GL_FLOAT, 0, 0, 0); glVertexAttribPointer(currentShader.locs[LOC_VERTEX_POSITION], 3, GL_FLOAT, 0, 0, 0);
// Vertex texcoord buffer (shader-location = 1) // Vertex texcoord buffer (shader-location = 1)
glGenBuffers(1, &quads.vboId[1]); glGenBuffers(1, &quads.vboId[1]);
glBindBuffer(GL_ARRAY_BUFFER, quads.vboId[1]); glBindBuffer(GL_ARRAY_BUFFER, quads.vboId[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2*4*MAX_QUADS_BATCH, quads.texcoords, GL_DYNAMIC_DRAW); glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2*4*MAX_QUADS_BATCH, quads.texcoords, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(currentShader.texcoordLoc); glEnableVertexAttribArray(currentShader.locs[LOC_VERTEX_TEXCOORD01]);
glVertexAttribPointer(currentShader.texcoordLoc, 2, GL_FLOAT, 0, 0, 0); glVertexAttribPointer(currentShader.locs[LOC_VERTEX_TEXCOORD01], 2, GL_FLOAT, 0, 0, 0);
// Vertex color buffer (shader-location = 3) // Vertex color buffer (shader-location = 3)
glGenBuffers(1, &quads.vboId[2]); glGenBuffers(1, &quads.vboId[2]);
glBindBuffer(GL_ARRAY_BUFFER, quads.vboId[2]); glBindBuffer(GL_ARRAY_BUFFER, quads.vboId[2]);
glBufferData(GL_ARRAY_BUFFER, sizeof(unsigned char)*4*4*MAX_QUADS_BATCH, quads.colors, GL_DYNAMIC_DRAW); glBufferData(GL_ARRAY_BUFFER, sizeof(unsigned char)*4*4*MAX_QUADS_BATCH, quads.colors, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(currentShader.colorLoc); glEnableVertexAttribArray(currentShader.locs[LOC_VERTEX_COLOR]);
glVertexAttribPointer(currentShader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0); glVertexAttribPointer(currentShader.locs[LOC_VERTEX_COLOR], 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);
// Fill index buffer // Fill index buffer
glGenBuffers(1, &quads.vboId[3]); glGenBuffers(1, &quads.vboId[3]);
@ -3338,9 +3338,9 @@ static void DrawDefaultBuffers()
// Create modelview-projection matrix // Create modelview-projection matrix
Matrix matMVP = MatrixMultiply(modelview, projection); Matrix matMVP = MatrixMultiply(modelview, projection);
glUniformMatrix4fv(currentShader.mvpLoc, 1, false, MatrixToFloat(matMVP)); glUniformMatrix4fv(currentShader.locs[LOC_MATRIX_MVP], 1, false, MatrixToFloat(matMVP));
glUniform4f(currentShader.colDiffuseLoc, 1.0f, 1.0f, 1.0f, 1.0f); glUniform4f(currentShader.locs[LOC_TEXTURE_COLOR01], 1.0f, 1.0f, 1.0f, 1.0f);
glUniform1i(currentShader.mapTexture0Loc, 0); glUniform1i(currentShader.locs[LOC_TEXTURE_MAP01], 0);
// NOTE: Additional map textures not considered for default buffers drawing // NOTE: Additional map textures not considered for default buffers drawing
} }
@ -3358,13 +3358,13 @@ static void DrawDefaultBuffers()
{ {
// Bind vertex attrib: position (shader-location = 0) // Bind vertex attrib: position (shader-location = 0)
glBindBuffer(GL_ARRAY_BUFFER, lines.vboId[0]); glBindBuffer(GL_ARRAY_BUFFER, lines.vboId[0]);
glVertexAttribPointer(currentShader.vertexLoc, 3, GL_FLOAT, 0, 0, 0); glVertexAttribPointer(currentShader.locs[LOC_VERTEX_POSITION], 3, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(currentShader.vertexLoc); glEnableVertexAttribArray(currentShader.locs[LOC_VERTEX_POSITION]);
// Bind vertex attrib: color (shader-location = 3) // Bind vertex attrib: color (shader-location = 3)
glBindBuffer(GL_ARRAY_BUFFER, lines.vboId[1]); glBindBuffer(GL_ARRAY_BUFFER, lines.vboId[1]);
glVertexAttribPointer(currentShader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0); glVertexAttribPointer(currentShader.locs[LOC_VERTEX_COLOR], 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);
glEnableVertexAttribArray(currentShader.colorLoc); glEnableVertexAttribArray(currentShader.locs[LOC_VERTEX_COLOR]);
} }
glDrawArrays(GL_LINES, 0, lines.vCounter); glDrawArrays(GL_LINES, 0, lines.vCounter);
@ -3386,13 +3386,13 @@ static void DrawDefaultBuffers()
{ {
// Bind vertex attrib: position (shader-location = 0) // Bind vertex attrib: position (shader-location = 0)
glBindBuffer(GL_ARRAY_BUFFER, triangles.vboId[0]); glBindBuffer(GL_ARRAY_BUFFER, triangles.vboId[0]);
glVertexAttribPointer(currentShader.vertexLoc, 3, GL_FLOAT, 0, 0, 0); glVertexAttribPointer(currentShader.locs[LOC_VERTEX_POSITION], 3, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(currentShader.vertexLoc); glEnableVertexAttribArray(currentShader.locs[LOC_VERTEX_POSITION]);
// Bind vertex attrib: color (shader-location = 3) // Bind vertex attrib: color (shader-location = 3)
glBindBuffer(GL_ARRAY_BUFFER, triangles.vboId[1]); glBindBuffer(GL_ARRAY_BUFFER, triangles.vboId[1]);
glVertexAttribPointer(currentShader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0); glVertexAttribPointer(currentShader.locs[LOC_VERTEX_COLOR], 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);
glEnableVertexAttribArray(currentShader.colorLoc); glEnableVertexAttribArray(currentShader.locs[LOC_VERTEX_COLOR]);
} }
glDrawArrays(GL_TRIANGLES, 0, triangles.vCounter); glDrawArrays(GL_TRIANGLES, 0, triangles.vCounter);
@ -3416,18 +3416,18 @@ static void DrawDefaultBuffers()
{ {
// Bind vertex attrib: position (shader-location = 0) // Bind vertex attrib: position (shader-location = 0)
glBindBuffer(GL_ARRAY_BUFFER, quads.vboId[0]); glBindBuffer(GL_ARRAY_BUFFER, quads.vboId[0]);
glVertexAttribPointer(currentShader.vertexLoc, 3, GL_FLOAT, 0, 0, 0); glVertexAttribPointer(currentShader.locs[LOC_VERTEX_POSITION], 3, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(currentShader.vertexLoc); glEnableVertexAttribArray(currentShader.locs[LOC_VERTEX_POSITION]);
// Bind vertex attrib: texcoord (shader-location = 1) // Bind vertex attrib: texcoord (shader-location = 1)
glBindBuffer(GL_ARRAY_BUFFER, quads.vboId[1]); glBindBuffer(GL_ARRAY_BUFFER, quads.vboId[1]);
glVertexAttribPointer(currentShader.texcoordLoc, 2, GL_FLOAT, 0, 0, 0); glVertexAttribPointer(currentShader.locs[LOC_VERTEX_TEXCOORD01], 2, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(currentShader.texcoordLoc); glEnableVertexAttribArray(currentShader.locs[LOC_VERTEX_TEXCOORD01]);
// Bind vertex attrib: color (shader-location = 3) // Bind vertex attrib: color (shader-location = 3)
glBindBuffer(GL_ARRAY_BUFFER, quads.vboId[2]); glBindBuffer(GL_ARRAY_BUFFER, quads.vboId[2]);
glVertexAttribPointer(currentShader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0); glVertexAttribPointer(currentShader.locs[LOC_VERTEX_COLOR], 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);
glEnableVertexAttribArray(currentShader.colorLoc); glEnableVertexAttribArray(currentShader.locs[LOC_VERTEX_COLOR]);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quads.vboId[3]); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quads.vboId[3]);
} }

View File

@ -105,6 +105,11 @@
#define MAX_QUADS_BATCH 1024 // Be careful with text, every letter maps a quad #define MAX_QUADS_BATCH 1024 // Be careful with text, every letter maps a quad
#endif #endif
// Shader and material limits
#define MAX_SHADER_LOCATIONS 32
#define MAX_MATERIAL_TEXTURE_MAPS 8
#define MAX_MATERIAL_PARAMS 8
// Texture parameters (equivalent to OpenGL defines) // Texture parameters (equivalent to OpenGL defines)
#define RL_TEXTURE_WRAP_S 0x2802 // GL_TEXTURE_WRAP_S #define RL_TEXTURE_WRAP_S 0x2802 // GL_TEXTURE_WRAP_S
#define RL_TEXTURE_WRAP_T 0x2803 // GL_TEXTURE_WRAP_T #define RL_TEXTURE_WRAP_T 0x2803 // GL_TEXTURE_WRAP_T
@ -145,6 +150,51 @@ typedef unsigned char byte;
// Boolean type // Boolean type
typedef enum { false, true } bool; typedef enum { false, true } bool;
#endif #endif
typedef enum {
LOC_VERTEX_POSITION = 0,
LOC_VERTEX_TEXCOORD01,
LOC_VERTEX_TEXCOORD02,
LOC_VERTEX_TEXCOORD03,
LOC_VERTEX_TEXCOORD04,
LOC_VERTEX_NORMAL,
LOC_VERTEX_TANGENT,
LOC_VERTEX_COLOR,
LOC_MATRIX_MVP,
LOC_MATRIX_VIEW,
LOC_MATRIX_PROJECTION,
LOC_TEXTURE_MAP01,
LOC_TEXTURE_MAP02,
LOC_TEXTURE_MAP03,
LOC_TEXTURE_MAP04,
LOC_TEXTURE_MAP05,
LOC_TEXTURE_MAP06,
LOC_TEXTURE_MAP07,
LOC_TEXTURE_MAP08,
LOC_TEXTURE_COLOR01,
LOC_TEXTURE_COLOR02,
LOC_TEXTURE_COLOR03,
LOC_TEXTURE_COLOR04,
LOC_TEXTURE_COLOR05,
LOC_TEXTURE_COLOR06,
LOC_TEXTURE_COLOR07,
LOC_TEXTURE_COLOR08
} ShaderLocationIndex;
typedef enum {
TEXMAP_DIFFUSE = 0,
TEXMAP_SPECULAR = 1,
TEXMAP_NORMAL = 2,
} TexmapBasicIndex;
typedef enum {
TEXMAP_ALBEDO = 0,
TEXMAP_METALNESS = 1,
TEXMAP_ROUGHNESS = 3,
TEXMAP_OCCLUSION,
TEXMAP_EMISSION,
TEXMAP_HEIGHT
} TexmapPBRIndex;
// Color type, RGBA (32bit) // Color type, RGBA (32bit)
typedef struct Color { typedef struct Color {
@ -186,44 +236,25 @@ typedef unsigned char byte;
unsigned int vaoId; // OpenGL Vertex Array Object id unsigned int vaoId; // OpenGL Vertex Array Object id
unsigned int vboId[7]; // OpenGL Vertex Buffer Objects id (7 types of vertex data) unsigned int vboId[7]; // OpenGL Vertex Buffer Objects id (7 types of vertex data)
} Mesh; } Mesh;
// Shader type (generic shader) // Shader type (generic)
typedef struct Shader { typedef struct Shader {
unsigned int id; // Shader program id unsigned int id; // Shader program id
int locs[MAX_SHADER_LOCATIONS]; // Initialized on LoadShader(), set to MAX_SHADER_LOCATIONS
// Vertex attributes locations (default locations)
int vertexLoc; // Vertex attribute location point (default-location = 0)
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)
int colDiffuseLoc; // Color uniform location point (fragment shader)
int colAmbientLoc; // Ambient color uniform location point (fragment shader)
int colSpecularLoc; // Specular color uniform location point (fragment shader)
// Texture map locations (generic for any kind of map)
int mapTexture0Loc; // Map texture uniform location point (default-texture-unit = 0)
int mapTexture1Loc; // Map texture uniform location point (default-texture-unit = 1)
int mapTexture2Loc; // Map texture uniform location point (default-texture-unit = 2)
} Shader; } Shader;
// Material type // Material texture map
typedef struct TextureMap {
Texture2D tex;
Color color;
float value;
} TextureMap;
// Material type (generic)
typedef struct Material { typedef struct Material {
Shader shader; // Standard shader (supports 3 map types: diffuse, normal, specular) Shader shader;
TextureMap maps[MAX_TEXTURE_MAPS]; // Initialized on LoadMaterial*(), set to MAX_TEXTURE_MAPS
Texture2D texDiffuse; // Diffuse texture float *params; // Initialized on LoadMaterial*(), set to MAX_MATERIAL_PARAMS
Texture2D texNormal; // Normal texture
Texture2D texSpecular; // Specular texture
Color colDiffuse; // Diffuse color
Color colAmbient; // Ambient color
Color colSpecular; // Specular color
float glossiness; // Glossiness level (Ranges from 0 to 1000)
} Material; } Material;
// Camera type, defines a camera position/orientation in 3d space // Camera type, defines a camera position/orientation in 3d space