Ver código fonte

Embed standard shader into raylib

Ray 9 anos atrás
pai
commit
9281e477eb
2 arquivos alterados com 203 adições e 21 exclusões
  1. 37 21
      src/rlgl.c
  2. 166 0
      src/standard_shader.h

+ 37 - 21
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
     {

+ 166 - 0
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";