| 
				
				
					
						
					
				
				
				 | 
			
			 | 
			
			@ -71,6 +71,8 @@ | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#define MAX_DRAWS_BY_TEXTURE      256   // Draws are organized by texture changes | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#define TEMP_VERTEX_BUFFER_SIZE  4096   // Temporal Vertex Buffer (required for vertex-transformations) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			                                        // NOTE: Every vertex are 3 floats (12 bytes) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			                                         | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#define MAX_LIGHTS                  8   // Max lights supported by standard shader | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#ifndef GL_SHADING_LANGUAGE_VERSION | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    #define GL_SHADING_LANGUAGE_VERSION         0x8B8C | 
			
		
		
	
	
		
			
				| 
				
					
						
					
				
				
					
						
					
				
				
				 | 
			
			 | 
			
			@ -199,6 +201,10 @@ 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 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#endif | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			// Compressed textures support flags | 
			
		
		
	
	
		
			
				| 
				
					
						
					
				
				
					
						
					
				
				
				 | 
			
			 | 
			
			@ -227,6 +233,7 @@ static void LoadCompressedTexture(unsigned char *data, int width, int height, in | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			static unsigned int LoadShaderProgram(char *vShaderStr, char *fShaderStr);  // Load custom shader strings and return program id | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			static Shader LoadDefaultShader(void);      // Load default shader (just vertex positioning and texture coloring) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			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 UnloadDefaultShader(void);      // Unload default shader | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
	
		
			
				| 
				
				
				
					
						
					
				
				 | 
			
			 | 
			
			@ -235,6 +242,8 @@ static void UpdateDefaultBuffers(void);     // Update default internal buffers ( | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			static void DrawDefaultBuffers(void);       // Draw default internal buffers vertex data | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			static void UnloadDefaultBuffers(void);     // Unload default internal buffers vertex data from CPU and GPU | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			static void SetShaderLights(Shader shader); // Sets shader uniform values for lights array | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			static char *ReadTextFile(const char *fileName); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			#endif | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
	
		
			
				| 
				
					
						
					
				
				
					
						
					
				
				
				 | 
			
			 | 
			
			@ -1749,11 +1758,19 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    // Send combined model-view-projection matrix to shader | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    glUniformMatrix4fv(material.shader.mvpLoc, 1, false, MatrixToFloat(matMVP)); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    // Apply color tinting (material.colDiffuse) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    // NOTE: Just update one uniform on fragment shader | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    float vColor[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, vColor); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    // Setup shader uniforms for material related data | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    // TODO: Check if using standard shader to get location points | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			     | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    // 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 }; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    glUniform4fv(material.shader.tintColorLoc, 1, vColorDiffuse); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			     | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    // 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); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			     | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    // Set shader textures (diffuse, normal, specular) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    glActiveTexture(GL_TEXTURE0); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    glBindTexture(GL_TEXTURE_2D, material.texDiffuse.id); | 
			
		
		
	
	
		
			
				| 
				
				
				
					
						
					
				
				 | 
			
			 | 
			
			@ -1764,6 +1781,9 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        glActiveTexture(GL_TEXTURE1); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        glBindTexture(GL_TEXTURE_2D, material.texNormal.id); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        glUniform1i(material.shader.mapNormalLoc, 1);     // Texture fits in active texture unit 1 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			         | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        // TODO: Upload to shader normalDepth | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        //glUniform1f(???, material.normalDepth); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    } | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			     | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    if ((material.texSpecular.id != 0) && (material.shader.mapSpecularLoc != -1)) | 
			
		
		
	
	
		
			
				| 
				
				
				
					
						
					
				
				 | 
			
			 | 
			
			@ -1771,7 +1791,13 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        glActiveTexture(GL_TEXTURE2); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        glBindTexture(GL_TEXTURE_2D, material.texSpecular.id); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        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) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    { | 
			
		
		
	
	
		
			
				| 
				
					
						
					
				
				
					
						
					
				
				
				 | 
			
			 | 
			
			@ -2198,6 +2224,55 @@ void SetBlendMode(int mode) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    } | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			} | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			// Create a new light, initialize it and add to pool | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			// TODO: Review creation parameters (only generic ones) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			Light CreateLight(int type, Vector3 position, Color diffuse) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			{ | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    // Allocate dynamic memory | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    Light light = (Light)malloc(sizeof(LightData)); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			     | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    // Initialize light values with generic values | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    light->id = lightsCount; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    light->type = type; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    light->enabled = true; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			     | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    light->position = position; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    light->direction = (Vector3){ 0.0f, 0.0f, 0.0f }; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    light->intensity = 1.0f; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    light->diffuse = diffuse; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    light->specular = WHITE; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			     | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    // Add new light to the array | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    lights[lightsCount] = light; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			     | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    // Increase enabled lights count | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    lightsCount++; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			     | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    return light; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			} | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			// Destroy a light and take it out of the list | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			void DestroyLight(Light light) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			{ | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    // Free dynamic memory allocation | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    free(lights[light->id]); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			     | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    // Remove *obj from the pointers array | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    for (int i = light->id; i < lightsCount; i++) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        // Resort all the following pointers of the array | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        if ((i + 1) < lightsCount) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			            lights[i] = lights[i + 1]; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			            lights[i]->id = lights[i + 1]->id; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        } | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        else free(lights[i]); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    } | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			     | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    // Decrease enabled physic objects count | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    lightsCount--; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			} | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			//---------------------------------------------------------------------------------- | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			// Module specific Functions Definition | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			//---------------------------------------------------------------------------------- | 
			
		
		
	
	
		
			
				| 
				
					
						
					
				
				
					
						
					
				
				
				 | 
			
			 | 
			
			@ -2415,6 +2490,32 @@ static Shader LoadDefaultShader(void) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    return shader; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			} | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			// Load standard shader | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			// NOTE: This shader supports:  | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			//      - Up to 3 different maps: diffuse, normal, specular | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			//      - Material properties: colDiffuse, colAmbient, colSpecular, glossiness, normalDepth | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			//      - Up to 8 lights: Point, Directional or Spot | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			static Shader LoadStandardShader(void) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			{ | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    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) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			     | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    shader.id = LoadShaderProgram(vShaderStr, fShaderStr); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    if (shader.id != 0) TraceLog(INFO, "[SHDR ID %i] Standard shader loaded successfully", shader.id); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    else TraceLog(WARNING, "[SHDR ID %i] Standard shader could not be loaded", shader.id); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    if (shader.id != 0) LoadDefaultShaderLocations(&shader);    // TODO: Review locations fetching | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    return shader; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			} | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			// Get location handlers to for shader attributes and uniforms | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			// NOTE: If any location is not found, loc point becomes -1 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			static void LoadDefaultShaderLocations(Shader *shader) | 
			
		
		
	
	
		
			
				| 
				
					
						
					
				
				
					
						
					
				
				
				 | 
			
			 | 
			
			@ -2900,6 +3001,62 @@ static void UnloadDefaultBuffers(void) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    free(quads.indices); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			} | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			// Sets shader uniform values for lights array | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			// NOTE: It would be far easier with shader UBOs but are not supported on OpenGL ES 2.0f | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			// TODO: Review memcpy() and parameters pass | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			static void SetShaderLights(Shader shader) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			{ | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    /* | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    // NOTE: Standard Shader must include the following data: | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			         | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    // Shader Light struct | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    struct Light { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        vec3 position; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        vec3 direction; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			         | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        vec3 diffuse; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        float intensity; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    } | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    const int maxLights = 8; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    uniform int lightsCount;            // Number of lights | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    uniform Light lights[maxLights]; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    */ | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			     | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    int locPoint; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    char locName[32] = "lights[x].position\0"; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			     | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    glUseProgram(shader.id); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    locPoint = glGetUniformLocation(shader.id, "lightsCount"); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    glUniform1i(locPoint, lightsCount); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    for (int i = 0; i < lightsCount; i++) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        locName[7] = '0' + i; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			         | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        memcpy(&locName[10], "position\0", strlen("position\0")); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        locPoint = glGetUniformLocation(shader.id, locName); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        glUniform3f(locPoint, lights[i]->position.x, lights[i]->position.y, lights[i]->position.z); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			         | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        memcpy(&locName[10], "direction\0", strlen("direction\0")); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        locPoint = glGetUniformLocation(shader.id, locName);        | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        glUniform3f(locPoint, lights[i]->direction.x, lights[i]->direction.y, lights[i]->direction.z); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        memcpy(&locName[10], "diffuse\0", strlen("diffuse\0")); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        locPoint = glGetUniformLocation(shader.id, locName); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        glUniform4f(locPoint, (float)lights[i]->diffuse.r/255, (float)lights[i]->diffuse.g/255, (float)lights[i]->diffuse.b/255, (float)lights[i]->diffuse.a/255 ); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			         | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        memcpy(&locName[10], "intensity\0", strlen("intensity\0")); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        locPoint = glGetUniformLocation(shader.id, locName); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        glUniform1f(locPoint, lights[i]->intensity); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			         | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        // TODO: Pass to the shader any other required data from LightData struct | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    } | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			     | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    glUseProgram(0); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			} | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			// Read text data from file | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			// NOTE: text chars array should be freed manually | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			static char *ReadTextFile(const char *fileName) | 
			
		
		
	
	
		
			
				| 
				
					
						
					
				
				
				
				 | 
			
			 | 
			
			
 |