aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorraysan5 <raysan5@gmail.com>2016-07-06 20:33:46 +0200
committerraysan5 <raysan5@gmail.com>2016-07-06 20:33:46 +0200
commit7cefbd8a947551f6c63dba88117099d6c0f4998b (patch)
treedae0c3d860df39b63d025a9c70e1b12a9a5f3c16
parente2a3a52ad6acaacf8c839fcefd405ff3258dcad9 (diff)
downloadraylib-7cefbd8a947551f6c63dba88117099d6c0f4998b.tar.gz
raylib-7cefbd8a947551f6c63dba88117099d6c0f4998b.zip
Updated lighting system...
...to avoid dynamic conditions on for loop (lightsCount) on standard shader, it seems GLSL 100 doesn't support that feature... on some GPUs like RaspberryPi...
-rw-r--r--src/raylib.h2
-rw-r--r--src/rlgl.c196
-rw-r--r--src/rlgl.h4
-rw-r--r--src/standard_shader.h3
4 files changed, 109 insertions, 96 deletions
diff --git a/src/raylib.h b/src/raylib.h
index 227f83f2..1d160492 100644
--- a/src/raylib.h
+++ b/src/raylib.h
@@ -431,8 +431,8 @@ typedef struct Model {
// Light type
typedef struct LightData {
unsigned int id; // Light unique id
- int type; // Light type: LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT
bool enabled; // Light enabled
+ int type; // Light type: LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT
Vector3 position; // Light position
Vector3 target; // Light target: LIGHT_DIRECTIONAL and LIGHT_SPOT (cone direction target)
diff --git a/src/rlgl.c b/src/rlgl.c
index 089e2809..aa729824 100644
--- a/src/rlgl.c
+++ b/src/rlgl.c
@@ -260,7 +260,7 @@ static bool texCompASTCSupported = false; // ASTC texture compression support
// Lighting data
static Light lights[MAX_LIGHTS]; // Lights pool
-static int lightsCount; // Enabled lights counter
+static int lightsCount = 0; // Enabled lights counter
#endif
#if defined(RLGL_OCULUS_SUPPORT)
@@ -2454,24 +2454,28 @@ Light CreateLight(int type, Vector3 position, Color diffuse)
Light light = NULL;
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
- // Allocate dynamic memory
- light = (Light)malloc(sizeof(LightData));
-
- // Initialize light values with generic values
- light->id = lightsCount;
- light->type = type;
- light->enabled = true;
-
- light->position = position;
- light->target = (Vector3){ 0.0f, 0.0f, 0.0f };
- light->intensity = 1.0f;
- light->diffuse = diffuse;
-
- // Add new light to the array
- lights[lightsCount] = light;
-
- // Increase enabled lights count
- lightsCount++;
+ if (lightsCount < MAX_LIGHTS)
+ {
+ // Allocate dynamic memory
+ light = (Light)malloc(sizeof(LightData));
+
+ // Initialize light values with generic values
+ light->id = lightsCount;
+ light->type = type;
+ light->enabled = true;
+
+ light->position = position;
+ light->target = (Vector3){ 0.0f, 0.0f, 0.0f };
+ light->intensity = 1.0f;
+ light->diffuse = diffuse;
+
+ // Add new light to the array
+ lights[lightsCount] = light;
+
+ // Increase enabled lights count
+ lightsCount++;
+ }
+ else TraceLog(WARNING, "Too many lights, only supported up to %i lights", MAX_LIGHTS);
#else
// TODO: Support OpenGL 1.1 lighting system
TraceLog(WARNING, "Lighting currently not supported on OpenGL 1.1");
@@ -2484,23 +2488,26 @@ Light CreateLight(int type, Vector3 position, Color diffuse)
void DestroyLight(Light light)
{
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
- // Free dynamic memory allocation
- free(lights[light->id]);
-
- // Remove *obj from the pointers array
- for (int i = light->id; i < lightsCount; i++)
+ if (light != NULL)
{
- // Resort all the following pointers of the array
- if ((i + 1) < lightsCount)
+ // Free dynamic memory allocation
+ free(lights[light->id]);
+
+ // Remove *obj from the pointers array
+ for (int i = light->id; i < lightsCount; i++)
{
- lights[i] = lights[i + 1];
- lights[i]->id = lights[i + 1]->id;
+ // 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]);
}
- else free(lights[i]);
+
+ // Decrease enabled physic objects count
+ lightsCount--;
}
-
- // Decrease enabled physic objects count
- lightsCount--;
#endif
}
@@ -3625,72 +3632,79 @@ static void UnloadDefaultBuffers(void)
// NOTE: It would be far easier with shader UBOs but are not supported on OpenGL ES 2.0f
static void SetShaderLights(Shader shader)
{
- int locPoint = glGetUniformLocation(shader.id, "lightsCount");
- glUniform1i(locPoint, lightsCount);
-
+ int locPoint = -1;
char locName[32] = "lights[x].position\0";
- for (int i = 0; i < lightsCount; i++)
+ for (int i = 0; i < MAX_LIGHTS; i++)
{
locName[7] = '0' + i;
-
- memcpy(&locName[10], "enabled\0", strlen("enabled\0") + 1);
- locPoint = GetShaderLocation(shader, locName);
- glUniform1i(locPoint, lights[i]->enabled);
-
- memcpy(&locName[10], "type\0", strlen("type\0") + 1);
- locPoint = GetShaderLocation(shader, locName);
- glUniform1i(locPoint, lights[i]->type);
-
- memcpy(&locName[10], "diffuse\0", strlen("diffuse\0") + 2);
- 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);
-
- switch (lights[i]->type)
+
+ if (lights[i] != NULL) // Only upload registered lights data
{
- case LIGHT_POINT:
- {
- memcpy(&locName[10], "position\0", strlen("position\0") + 1);
- locPoint = GetShaderLocation(shader, locName);
- glUniform3f(locPoint, lights[i]->position.x, lights[i]->position.y, lights[i]->position.z);
-
- memcpy(&locName[10], "radius\0", strlen("radius\0") + 2);
- locPoint = GetShaderLocation(shader, locName);
- glUniform1f(locPoint, lights[i]->radius);
- } break;
- case LIGHT_DIRECTIONAL:
- {
- memcpy(&locName[10], "direction\0", strlen("direction\0") + 2);
- locPoint = GetShaderLocation(shader, locName);
- Vector3 direction = { lights[i]->target.x - lights[i]->position.x, lights[i]->target.y - lights[i]->position.y, lights[i]->target.z - lights[i]->position.z };
- VectorNormalize(&direction);
- glUniform3f(locPoint, direction.x, direction.y, direction.z);
- } break;
- case LIGHT_SPOT:
+ memcpy(&locName[10], "enabled\0", strlen("enabled\0") + 1);
+ locPoint = GetShaderLocation(shader, locName);
+ glUniform1i(locPoint, lights[i]->enabled);
+
+ memcpy(&locName[10], "type\0", strlen("type\0") + 1);
+ locPoint = GetShaderLocation(shader, locName);
+ glUniform1i(locPoint, lights[i]->type);
+
+ memcpy(&locName[10], "diffuse\0", strlen("diffuse\0") + 2);
+ 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);
+
+ switch (lights[i]->type)
{
- memcpy(&locName[10], "position\0", strlen("position\0") + 1);
- locPoint = GetShaderLocation(shader, locName);
- glUniform3f(locPoint, lights[i]->position.x, lights[i]->position.y, lights[i]->position.z);
-
- memcpy(&locName[10], "direction\0", strlen("direction\0") + 2);
- locPoint = GetShaderLocation(shader, locName);
-
- Vector3 direction = { lights[i]->target.x - lights[i]->position.x, lights[i]->target.y - lights[i]->position.y, lights[i]->target.z - lights[i]->position.z };
- VectorNormalize(&direction);
- glUniform3f(locPoint, direction.x, direction.y, direction.z);
-
- memcpy(&locName[10], "coneAngle\0", strlen("coneAngle\0"));
- locPoint = GetShaderLocation(shader, locName);
- glUniform1f(locPoint, lights[i]->coneAngle);
- } break;
- default: break;
+ case LIGHT_POINT:
+ {
+ memcpy(&locName[10], "position\0", strlen("position\0") + 1);
+ locPoint = GetShaderLocation(shader, locName);
+ glUniform3f(locPoint, lights[i]->position.x, lights[i]->position.y, lights[i]->position.z);
+
+ memcpy(&locName[10], "radius\0", strlen("radius\0") + 2);
+ locPoint = GetShaderLocation(shader, locName);
+ glUniform1f(locPoint, lights[i]->radius);
+ } break;
+ case LIGHT_DIRECTIONAL:
+ {
+ memcpy(&locName[10], "direction\0", strlen("direction\0") + 2);
+ locPoint = GetShaderLocation(shader, locName);
+ Vector3 direction = { lights[i]->target.x - lights[i]->position.x, lights[i]->target.y - lights[i]->position.y, lights[i]->target.z - lights[i]->position.z };
+ VectorNormalize(&direction);
+ glUniform3f(locPoint, direction.x, direction.y, direction.z);
+ } break;
+ case LIGHT_SPOT:
+ {
+ memcpy(&locName[10], "position\0", strlen("position\0") + 1);
+ locPoint = GetShaderLocation(shader, locName);
+ glUniform3f(locPoint, lights[i]->position.x, lights[i]->position.y, lights[i]->position.z);
+
+ memcpy(&locName[10], "direction\0", strlen("direction\0") + 2);
+ locPoint = GetShaderLocation(shader, locName);
+
+ Vector3 direction = { lights[i]->target.x - lights[i]->position.x, lights[i]->target.y - lights[i]->position.y, lights[i]->target.z - lights[i]->position.z };
+ VectorNormalize(&direction);
+ glUniform3f(locPoint, direction.x, direction.y, direction.z);
+
+ memcpy(&locName[10], "coneAngle\0", strlen("coneAngle\0"));
+ locPoint = GetShaderLocation(shader, locName);
+ glUniform1f(locPoint, lights[i]->coneAngle);
+ } break;
+ default: break;
+ }
+
+ // TODO: Pass to the shader any other required data from LightData struct
+ }
+ else // Not enabled lights
+ {
+ memcpy(&locName[10], "enabled\0", strlen("enabled\0") + 1);
+ locPoint = GetShaderLocation(shader, locName);
+ glUniform1i(locPoint, 0);
}
-
- // TODO: Pass to the shader any other required data from LightData struct
}
}
diff --git a/src/rlgl.h b/src/rlgl.h
index f984c0c6..9afafc52 100644
--- a/src/rlgl.h
+++ b/src/rlgl.h
@@ -218,9 +218,9 @@ typedef enum { OPENGL_11 = 1, OPENGL_21, OPENGL_33, OPENGL_ES_20 } GlVersion;
// Light type
typedef struct LightData {
unsigned int id; // Light unique id
- int type; // Light type: LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT
bool enabled; // Light enabled
-
+ int type; // Light type: LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT
+
Vector3 position; // Light position
Vector3 target; // Light target: LIGHT_DIRECTIONAL and LIGHT_SPOT (cone direction target)
float radius; // Light attenuation radius light intensity reduced with distance (world distance)
diff --git a/src/standard_shader.h b/src/standard_shader.h
index e1668ae7..deae7fe1 100644
--- a/src/standard_shader.h
+++ b/src/standard_shader.h
@@ -78,7 +78,6 @@ static const char fStandardShaderStr[] =
" 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"
@@ -157,7 +156,7 @@ static const char fStandardShaderStr[] =
#elif defined(GRAPHICS_API_OPENGL_33)
" if (useSpecular == 1) spec *= normalize(texture(texture2, fragTexCoord).r);\n"
#endif
-" for (int i = 0; i < lightsCount; i++)\n"
+" for (int i = 0; i < maxLights; i++)\n"
" {\n"
" if (lights[i].enabled == 1)\n"
" {\n"