|
|
@ -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) |
|
|
|