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
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

View File

@ -720,15 +720,16 @@ Material LoadDefaultMaterial(void)
Material material = { 0 };
material.shader = GetDefaultShader();
material.texDiffuse = GetDefaultTexture(); // White texture (1x1 pixel)
//material.texNormal; // NOTE: By default, not set
//material.texSpecular; // NOTE: By default, not set
material.maps[TEXMAP_DIFFUSE].tex = GetDefaultTexture(); // White texture (1x1 pixel)
//material.maps[TEXMAP_NORMAL].tex; // NOTE: By default, not set
//material.maps[TEXMAP_SPECULAR].tex; // NOTE: By default, not set
material.colDiffuse = WHITE; // Diffuse color
material.colAmbient = WHITE; // Ambient color
material.colSpecular = WHITE; // Specular color
material.maps[TEXMAP_DIFFUSE].color = WHITE; // Diffuse color
//material.colAmbient = WHITE; // Ambient 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;
}
@ -736,9 +737,9 @@ Material LoadDefaultMaterial(void)
// Unload material from memory
void UnloadMaterial(Material material)
{
rlDeleteTextures(material.texDiffuse.id);
rlDeleteTextures(material.texNormal.id);
rlDeleteTextures(material.texSpecular.id);
rlDeleteTextures(material.maps[TEXMAP_DIFFUSE].tex.id);
rlDeleteTextures(material.maps[TEXMAP_NORMAL].tex.id);
rlDeleteTextures(material.maps[TEXMAP_SPECULAR].tex.id);
}
// 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
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);
}
@ -1979,23 +1980,24 @@ static Material LoadMTL(const char *fileName)
case 'a': // Ka float float float Ambient color (RGB)
{
sscanf(buffer, "Ka %f %f %f", &color.x, &color.y, &color.z);
material.colAmbient.r = (unsigned char)(color.x*255);
material.colAmbient.g = (unsigned char)(color.y*255);
material.colAmbient.b = (unsigned char)(color.z*255);
// TODO: Support ambient color
//material.colAmbient.r = (unsigned char)(color.x*255);
//material.colAmbient.g = (unsigned char)(color.y*255);
//material.colAmbient.b = (unsigned char)(color.z*255);
} break;
case 'd': // Kd float float float Diffuse color (RGB)
{
sscanf(buffer, "Kd %f %f %f", &color.x, &color.y, &color.z);
material.colDiffuse.r = (unsigned char)(color.x*255);
material.colDiffuse.g = (unsigned char)(color.y*255);
material.colDiffuse.b = (unsigned char)(color.z*255);
material.maps[TEXMAP_DIFFUSE].color.r = (unsigned char)(color.x*255);
material.maps[TEXMAP_DIFFUSE].color.g = (unsigned char)(color.y*255);
material.maps[TEXMAP_DIFFUSE].color.b = (unsigned char)(color.z*255);
} break;
case 's': // Ks float float float Specular color (RGB)
{
sscanf(buffer, "Ks %f %f %f", &color.x, &color.y, &color.z);
material.colSpecular.r = (unsigned char)(color.x*255);
material.colSpecular.g = (unsigned char)(color.y*255);
material.colSpecular.b = (unsigned char)(color.z*255);
material.maps[TEXMAP_SPECULAR].color.r = (unsigned char)(color.x*255);
material.maps[TEXMAP_SPECULAR].color.g = (unsigned char)(color.y*255);
material.maps[TEXMAP_SPECULAR].color.b = (unsigned char)(color.z*255);
} break;
case 'e': // Ke float float float Emmisive color (RGB)
{
@ -2011,7 +2013,7 @@ static Material LoadMTL(const char *fileName)
int shininess = 0;
sscanf(buffer, "Ns %i", &shininess);
material.glossiness = (float)shininess;
//material.params[PARAM_GLOSSINES] = (float)shininess;
}
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.
{
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.
{
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.
{
@ -2042,12 +2044,12 @@ static Material LoadMTL(const char *fileName)
case 'B': // map_Bump string Bump texture map.
{
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;
case 'b': // map_bump string Bump texture map.
{
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;
case 'd': // map_d string Opacity texture map.
{
@ -2062,7 +2064,7 @@ static Material LoadMTL(const char *fileName)
{
float alpha = 1.0f;
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
{
@ -2072,13 +2074,13 @@ static Material LoadMTL(const char *fileName)
case 'b': // bump string Bump texture map
{
result = sscanf(buffer, "bump %s", mapFileName);
if (result != EOF) material.texNormal = LoadTexture(mapFileName);
if (result != EOF) material.maps[TEXMAP_NORMAL].tex = LoadTexture(mapFileName);
} break;
case 'T': // Tr float Transparency Tr (alpha). Tr is inverse of d
{
float ialpha = 0.0f;
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;
case 'r': // refl string Reflection texture map

View File

@ -291,6 +291,11 @@
#define MAGENTA CLITERAL{ 255, 0, 255, 255 } // Magenta
#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
//----------------------------------------------------------------------------------
@ -420,43 +425,24 @@ typedef struct Mesh {
unsigned int vboId[7]; // OpenGL Vertex Buffer Objects id (7 types of vertex data)
} Mesh;
// Shader type (generic shader)
// Shader type (generic)
typedef struct Shader {
unsigned int id; // Shader program id
// 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)
int locs[MAX_SHADER_LOCATIONS]; // Initialized on LoadShader(), set to MAX_SHADER_LOCATIONS
} Shader;
// Material type
// Material texture map
typedef struct TextureMap {
Texture2D tex;
Color color;
float value;
} TextureMap;
// Material type (generic)
typedef struct Material {
Shader shader; // Standard shader (supports 3 map textures)
Texture2D texDiffuse; // Diffuse texture (binded to shader mapTexture0Loc)
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)
Shader shader;
TextureMap maps[MAX_MATERIAL_TEXTURE_MAPS]; // Initialized on LoadMaterial*(), set to MAX_MATERIAL_TEXTURE_MAPS
float *params; // Initialized on LoadMaterial*(), set to MAX_MATERIAL_PARAMS
} Material;
// Model type
@ -540,6 +526,58 @@ typedef enum {
OTHER
} 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
// NOTE: Support depends on OpenGL version and platform
typedef enum {

View File

@ -1912,7 +1912,7 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform)
{
#if defined(GRAPHICS_API_OPENGL_11)
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
glEnableClientState(GL_VERTEX_ARRAY); // Enable vertex array
@ -1946,13 +1946,13 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform)
glUseProgram(material.shader.id);
// 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)
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);
// TODO: Upload to shader material.colAmbient (if available)
//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)
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)
// 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");
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");
if (glossinessLoc != -1) glUniform1f(glossinessLoc, material.glossiness);
//if (glossinessLoc != -1) glUniform1f(glossinessLoc, material.glossiness);
}
// Set shader textures (diffuse, normal, specular)
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, material.texDiffuse.id);
glUniform1i(material.shader.mapTexture0Loc, 0); // Diffuse texture fits in active texture unit 0
glBindTexture(GL_TEXTURE_2D, material.maps[TEXMAP_DIFFUSE].tex.id);
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
glUniform1i(glGetUniformLocation(material.shader.id, "useNormal"), 1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, material.texNormal.id);
glUniform1i(material.shader.mapTexture1Loc, 1); // Normal texture fits in active texture unit 1
glBindTexture(GL_TEXTURE_2D, material.maps[TEXMAP_NORMAL].tex.id);
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
glUniform1i(glGetUniformLocation(material.shader.id, "useSpecular"), 1);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, material.texSpecular.id);
glUniform1i(material.shader.mapTexture2Loc, 2); // Specular texture fits in active texture unit 2
glBindTexture(GL_TEXTURE_2D, material.maps[TEXMAP_SPECULAR].tex.id);
glUniform1i(material.shader.locs[LOC_TEXTURE_MAP02], 2); // Specular texture fits in active texture unit 2
}
if (vaoSupported)
@ -2022,54 +2022,54 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform)
{
// Bind mesh VBO data: vertex position (shader-location = 0)
glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[0]);
glVertexAttribPointer(material.shader.vertexLoc, 3, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(material.shader.vertexLoc);
glVertexAttribPointer(material.shader.locs[LOC_VERTEX_POSITION], 3, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(material.shader.locs[LOC_VERTEX_POSITION]);
// Bind mesh VBO data: vertex texcoords (shader-location = 1)
glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[1]);
glVertexAttribPointer(material.shader.texcoordLoc, 2, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(material.shader.texcoordLoc);
glVertexAttribPointer(material.shader.locs[LOC_VERTEX_TEXCOORD01], 2, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(material.shader.locs[LOC_VERTEX_TEXCOORD01]);
// 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]);
glVertexAttribPointer(material.shader.normalLoc, 3, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(material.shader.normalLoc);
glVertexAttribPointer(material.shader.locs[LOC_VERTEX_NORMAL], 3, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(material.shader.locs[LOC_VERTEX_NORMAL]);
}
// 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)
{
glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[3]);
glVertexAttribPointer(material.shader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);
glEnableVertexAttribArray(material.shader.colorLoc);
glVertexAttribPointer(material.shader.locs[LOC_VERTEX_COLOR], 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);
glEnableVertexAttribArray(material.shader.locs[LOC_VERTEX_COLOR]);
}
else
{
// Set default value for unused attribute
// NOTE: Required when using default shader and no VAO support
glVertexAttrib4f(material.shader.colorLoc, 1.0f, 1.0f, 1.0f, 1.0f);
glDisableVertexAttribArray(material.shader.colorLoc);
glVertexAttrib4f(material.shader.locs[LOC_VERTEX_COLOR], 1.0f, 1.0f, 1.0f, 1.0f);
glDisableVertexAttribArray(material.shader.locs[LOC_VERTEX_COLOR]);
}
}
// 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]);
glVertexAttribPointer(material.shader.tangentLoc, 3, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(material.shader.tangentLoc);
glVertexAttribPointer(material.shader.locs[LOC_VERTEX_TANGENT], 3, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(material.shader.locs[LOC_VERTEX_TANGENT]);
}
// 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]);
glVertexAttribPointer(material.shader.texcoord2Loc, 2, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(material.shader.texcoord2Loc);
glVertexAttribPointer(material.shader.locs[LOC_VERTEX_TEXCOORD02], 2, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(material.shader.locs[LOC_VERTEX_TEXCOORD02]);
}
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
// 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!
if (mesh.indices != NULL) glDrawElements(GL_TRIANGLES, mesh.triangleCount*3, GL_UNSIGNED_SHORT, 0); // Indexed vertices draw
else glDrawArrays(GL_TRIANGLES, 0, mesh.vertexCount);
}
if (material.texNormal.id != 0)
if (material.maps[TEXMAP_NORMAL].tex.id != 0)
{
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, 0);
}
if (material.texSpecular.id != 0)
if (material.maps[TEXMAP_SPECULAR].tex.id != 0)
{
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, 0);
@ -3036,24 +3036,24 @@ static void LoadDefaultShaderLocations(Shader *shader)
// vertex texcoord2 location = 5
// Get handles to GLSL input attibute locations
shader->vertexLoc = glGetAttribLocation(shader->id, DEFAULT_ATTRIB_POSITION_NAME);
shader->texcoordLoc = glGetAttribLocation(shader->id, DEFAULT_ATTRIB_TEXCOORD_NAME);
shader->texcoord2Loc = glGetAttribLocation(shader->id, DEFAULT_ATTRIB_TEXCOORD2_NAME);
shader->normalLoc = glGetAttribLocation(shader->id, DEFAULT_ATTRIB_NORMAL_NAME);
shader->tangentLoc = glGetAttribLocation(shader->id, DEFAULT_ATTRIB_TANGENT_NAME);
shader->colorLoc = glGetAttribLocation(shader->id, DEFAULT_ATTRIB_COLOR_NAME);
shader->locs[LOC_VERTEX_POSITION] = glGetAttribLocation(shader->id, DEFAULT_ATTRIB_POSITION_NAME);
shader->locs[LOC_VERTEX_TEXCOORD01] = glGetAttribLocation(shader->id, DEFAULT_ATTRIB_TEXCOORD_NAME);
shader->locs[LOC_VERTEX_TEXCOORD02] = glGetAttribLocation(shader->id, DEFAULT_ATTRIB_TEXCOORD2_NAME);
shader->locs[LOC_VERTEX_NORMAL] = glGetAttribLocation(shader->id, DEFAULT_ATTRIB_NORMAL_NAME);
shader->locs[LOC_VERTEX_TANGENT] = glGetAttribLocation(shader->id, DEFAULT_ATTRIB_TANGENT_NAME);
shader->locs[LOC_VERTEX_COLOR] = glGetAttribLocation(shader->id, DEFAULT_ATTRIB_COLOR_NAME);
// 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)
shader->colDiffuseLoc = glGetUniformLocation(shader->id, "colDiffuse");
shader->colAmbientLoc = glGetUniformLocation(shader->id, "colAmbient");
shader->colSpecularLoc = glGetUniformLocation(shader->id, "colSpecular");
shader->locs[LOC_TEXTURE_COLOR01] = glGetUniformLocation(shader->id, "colDiffuse");
shader->locs[LOC_TEXTURE_COLOR02] = glGetUniformLocation(shader->id, "colAmbient");
shader->locs[LOC_TEXTURE_COLOR03] = glGetUniformLocation(shader->id, "colSpecular");
shader->mapTexture0Loc = glGetUniformLocation(shader->id, "texture0");
shader->mapTexture1Loc = glGetUniformLocation(shader->id, "texture1");
shader->mapTexture2Loc = glGetUniformLocation(shader->id, "texture2");
shader->locs[LOC_TEXTURE_MAP01] = glGetUniformLocation(shader->id, "texture0");
shader->locs[LOC_TEXTURE_MAP02] = glGetUniformLocation(shader->id, "texture1");
shader->locs[LOC_TEXTURE_MAP03] = glGetUniformLocation(shader->id, "texture2");
// 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]);
glBindBuffer(GL_ARRAY_BUFFER, lines.vboId[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*2*MAX_LINES_BATCH, lines.vertices, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(currentShader.vertexLoc);
glVertexAttribPointer(currentShader.vertexLoc, 3, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(currentShader.locs[LOC_VERTEX_POSITION]);
glVertexAttribPointer(currentShader.locs[LOC_VERTEX_POSITION], 3, GL_FLOAT, 0, 0, 0);
// Vertex color buffer (shader-location = 3)
glGenBuffers(2, &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);
glEnableVertexAttribArray(currentShader.colorLoc);
glVertexAttribPointer(currentShader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);
glEnableVertexAttribArray(currentShader.locs[LOC_VERTEX_COLOR]);
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);
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]);
glBindBuffer(GL_ARRAY_BUFFER, triangles.vboId[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*3*MAX_TRIANGLES_BATCH, triangles.vertices, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(currentShader.vertexLoc);
glVertexAttribPointer(currentShader.vertexLoc, 3, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(currentShader.locs[LOC_VERTEX_POSITION]);
glVertexAttribPointer(currentShader.locs[LOC_VERTEX_POSITION], 3, GL_FLOAT, 0, 0, 0);
// Vertex color buffer (shader-location = 3)
glGenBuffers(1, &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);
glEnableVertexAttribArray(currentShader.colorLoc);
glVertexAttribPointer(currentShader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);
glEnableVertexAttribArray(currentShader.locs[LOC_VERTEX_COLOR]);
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);
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]);
glBindBuffer(GL_ARRAY_BUFFER, quads.vboId[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*4*MAX_QUADS_BATCH, quads.vertices, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(currentShader.vertexLoc);
glVertexAttribPointer(currentShader.vertexLoc, 3, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(currentShader.locs[LOC_VERTEX_POSITION]);
glVertexAttribPointer(currentShader.locs[LOC_VERTEX_POSITION], 3, GL_FLOAT, 0, 0, 0);
// Vertex texcoord buffer (shader-location = 1)
glGenBuffers(1, &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);
glEnableVertexAttribArray(currentShader.texcoordLoc);
glVertexAttribPointer(currentShader.texcoordLoc, 2, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(currentShader.locs[LOC_VERTEX_TEXCOORD01]);
glVertexAttribPointer(currentShader.locs[LOC_VERTEX_TEXCOORD01], 2, GL_FLOAT, 0, 0, 0);
// Vertex color buffer (shader-location = 3)
glGenBuffers(1, &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);
glEnableVertexAttribArray(currentShader.colorLoc);
glVertexAttribPointer(currentShader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);
glEnableVertexAttribArray(currentShader.locs[LOC_VERTEX_COLOR]);
glVertexAttribPointer(currentShader.locs[LOC_VERTEX_COLOR], 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);
// Fill index buffer
glGenBuffers(1, &quads.vboId[3]);
@ -3338,9 +3338,9 @@ static void DrawDefaultBuffers()
// Create modelview-projection matrix
Matrix matMVP = MatrixMultiply(modelview, projection);
glUniformMatrix4fv(currentShader.mvpLoc, 1, false, MatrixToFloat(matMVP));
glUniform4f(currentShader.colDiffuseLoc, 1.0f, 1.0f, 1.0f, 1.0f);
glUniform1i(currentShader.mapTexture0Loc, 0);
glUniformMatrix4fv(currentShader.locs[LOC_MATRIX_MVP], 1, false, MatrixToFloat(matMVP));
glUniform4f(currentShader.locs[LOC_TEXTURE_COLOR01], 1.0f, 1.0f, 1.0f, 1.0f);
glUniform1i(currentShader.locs[LOC_TEXTURE_MAP01], 0);
// NOTE: Additional map textures not considered for default buffers drawing
}
@ -3358,13 +3358,13 @@ static void DrawDefaultBuffers()
{
// Bind vertex attrib: position (shader-location = 0)
glBindBuffer(GL_ARRAY_BUFFER, lines.vboId[0]);
glVertexAttribPointer(currentShader.vertexLoc, 3, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(currentShader.vertexLoc);
glVertexAttribPointer(currentShader.locs[LOC_VERTEX_POSITION], 3, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(currentShader.locs[LOC_VERTEX_POSITION]);
// Bind vertex attrib: color (shader-location = 3)
glBindBuffer(GL_ARRAY_BUFFER, lines.vboId[1]);
glVertexAttribPointer(currentShader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);
glEnableVertexAttribArray(currentShader.colorLoc);
glVertexAttribPointer(currentShader.locs[LOC_VERTEX_COLOR], 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);
glEnableVertexAttribArray(currentShader.locs[LOC_VERTEX_COLOR]);
}
glDrawArrays(GL_LINES, 0, lines.vCounter);
@ -3386,13 +3386,13 @@ static void DrawDefaultBuffers()
{
// Bind vertex attrib: position (shader-location = 0)
glBindBuffer(GL_ARRAY_BUFFER, triangles.vboId[0]);
glVertexAttribPointer(currentShader.vertexLoc, 3, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(currentShader.vertexLoc);
glVertexAttribPointer(currentShader.locs[LOC_VERTEX_POSITION], 3, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(currentShader.locs[LOC_VERTEX_POSITION]);
// Bind vertex attrib: color (shader-location = 3)
glBindBuffer(GL_ARRAY_BUFFER, triangles.vboId[1]);
glVertexAttribPointer(currentShader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);
glEnableVertexAttribArray(currentShader.colorLoc);
glVertexAttribPointer(currentShader.locs[LOC_VERTEX_COLOR], 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);
glEnableVertexAttribArray(currentShader.locs[LOC_VERTEX_COLOR]);
}
glDrawArrays(GL_TRIANGLES, 0, triangles.vCounter);
@ -3416,18 +3416,18 @@ static void DrawDefaultBuffers()
{
// Bind vertex attrib: position (shader-location = 0)
glBindBuffer(GL_ARRAY_BUFFER, quads.vboId[0]);
glVertexAttribPointer(currentShader.vertexLoc, 3, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(currentShader.vertexLoc);
glVertexAttribPointer(currentShader.locs[LOC_VERTEX_POSITION], 3, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(currentShader.locs[LOC_VERTEX_POSITION]);
// Bind vertex attrib: texcoord (shader-location = 1)
glBindBuffer(GL_ARRAY_BUFFER, quads.vboId[1]);
glVertexAttribPointer(currentShader.texcoordLoc, 2, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(currentShader.texcoordLoc);
glVertexAttribPointer(currentShader.locs[LOC_VERTEX_TEXCOORD01], 2, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(currentShader.locs[LOC_VERTEX_TEXCOORD01]);
// Bind vertex attrib: color (shader-location = 3)
glBindBuffer(GL_ARRAY_BUFFER, quads.vboId[2]);
glVertexAttribPointer(currentShader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);
glEnableVertexAttribArray(currentShader.colorLoc);
glVertexAttribPointer(currentShader.locs[LOC_VERTEX_COLOR], 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);
glEnableVertexAttribArray(currentShader.locs[LOC_VERTEX_COLOR]);
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
#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)
#define RL_TEXTURE_WRAP_S 0x2802 // GL_TEXTURE_WRAP_S
#define RL_TEXTURE_WRAP_T 0x2803 // GL_TEXTURE_WRAP_T
@ -146,6 +151,51 @@ typedef unsigned char byte;
typedef enum { false, true } bool;
#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)
typedef struct Color {
unsigned char r;
@ -187,43 +237,24 @@ typedef unsigned char byte;
unsigned int vboId[7]; // OpenGL Vertex Buffer Objects id (7 types of vertex data)
} Mesh;
// Shader type (generic shader)
// Shader type (generic)
typedef struct Shader {
unsigned int id; // Shader program id
// 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)
int locs[MAX_SHADER_LOCATIONS]; // Initialized on LoadShader(), set to MAX_SHADER_LOCATIONS
} Shader;
// Material type
// Material texture map
typedef struct TextureMap {
Texture2D tex;
Color color;
float value;
} TextureMap;
// Material type (generic)
typedef struct Material {
Shader shader; // Standard shader (supports 3 map types: diffuse, normal, specular)
Texture2D texDiffuse; // Diffuse texture
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)
Shader shader;
TextureMap maps[MAX_TEXTURE_MAPS]; // Initialized on LoadMaterial*(), set to MAX_TEXTURE_MAPS
float *params; // Initialized on LoadMaterial*(), set to MAX_MATERIAL_PARAMS
} Material;
// Camera type, defines a camera position/orientation in 3d space