diff --git a/examples/shaders/shaders_model_shader.c b/examples/shaders/shaders_model_shader.c index 51e9c1b39..ef5665d27 100644 --- a/examples/shaders/shaders_model_shader.c +++ b/examples/shaders/shaders_model_shader.c @@ -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 diff --git a/src/models.c b/src/models.c index 0a692f5cd..a8f120ed7 100644 --- a/src/models.c +++ b/src/models.c @@ -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 diff --git a/src/raylib.h b/src/raylib.h index 6d597fef3..a412cf13f 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -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 { diff --git a/src/rlgl.c b/src/rlgl.c index a40836ca2..0f21500e8 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -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]); } diff --git a/src/rlgl.h b/src/rlgl.h index 6d6ad516a..362127972 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -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 @@ -145,6 +150,51 @@ typedef unsigned char byte; // Boolean type 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 { @@ -186,44 +236,25 @@ typedef unsigned char byte; unsigned int vaoId; // OpenGL Vertex Array Object id 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