|
@@ -191,6 +191,7 @@ static bool useTempBuffer = false;
|
|
|
|
|
|
// Shader Programs
|
|
// Shader Programs
|
|
static Shader defaultShader;
|
|
static Shader defaultShader;
|
|
|
|
+static Shader standardShader;
|
|
static Shader currentShader; // By default, defaultShader
|
|
static Shader currentShader; // By default, defaultShader
|
|
|
|
|
|
// Flags for supported extensions
|
|
// Flags for supported extensions
|
|
@@ -236,6 +237,7 @@ static Shader LoadDefaultShader(void); // Load default shader (just vertex
|
|
static Shader LoadStandardShader(void); // Load standard shader (support materials and lighting)
|
|
static Shader LoadStandardShader(void); // Load standard shader (support materials and lighting)
|
|
static void LoadDefaultShaderLocations(Shader *shader); // Bind default shader locations (attributes and uniforms)
|
|
static void LoadDefaultShaderLocations(Shader *shader); // Bind default shader locations (attributes and uniforms)
|
|
static void UnloadDefaultShader(void); // Unload default shader
|
|
static void UnloadDefaultShader(void); // Unload default shader
|
|
|
|
+static void UnloadStandardShader(void); // Unload standard shader
|
|
|
|
|
|
static void LoadDefaultBuffers(void); // Load default internal buffers (lines, triangles, quads)
|
|
static void LoadDefaultBuffers(void); // Load default internal buffers (lines, triangles, quads)
|
|
static void UpdateDefaultBuffers(void); // Update default internal buffers (VAOs/VBOs) with vertex data
|
|
static void UpdateDefaultBuffers(void); // Update default internal buffers (VAOs/VBOs) with vertex data
|
|
@@ -1018,6 +1020,7 @@ void rlglInit(void)
|
|
|
|
|
|
// Init default Shader (customized for GL 3.3 and ES2)
|
|
// Init default Shader (customized for GL 3.3 and ES2)
|
|
defaultShader = LoadDefaultShader();
|
|
defaultShader = LoadDefaultShader();
|
|
|
|
+ standardShader = LoadStandardShader();
|
|
currentShader = defaultShader;
|
|
currentShader = defaultShader;
|
|
|
|
|
|
LoadDefaultBuffers(); // Initialize default vertex arrays buffers (lines, triangles, quads)
|
|
LoadDefaultBuffers(); // Initialize default vertex arrays buffers (lines, triangles, quads)
|
|
@@ -1046,6 +1049,7 @@ void rlglClose(void)
|
|
{
|
|
{
|
|
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
|
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
|
UnloadDefaultShader();
|
|
UnloadDefaultShader();
|
|
|
|
+ UnloadStandardShader();
|
|
UnloadDefaultBuffers();
|
|
UnloadDefaultBuffers();
|
|
|
|
|
|
// Delete default white texture
|
|
// Delete default white texture
|
|
@@ -1757,19 +1761,30 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform)
|
|
|
|
|
|
// 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.mvpLoc, 1, false, MatrixToFloat(matMVP));
|
|
-
|
|
|
|
- // Setup shader uniforms for material related data
|
|
|
|
- // TODO: Check if using standard shader to get location points
|
|
|
|
|
|
|
|
// Upload to shader material.colDiffuse
|
|
// Upload to shader material.colDiffuse
|
|
float vColorDiffuse[4] = { (float)material.colDiffuse.r/255, (float)material.colDiffuse.g/255, (float)material.colDiffuse.b/255, (float)material.colDiffuse.a/255 };
|
|
float vColorDiffuse[4] = { (float)material.colDiffuse.r/255, (float)material.colDiffuse.g/255, (float)material.colDiffuse.b/255, (float)material.colDiffuse.a/255 };
|
|
glUniform4fv(material.shader.tintColorLoc, 1, vColorDiffuse);
|
|
glUniform4fv(material.shader.tintColorLoc, 1, vColorDiffuse);
|
|
|
|
+
|
|
|
|
+ // Check if using standard shader to get location points
|
|
|
|
+ // NOTE: standard shader specific locations are got at render time to keep Shader struct as simple as possible (with just default shader locations)
|
|
|
|
+ if(material.shader.id == standardShader.id)
|
|
|
|
+ {
|
|
|
|
+ // Send model transformations matrix to shader
|
|
|
|
+ glUniformMatrix4fv(glGetUniformLocation(material.shader.id, "modelMatrix"), 1, false, MatrixToFloat(transform));
|
|
|
|
+
|
|
|
|
+ // Setup shader uniforms for lights
|
|
|
|
+ SetShaderLights(material.shader);
|
|
|
|
+
|
|
|
|
+ // Upload to shader material.colAmbient
|
|
|
|
+ glUniform4f(glGetUniformLocation(material.shader.id, "colAmbient"), (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
|
|
|
|
+ glUniform4f(glGetUniformLocation(material.shader.id, "colSpecular"), (float)material.colSpecular.r/255, (float)material.colSpecular.g/255, (float)material.colSpecular.b/255, (float)material.colSpecular.a/255);
|
|
|
|
|
|
- // TODO: Upload to shader material.colAmbient
|
|
|
|
- // glUniform4f(???, (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.colSpecular
|
|
|
|
- // glUniform4f(???, (float)material.colSpecular.r/255, (float)material.colSpecular.g/255, (float)material.colSpecular.b/255, (float)material.colSpecular.a/255);
|
|
|
|
|
|
+ // TODO: Upload to shader glossiness
|
|
|
|
+ //glUniform1f(???, material.glossiness);
|
|
|
|
+ }
|
|
|
|
|
|
// Set shader textures (diffuse, normal, specular)
|
|
// Set shader textures (diffuse, normal, specular)
|
|
glActiveTexture(GL_TEXTURE0);
|
|
glActiveTexture(GL_TEXTURE0);
|
|
@@ -1791,13 +1806,7 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform)
|
|
glActiveTexture(GL_TEXTURE2);
|
|
glActiveTexture(GL_TEXTURE2);
|
|
glBindTexture(GL_TEXTURE_2D, material.texSpecular.id);
|
|
glBindTexture(GL_TEXTURE_2D, material.texSpecular.id);
|
|
glUniform1i(material.shader.mapSpecularLoc, 2); // Texture fits in active texture unit 2
|
|
glUniform1i(material.shader.mapSpecularLoc, 2); // Texture fits in active texture unit 2
|
|
-
|
|
|
|
- // TODO: Upload to shader glossiness
|
|
|
|
- //glUniform1f(???, material.glossiness);
|
|
|
|
}
|
|
}
|
|
-
|
|
|
|
- // Setup shader uniforms for lights
|
|
|
|
- //SetShaderLights(material.shader);
|
|
|
|
|
|
|
|
if (vaoSupported)
|
|
if (vaoSupported)
|
|
{
|
|
{
|
|
@@ -2148,6 +2157,17 @@ Shader GetDefaultShader(void)
|
|
#endif
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// Get default shader
|
|
|
|
+Shader GetStandardShader(void)
|
|
|
|
+{
|
|
|
|
+#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
|
|
|
+ return standardShader;
|
|
|
|
+#else
|
|
|
|
+ Shader shader = { 0 };
|
|
|
|
+ return shader;
|
|
|
|
+#endif
|
|
|
|
+}
|
|
|
|
+
|
|
// Get shader uniform location
|
|
// Get shader uniform location
|
|
int GetShaderLocation(Shader shader, const char *uniformName)
|
|
int GetShaderLocation(Shader shader, const char *uniformName)
|
|
{
|
|
{
|
|
@@ -2499,13 +2519,75 @@ static Shader LoadStandardShader(void)
|
|
{
|
|
{
|
|
Shader shader;
|
|
Shader shader;
|
|
|
|
|
|
- char *vShaderStr;
|
|
|
|
- char *fShaderStr;
|
|
|
|
-
|
|
|
|
- // TODO: Implement standard uber-shader, supporting all features (GLSL 100 / GLSL 330)
|
|
|
|
-
|
|
|
|
- // NOTE: Shader could be quite extensive so it could be implemented in external files (standard.vs/standard.fs)
|
|
|
|
-
|
|
|
|
|
|
+ // Vertex shader directly defined, no external file required
|
|
|
|
+#if defined(GRAPHICS_API_OPENGL_33)
|
|
|
|
+ char vShaderStr[] = "#version 330 \n"
|
|
|
|
+ "in vec3 vertexPosition; \n"
|
|
|
|
+ "in vec3 vertexNormal; \n"
|
|
|
|
+ "in vec2 vertexTexCoord; \n"
|
|
|
|
+ "in vec4 vertexColor; \n"
|
|
|
|
+ "out vec2 fragTexCoord; \n"
|
|
|
|
+ "out vec4 fragColor; \n"
|
|
|
|
+ "out vec3 fragNormal; \n"
|
|
|
|
+#elif defined(GRAPHICS_API_OPENGL_ES2)
|
|
|
|
+ char vShaderStr[] = "#version 100 \n"
|
|
|
|
+ "attribute vec3 vertexPosition; \n"
|
|
|
|
+ "attribute vec3 vertexNormal; \n"
|
|
|
|
+ "attribute vec2 vertexTexCoord; \n"
|
|
|
|
+ "attribute vec4 vertexColor; \n"
|
|
|
|
+ "varying vec2 fragTexCoord; \n"
|
|
|
|
+ "varying vec4 fragColor; \n"
|
|
|
|
+ "varying vec3 fragNormal; \n"
|
|
|
|
+#endif
|
|
|
|
+ "uniform mat4 mvpMatrix; \n"
|
|
|
|
+ "uniform mat4 modelMatrix; \n"
|
|
|
|
+ "void main() \n"
|
|
|
|
+ "{ \n"
|
|
|
|
+ " fragTexCoord = vertexTexCoord; \n"
|
|
|
|
+ " fragColor = vertexColor; \n"
|
|
|
|
+ " mat3 normalMatrix = transpose(inverse(mat3(modelMatrix))); \n"
|
|
|
|
+ " fragNormal = normalize(normalMatrix*vertexNormal); \n"
|
|
|
|
+ " gl_Position = mvpMatrix*vec4(vertexPosition, 1.0); \n"
|
|
|
|
+ "} \n";
|
|
|
|
+
|
|
|
|
+ // TODO: add specular calculation, multi-lights structs and light type calculations (directional, point, spot)
|
|
|
|
+ // Fragment shader directly defined, no external file required
|
|
|
|
+#if defined(GRAPHICS_API_OPENGL_33)
|
|
|
|
+ char fShaderStr[] = "#version 330 \n"
|
|
|
|
+ "in vec2 fragTexCoord; \n"
|
|
|
|
+ "in vec4 fragColor; \n"
|
|
|
|
+ "in vec3 fragNormal; \n"
|
|
|
|
+ "out vec4 finalColor; \n"
|
|
|
|
+#elif defined(GRAPHICS_API_OPENGL_ES2)
|
|
|
|
+ char fShaderStr[] = "#version 100 \n"
|
|
|
|
+ "precision mediump float; \n" // precision required for OpenGL ES2 (WebGL)
|
|
|
|
+ "varying vec2 fragTexCoord; \n"
|
|
|
|
+ "varying vec4 fragColor; \n"
|
|
|
|
+ "varying vec3 fragNormal; \n"
|
|
|
|
+#endif
|
|
|
|
+ "uniform sampler2D texture0; \n"
|
|
|
|
+ "uniform vec4 fragTintColor; \n"
|
|
|
|
+ "uniform vec4 colAmbient; \n"
|
|
|
|
+ "uniform vec4 colSpecular; \n"
|
|
|
|
+ "uniform vec3 lightDir; \n"
|
|
|
|
+ "vec3 LambertLighting(in vec3 n, in vec3 l) \n"
|
|
|
|
+ "{ \n"
|
|
|
|
+ " return clamp(dot(n, l), 0, 1)*fragTintColor.rgb; \n"
|
|
|
|
+ "} \n"
|
|
|
|
+
|
|
|
|
+ "void main() \n"
|
|
|
|
+ "{ \n"
|
|
|
|
+ " vec3 n = normalize(fragNormal); \n"
|
|
|
|
+ " vec3 l = normalize(lightDir); \n"
|
|
|
|
+#if defined(GRAPHICS_API_OPENGL_33)
|
|
|
|
+ " vec4 texelColor = texture(texture0, fragTexCoord); \n"
|
|
|
|
+ " finalColor = vec4(texelColor.rgb*(colAmbient.rgb + LambertLighting(n, l)) - colSpecular.rgb + colSpecular.rgb, texelColor.a*fragTintColor.a); \n" // Stupid specular color operation to avoid shader location errors
|
|
|
|
+#elif defined(GRAPHICS_API_OPENGL_ES2)
|
|
|
|
+ " vec4 texelColor = texture2D(texture0, fragTexCoord); \n" // NOTE: texture2D() is deprecated on OpenGL 3.3 and ES 3.0
|
|
|
|
+ " gl_FragColor = texelColor*fragTintColor*fragColor; \n"
|
|
|
|
+#endif
|
|
|
|
+ "} \n";
|
|
|
|
+
|
|
shader.id = LoadShaderProgram(vShaderStr, fShaderStr);
|
|
shader.id = LoadShaderProgram(vShaderStr, fShaderStr);
|
|
|
|
|
|
if (shader.id != 0) TraceLog(INFO, "[SHDR ID %i] Standard shader loaded successfully", shader.id);
|
|
if (shader.id != 0) TraceLog(INFO, "[SHDR ID %i] Standard shader loaded successfully", shader.id);
|
|
@@ -2554,10 +2636,23 @@ static void UnloadDefaultShader(void)
|
|
//glDetachShader(defaultShader, vertexShader);
|
|
//glDetachShader(defaultShader, vertexShader);
|
|
//glDetachShader(defaultShader, fragmentShader);
|
|
//glDetachShader(defaultShader, fragmentShader);
|
|
//glDeleteShader(vertexShader); // Already deleted on shader compilation
|
|
//glDeleteShader(vertexShader); // Already deleted on shader compilation
|
|
- //glDeleteShader(fragmentShader); // Already deleted on sahder compilation
|
|
|
|
|
|
+ //glDeleteShader(fragmentShader); // Already deleted on shader compilation
|
|
glDeleteProgram(defaultShader.id);
|
|
glDeleteProgram(defaultShader.id);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// Unload standard shader
|
|
|
|
+static void UnloadStandardShader(void)
|
|
|
|
+{
|
|
|
|
+ glUseProgram(0);
|
|
|
|
+
|
|
|
|
+ //glDetachShader(defaultShader, vertexShader);
|
|
|
|
+ //glDetachShader(defaultShader, fragmentShader);
|
|
|
|
+ //glDeleteShader(vertexShader); // Already deleted on shader compilation
|
|
|
|
+ //glDeleteShader(fragmentShader); // Already deleted on shader compilation
|
|
|
|
+ glDeleteProgram(standardShader.id);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
// Load default internal buffers (lines, triangles, quads)
|
|
// Load default internal buffers (lines, triangles, quads)
|
|
static void LoadDefaultBuffers(void)
|
|
static void LoadDefaultBuffers(void)
|
|
{
|
|
{
|
|
@@ -3006,6 +3101,9 @@ static void UnloadDefaultBuffers(void)
|
|
// TODO: Review memcpy() and parameters pass
|
|
// TODO: Review memcpy() and parameters pass
|
|
static void SetShaderLights(Shader shader)
|
|
static void SetShaderLights(Shader shader)
|
|
{
|
|
{
|
|
|
|
+ // Note: currently working with one light (index 0)
|
|
|
|
+ // TODO: add multi-lights feature (http://www.learnopengl.com/#!Lighting/Multiple-lights)
|
|
|
|
+
|
|
/*
|
|
/*
|
|
// NOTE: Standard Shader must include the following data:
|
|
// NOTE: Standard Shader must include the following data:
|
|
|
|
|
|
@@ -3023,7 +3121,7 @@ static void SetShaderLights(Shader shader)
|
|
uniform Light lights[maxLights];
|
|
uniform Light lights[maxLights];
|
|
*/
|
|
*/
|
|
|
|
|
|
- int locPoint;
|
|
|
|
|
|
+ /*int locPoint;
|
|
char locName[32] = "lights[x].position\0";
|
|
char locName[32] = "lights[x].position\0";
|
|
|
|
|
|
glUseProgram(shader.id);
|
|
glUseProgram(shader.id);
|
|
@@ -3052,9 +3150,10 @@ static void SetShaderLights(Shader shader)
|
|
glUniform1f(locPoint, lights[i]->intensity);
|
|
glUniform1f(locPoint, lights[i]->intensity);
|
|
|
|
|
|
// TODO: Pass to the shader any other required data from LightData struct
|
|
// TODO: Pass to the shader any other required data from LightData struct
|
|
- }
|
|
|
|
|
|
+ }*/
|
|
|
|
|
|
- glUseProgram(0);
|
|
|
|
|
|
+ int locPoint = GetShaderLocation(shader, "lightDir");
|
|
|
|
+ glUniform3f(locPoint, lights[0]->position.x, lights[0]->position.y, lights[0]->position.z);
|
|
}
|
|
}
|
|
|
|
|
|
// Read text data from file
|
|
// Read text data from file
|