aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRay <raysan5@gmail.com>2016-06-07 00:32:45 +0200
committerRay <raysan5@gmail.com>2016-06-07 00:32:45 +0200
commit9281e477eb3845b4a375836bcd00df99ff4b6af1 (patch)
treed0c9af658d89822b590b7c00a99f67fdbaa08ca0 /src
parent1bcf500ecac076892c4eac0594b997add6dcac71 (diff)
downloadraylib-9281e477eb3845b4a375836bcd00df99ff4b6af1.tar.gz
raylib-9281e477eb3845b4a375836bcd00df99ff4b6af1.zip
Embed standard shader into raylib
Diffstat (limited to 'src')
-rw-r--r--src/rlgl.c58
-rw-r--r--src/standard_shader.h166
2 files changed, 203 insertions, 21 deletions
diff --git a/src/rlgl.c b/src/rlgl.c
index 8d230550..3dda77b1 100644
--- a/src/rlgl.c
+++ b/src/rlgl.c
@@ -62,6 +62,10 @@
#include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end() [Used only on TraceLog()]
#endif
+#if !defined(GRAPHICS_API_OPENGL_11)
+ #include "standard_shader.h" // Standard shader to embed
+#endif
+
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
@@ -189,26 +193,27 @@ static bool useTempBuffer = false;
// Shader Programs
static Shader defaultShader;
-static Shader standardShader;
-static Shader currentShader; // By default, defaultShader
+static Shader standardShader; // Lazy initialization when GetStandardShader()
+static Shader currentShader; // By default, defaultShader
+static bool standardShaderLoaded = false;
// Flags for supported extensions
-static bool vaoSupported = false; // VAO support (OpenGL ES2 could not support VAO extension)
+static bool vaoSupported = false; // VAO support (OpenGL ES2 could not support VAO extension)
// Compressed textures support flags
-static bool texCompETC1Supported = false; // ETC1 texture compression support
-static bool texCompETC2Supported = false; // ETC2/EAC texture compression support
-static bool texCompPVRTSupported = false; // PVR texture compression support
-static bool texCompASTCSupported = false; // ASTC texture compression support
+static bool texCompETC1Supported = false; // ETC1 texture compression support
+static bool texCompETC2Supported = false; // ETC2/EAC texture compression support
+static bool texCompPVRTSupported = false; // PVR texture compression support
+static bool texCompASTCSupported = false; // ASTC texture compression support
// Lighting data
-static Light lights[MAX_LIGHTS]; // Lights pool
-static int lightsCount; // Counts current enabled physic objects
+static Light lights[MAX_LIGHTS]; // Lights pool
+static int lightsCount; // Counts current enabled physic objects
#endif
// Compressed textures support flags
-static bool texCompDXTSupported = false; // DDS texture compression support
-static bool npotSupported = false; // NPOT textures full support
+static bool texCompDXTSupported = false; // DDS texture compression support
+static bool npotSupported = false; // NPOT textures full support
#if defined(GRAPHICS_API_OPENGL_ES2)
// NOTE: VAO functionality is exposed through extensions (OES)
@@ -1031,7 +1036,6 @@ void rlglInit(void)
// Init default Shader (customized for GL 3.3 and ES2)
defaultShader = LoadDefaultShader();
- standardShader = LoadStandardShader();
currentShader = defaultShader;
LoadDefaultBuffers(); // Initialize default vertex arrays buffers (lines, triangles, quads)
@@ -2184,14 +2188,22 @@ Shader GetDefaultShader(void)
}
// Get default shader
+// NOTE: Inits global variable standardShader
Shader GetStandardShader(void)
{
-#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
- return standardShader;
-#else
Shader shader = { 0 };
- return shader;
+
+#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
+ if (standardShaderLoaded) shader = standardShader;
+ else
+ {
+ // Lazy initialization of standard shader
+ standardShader = LoadStandardShader();
+ shader = standardShader;
+ }
#endif
+
+ return shader;
}
// Get shader uniform location
@@ -2567,18 +2579,22 @@ static Shader LoadDefaultShader(void)
// Load standard shader
// NOTE: This shader supports:
-// - Up to 3 different maps: diffuse, normal, specular
-// - Material properties: colAmbient, colDiffuse, colSpecular, glossiness
-// - Up to 8 lights: Point, Directional or Spot
+// - Up to 3 different maps: diffuse, normal, specular
+// - Material properties: colAmbient, colDiffuse, colSpecular, glossiness
+// - Up to 8 lights: Point, Directional or Spot
static Shader LoadStandardShader(void)
{
- // Load standard shader (TODO: rewrite as char pointers)
- Shader shader = LoadShader("resources/shaders/standard.vs", "resources/shaders/standard.fs");
+ Shader shader;
+
+ // Load standard shader (embeded in standard_shader.h)
+ shader.id = LoadShaderProgram(vStandardShaderStr, fStandardShaderStr);
if (shader.id != 0)
{
LoadDefaultShaderLocations(&shader);
TraceLog(INFO, "[SHDR ID %i] Standard shader loaded successfully", shader.id);
+
+ standardShaderLoaded = true;
}
else
{
diff --git a/src/standard_shader.h b/src/standard_shader.h
new file mode 100644
index 00000000..956b5c32
--- /dev/null
+++ b/src/standard_shader.h
@@ -0,0 +1,166 @@
+
+// Vertex shader definition to embed, no external file required
+const static unsigned char vStandardShaderStr[] =
+#if defined(GRAPHICS_API_OPENGL_21)
+"#version 120 \n"
+#elif defined(GRAPHICS_API_OPENGL_ES2)
+"#version 100 \n"
+#endif
+#if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21)
+"attribute vec3 vertexPosition; \n"
+"attribute vec3 vertexNormal; \n"
+"attribute vec2 vertexTexCoord; \n"
+"attribute vec4 vertexColor; \n"
+"varying vec3 fragPosition; \n"
+"varying vec3 fragNormal; \n"
+"varying vec2 fragTexCoord; \n"
+"varying vec4 fragColor; \n"
+#elif defined(GRAPHICS_API_OPENGL_33)
+"#version 330 \n"
+"in vec3 vertexPosition; \n"
+"in vec3 vertexNormal; \n"
+"in vec2 vertexTexCoord; \n"
+"in vec4 vertexColor; \n"
+"out vec3 fragPosition; \n"
+"out vec3 fragNormal; \n"
+"out vec2 fragTexCoord; \n"
+"out vec4 fragColor; \n"
+#endif
+"uniform mat4 mvpMatrix; \n"
+"void main() \n"
+"{ \n"
+" fragPosition = vertexPosition; \n"
+" fragNormal = vertexNormal; \n"
+" fragTexCoord = vertexTexCoord; \n"
+" fragColor = vertexColor; \n"
+" gl_Position = mvpMatrix*vec4(vertexPosition, 1.0); \n"
+"} \n";
+
+// Fragment shader definition to embed, no external file required
+const static unsigned char fStandardShaderStr[] =
+#if defined(GRAPHICS_API_OPENGL_21)
+"#version 120 \n"
+#elif defined(GRAPHICS_API_OPENGL_ES2)
+"#version 100 \n"
+"precision mediump float; \n" // precision required for OpenGL ES2 (WebGL)
+#endif
+#if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21)
+"varying vec3 fragPosition; \n"
+"varying vec3 fragNormal; \n"
+"varying vec2 fragTexCoord; \n"
+"varying vec4 fragColor; \n"
+#elif defined(GRAPHICS_API_OPENGL_33)
+"#version 330 \n"
+"in vec3 fragPosition; \n"
+"in vec3 fragNormal; \n"
+"in vec2 fragTexCoord; \n"
+"in vec4 fragColor; \n"
+"out vec4 finalColor; \n"
+#endif
+"uniform sampler2D texture0; \n"
+"uniform sampler2D texture1; \n"
+"uniform sampler2D texture2; \n"
+"uniform vec4 colAmbient; \n"
+"uniform vec4 colDiffuse; \n"
+"uniform vec4 colSpecular; \n"
+"uniform float glossiness; \n"
+"uniform int useNormal; \n"
+"uniform int useSpecular; \n"
+"uniform mat4 modelMatrix; \n"
+"uniform vec3 viewDir; \n"
+"struct Light { \n"
+" int enabled; \n"
+" int type; \n"
+" vec3 position; \n"
+" vec3 direction; \n"
+" vec4 diffuse; \n"
+" float intensity; \n"
+" float radius; \n"
+" float coneAngle; }; \n"
+"const int maxLights = 8; \n"
+"uniform int lightsCount; \n"
+"uniform Light lights[maxLights]; \n"
+"\n"
+"vec3 CalcPointLight(Light l, vec3 n, vec3 v, float s) \n"
+"{\n"
+" vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1));\n"
+" vec3 surfaceToLight = l.position - surfacePos;\n"
+" float brightness = clamp(dot(n, surfaceToLight)/(length(surfaceToLight)*length(n)), 0, 1);\n"
+" float diff = 1.0/dot(surfaceToLight/l.radius, surfaceToLight/l.radius)*brightness*l.intensity;\n"
+" float spec = 0.0;\n"
+" if (diff > 0.0)\n"
+" {\n"
+" vec3 h = normalize(-l.direction + v);\n"
+" spec = pow(dot(n, h), 3 + glossiness)*s;\n"
+" }\n"
+" return (diff*l.diffuse.rgb + spec*colSpecular.rgb);\n"
+"}\n"
+"\n"
+"vec3 CalcDirectionalLight(Light l, vec3 n, vec3 v, float s)\n"
+"{\n"
+" vec3 lightDir = normalize(-l.direction);\n"
+" float diff = clamp(dot(n, lightDir), 0.0, 1.0)*l.intensity;\n"
+" float spec = 0.0;\n"
+" if (diff > 0.0)\n"
+" {\n"
+" vec3 h = normalize(lightDir + v);\n"
+" spec = pow(dot(n, h), 3 + glossiness)*s;\n"
+" }\n"
+" return (diff*l.intensity*l.diffuse.rgb + spec*colSpecular.rgb);\n"
+"}\n"
+"\n"
+"vec3 CalcSpotLight(Light l, vec3 n, vec3 v, float s)\n"
+"{\n"
+" vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1));\n"
+" vec3 lightToSurface = normalize(surfacePos - l.position);\n"
+" vec3 lightDir = normalize(-l.direction);\n"
+" float diff = clamp(dot(n, lightDir), 0.0, 1.0)*l.intensity;\n"
+" float attenuation = clamp(dot(n, lightToSurface), 0.0, 1.0);\n"
+" attenuation = dot(lightToSurface, -lightDir);\n"
+" float lightToSurfaceAngle = degrees(acos(attenuation));\n"
+" if (lightToSurfaceAngle > l.coneAngle) attenuation = 0.0;\n"
+" float falloff = (l.coneAngle - lightToSurfaceAngle)/l.coneAngle;\n"
+" float diffAttenuation = diff*attenuation;\n"
+" float spec = 0.0;\n"
+" if (diffAttenuation > 0.0)\n"
+" {\n"
+" vec3 h = normalize(lightDir + v);\n"
+" spec = pow(dot(n, h), 3 + glossiness)*s;\n"
+" }\n"
+" return (falloff*(diffAttenuation*l.diffuse.rgb + spec*colSpecular.rgb));\n"
+"}\n"
+"\n"
+"void main()\n"
+"{\n"
+" mat3 normalMatrix = transpose(inverse(mat3(modelMatrix)));\n"
+" vec3 normal = normalize(normalMatrix*fragNormal);\n"
+" vec3 n = normalize(normal);\n"
+" vec3 v = normalize(viewDir);\n"
+" vec4 texelColor = texture(texture0, fragTexCoord);\n"
+" vec3 lighting = colAmbient.rgb;\n"
+" if (useNormal == 1)\n"
+" {\n"
+" n *= texture(texture1, fragTexCoord).rgb;\n"
+" n = normalize(n);\n"
+" }\n"
+" float spec = 1.0;\n"
+" if (useSpecular == 1) spec *= normalize(texture(texture2, fragTexCoord).r);\n"
+" for (int i = 0; i < lightsCount; i++)\n"
+" {\n"
+" if (lights[i].enabled == 1)\n"
+" {\n"
+" switch (lights[i].type)\n"
+" {\n"
+" case 0: lighting += CalcPointLight(lights[i], n, v, spec); break;\n"
+" case 1: lighting += CalcDirectionalLight(lights[i], n, v, spec); break;\n"
+" case 2: lighting += CalcSpotLight(lights[i], n, v, spec); break;\n"
+" default: break;\n"
+" }\n"
+" }\n"
+" }\n"
+#if defined(GRAPHICS_API_OPENGL_33)
+" finalColor = vec4(texelColor.rgb*lighting*colDiffuse.rgb, texelColor.a*colDiffuse.a); \n"
+#elif defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21)
+" gl_FragColor = vec4(texelColor.rgb*lighting*colDiffuse.rgb, texelColor.a*colDiffuse.a); \n"
+#endif
+"} \n"; \ No newline at end of file