mirror of
				https://github.com/raysan5/raylib.git
				synced 2025-10-26 12:27:01 +00:00 
			
		
		
		
	REVIEWED: Examples section comments, for better organization and consistency
This commit is contained in:
		| @@ -24,6 +24,9 @@ | |||||||
|  |  | ||||||
| #define MAX_ENVIRONMENT_ELEMENTS    5 | #define MAX_ENVIRONMENT_ELEMENTS    5 | ||||||
|  |  | ||||||
|  | //---------------------------------------------------------------------------------- | ||||||
|  | // Types and Structures Definition | ||||||
|  | //---------------------------------------------------------------------------------- | ||||||
| typedef struct Player { | typedef struct Player { | ||||||
|     Vector2 position; |     Vector2 position; | ||||||
|     float speed; |     float speed; | ||||||
| @@ -36,7 +39,6 @@ typedef struct EnvElement { | |||||||
|     Color color; |     Color color; | ||||||
| } EnvElement; | } EnvElement; | ||||||
|  |  | ||||||
|  |  | ||||||
| //------------------------------------------------------------------------------------ | //------------------------------------------------------------------------------------ | ||||||
| // Program main entry point | // Program main entry point | ||||||
| //------------------------------------------------------------------------------------ | //------------------------------------------------------------------------------------ | ||||||
|   | |||||||
| @@ -31,7 +31,7 @@ typedef struct ColorRect { | |||||||
| //------------------------------------------------------------------------------------ | //------------------------------------------------------------------------------------ | ||||||
| // Module Functions Declaration | // Module Functions Declaration | ||||||
| //------------------------------------------------------------------------------------ | //------------------------------------------------------------------------------------ | ||||||
| static Color GenerateRandomColor(); | static Color GenerateRandomColor(void); | ||||||
| static ColorRect *GenerateRandomColorRectSequence(float rectCount, float rectWidth, float screenWidth, float screenHeight); | static ColorRect *GenerateRandomColorRectSequence(float rectCount, float rectWidth, float screenWidth, float screenHeight); | ||||||
| static void ShuffleColorRectSequence(ColorRect *rectangles, int rectCount); | static void ShuffleColorRectSequence(ColorRect *rectangles, int rectCount); | ||||||
|  |  | ||||||
| @@ -122,7 +122,7 @@ int main(void) | |||||||
| //------------------------------------------------------------------------------------ | //------------------------------------------------------------------------------------ | ||||||
| // Module Functions Definition | // Module Functions Definition | ||||||
| //------------------------------------------------------------------------------------ | //------------------------------------------------------------------------------------ | ||||||
| static Color GenerateRandomColor() | static Color GenerateRandomColor(void) | ||||||
| { | { | ||||||
|     Color color = { |     Color color = { | ||||||
|         GetRandomValue(0, 255), |         GetRandomValue(0, 255), | ||||||
|   | |||||||
| @@ -25,7 +25,9 @@ typedef enum { | |||||||
|     STORAGE_POSITION_HISCORE    = 1 |     STORAGE_POSITION_HISCORE    = 1 | ||||||
| } StorageData; | } StorageData; | ||||||
|  |  | ||||||
| // Persistent storage functions | //------------------------------------------------------------------------------------ | ||||||
|  | // Module Functions Declaration | ||||||
|  | //------------------------------------------------------------------------------------ | ||||||
| static bool SaveStorageValue(unsigned int position, int value); | static bool SaveStorageValue(unsigned int position, int value); | ||||||
| static int LoadStorageValue(unsigned int position); | static int LoadStorageValue(unsigned int position); | ||||||
|  |  | ||||||
| @@ -101,6 +103,9 @@ int main(void) | |||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------------ | ||||||
|  | // Module Functions Declaration | ||||||
|  | //------------------------------------------------------------------------------------ | ||||||
| // Save integer value to storage file (to defined position) | // Save integer value to storage file (to defined position) | ||||||
| // NOTE: Storage positions is directly related to file memory layout (4 bytes each integer) | // NOTE: Storage positions is directly related to file memory layout (4 bytes each integer) | ||||||
| bool SaveStorageValue(unsigned int position, int value) | bool SaveStorageValue(unsigned int position, int value) | ||||||
|   | |||||||
| @@ -17,6 +17,9 @@ | |||||||
|  |  | ||||||
| #define NUM_MODELS  9               // Parametric 3d shapes to generate | #define NUM_MODELS  9               // Parametric 3d shapes to generate | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------------ | ||||||
|  | // Module Functions Declaration | ||||||
|  | //------------------------------------------------------------------------------------ | ||||||
| static Mesh GenMeshCustom(void);    // Generate a simple triangle mesh from code | static Mesh GenMeshCustom(void);    // Generate a simple triangle mesh from code | ||||||
|  |  | ||||||
| //------------------------------------------------------------------------------------ | //------------------------------------------------------------------------------------ | ||||||
| @@ -136,6 +139,9 @@ int main(void) | |||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------------ | ||||||
|  | // Module Functions Definition | ||||||
|  | //------------------------------------------------------------------------------------ | ||||||
| // Generate a simple triangle mesh from code | // Generate a simple triangle mesh from code | ||||||
| static Mesh GenMeshCustom(void) | static Mesh GenMeshCustom(void) | ||||||
| { | { | ||||||
|   | |||||||
| @@ -18,11 +18,14 @@ | |||||||
| #include "raylib.h" | #include "raylib.h" | ||||||
|  |  | ||||||
| #include <stdlib.h>             // Required for: rand() | #include <stdlib.h>             // Required for: rand() | ||||||
| #include <math.h>               // Required for: cos(), sin() | #include <math.h>               // Required for: cosf(), sinf() | ||||||
|  |  | ||||||
| #define MAX_POINTS 10000000     // 10 million | #define MAX_POINTS 10000000     // 10 million | ||||||
| #define MIN_POINTS 1000         // 1 thousand | #define MIN_POINTS 1000         // 1 thousand | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------------ | ||||||
|  | // Module Functions Declaration | ||||||
|  | //------------------------------------------------------------------------------------ | ||||||
| // Generate mesh using points | // Generate mesh using points | ||||||
| static Mesh GenMeshPoints(int numPoints); | static Mesh GenMeshPoints(int numPoints); | ||||||
|  |  | ||||||
| @@ -148,6 +151,9 @@ int main() | |||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------------ | ||||||
|  | // Module Functions Definition | ||||||
|  | //------------------------------------------------------------------------------------ | ||||||
| // Generate a spherical point cloud | // Generate a spherical point cloud | ||||||
| static Mesh GenMeshPoints(int numPoints) | static Mesh GenMeshPoints(int numPoints) | ||||||
| { | { | ||||||
| @@ -158,7 +164,7 @@ static Mesh GenMeshPoints(int numPoints) | |||||||
|         .colors = (unsigned char*)MemAlloc(numPoints*4*sizeof(unsigned char)), |         .colors = (unsigned char*)MemAlloc(numPoints*4*sizeof(unsigned char)), | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     // https://en.wikipedia.org/wiki/Spherical_coordinate_system |     // REF: https://en.wikipedia.org/wiki/Spherical_coordinate_system | ||||||
|     for (int i = 0; i < numPoints; i++) |     for (int i = 0; i < numPoints; i++) | ||||||
|     { |     { | ||||||
|         float theta = ((float)PI*rand())/((float)RAND_MAX); |         float theta = ((float)PI*rand())/((float)RAND_MAX); | ||||||
|   | |||||||
| @@ -24,6 +24,9 @@ | |||||||
|     #define GLSL_VERSION            100 |     #define GLSL_VERSION            100 | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------------ | ||||||
|  | // Module Functions Declaration | ||||||
|  | //------------------------------------------------------------------------------------ | ||||||
| // Generate cubemap (6 faces) from equirectangular (panorama) texture | // Generate cubemap (6 faces) from equirectangular (panorama) texture | ||||||
| static TextureCubemap GenTextureCubemap(Shader shader, Texture2D panorama, int size, int format); | static TextureCubemap GenTextureCubemap(Shader shader, Texture2D panorama, int size, int format); | ||||||
|  |  | ||||||
| @@ -183,6 +186,9 @@ int main(void) | |||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------------ | ||||||
|  | // Module Functions Definition | ||||||
|  | //------------------------------------------------------------------------------------ | ||||||
| // Generate cubemap texture from HDR texture | // Generate cubemap texture from HDR texture | ||||||
| static TextureCubemap GenTextureCubemap(Shader shader, Texture2D panorama, int size, int format) | static TextureCubemap GenTextureCubemap(Shader shader, Texture2D panorama, int size, int format) | ||||||
| { | { | ||||||
|   | |||||||
| @@ -54,6 +54,9 @@ | |||||||
|  |  | ||||||
| #define MAX_PARTICLES       1000 | #define MAX_PARTICLES       1000 | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------------ | ||||||
|  | // Module Functions Declaration | ||||||
|  | //------------------------------------------------------------------------------------ | ||||||
| // Particle type | // Particle type | ||||||
| typedef struct Particle { | typedef struct Particle { | ||||||
|     float x; |     float x; | ||||||
|   | |||||||
| @@ -30,6 +30,9 @@ | |||||||
| // Maximum amount of queued draw commands (squares draw from mouse down events) | // Maximum amount of queued draw commands (squares draw from mouse down events) | ||||||
| #define MAX_BUFFERED_TRANSFERTS 48 | #define MAX_BUFFERED_TRANSFERTS 48 | ||||||
|  |  | ||||||
|  | //---------------------------------------------------------------------------------- | ||||||
|  | // Types and Structures Definition | ||||||
|  | //---------------------------------------------------------------------------------- | ||||||
| // Game Of Life Update Command | // Game Of Life Update Command | ||||||
| typedef struct GolUpdateCmd { | typedef struct GolUpdateCmd { | ||||||
|     unsigned int x;         // x coordinate of the gol command |     unsigned int x;         // x coordinate of the gol command | ||||||
|   | |||||||
| @@ -35,6 +35,9 @@ | |||||||
|  |  | ||||||
| #define MAX_CUBES   30 | #define MAX_CUBES   30 | ||||||
|  |  | ||||||
|  | //---------------------------------------------------------------------------------- | ||||||
|  | // Types and Structures Definition | ||||||
|  | //---------------------------------------------------------------------------------- | ||||||
| // GBuffer data | // GBuffer data | ||||||
| typedef struct GBuffer { | typedef struct GBuffer { | ||||||
|     unsigned int framebuffer; |     unsigned int framebuffer; | ||||||
|   | |||||||
| @@ -34,6 +34,9 @@ | |||||||
| #define COLORS_PER_PALETTE      8 | #define COLORS_PER_PALETTE      8 | ||||||
| #define VALUES_PER_COLOR        3 | #define VALUES_PER_COLOR        3 | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------------ | ||||||
|  | // Global Variables Definition | ||||||
|  | //------------------------------------------------------------------------------------ | ||||||
| static const int palettes[MAX_PALETTES][COLORS_PER_PALETTE*VALUES_PER_COLOR] = { | static const int palettes[MAX_PALETTES][COLORS_PER_PALETTE*VALUES_PER_COLOR] = { | ||||||
|     {   // 3-BIT RGB |     {   // 3-BIT RGB | ||||||
|         0, 0, 0, |         0, 0, 0, | ||||||
|   | |||||||
| @@ -46,6 +46,9 @@ typedef enum { | |||||||
|     //FX_FXAA |     //FX_FXAA | ||||||
| } PostproShader; | } PostproShader; | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------------ | ||||||
|  | // Global Variables Definition | ||||||
|  | //------------------------------------------------------------------------------------ | ||||||
| static const char *postproShaderText[] = { | static const char *postproShaderText[] = { | ||||||
|     "GRAYSCALE", |     "GRAYSCALE", | ||||||
|     "POSTERIZATION", |     "POSTERIZATION", | ||||||
|   | |||||||
| @@ -22,6 +22,9 @@ | |||||||
|  |  | ||||||
| #define MAX_SPLINE_POINTS      32 | #define MAX_SPLINE_POINTS      32 | ||||||
|  |  | ||||||
|  | //---------------------------------------------------------------------------------- | ||||||
|  | // Types and Structures Definition | ||||||
|  | //---------------------------------------------------------------------------------- | ||||||
| // Cubic Bezier spline control points | // Cubic Bezier spline control points | ||||||
| // NOTE: Every segment has two control points | // NOTE: Every segment has two control points | ||||||
| typedef struct { | typedef struct { | ||||||
|   | |||||||
| @@ -25,9 +25,12 @@ | |||||||
| #define RLGL_MAX        0x8008 | #define RLGL_MAX        0x8008 | ||||||
|  |  | ||||||
| #define MAX_BOXES       20 | #define MAX_BOXES       20 | ||||||
| #define MAX_SHADOWS   MAX_BOXES*3         // MAX_BOXES *3. Each box can cast up to two shadow volumes for the edges it is away from, and one for the box itself | #define MAX_SHADOWS     MAX_BOXES*3     // MAX_BOXES*3 - Each box can cast up to two shadow volumes for the edges it is away from, and one for the box itself | ||||||
| #define MAX_LIGHTS      16 | #define MAX_LIGHTS      16 | ||||||
|  |  | ||||||
|  | //---------------------------------------------------------------------------------- | ||||||
|  | // Types and Structures Definition | ||||||
|  | //---------------------------------------------------------------------------------- | ||||||
| // Shadow geometry type | // Shadow geometry type | ||||||
| typedef struct ShadowGeometry { | typedef struct ShadowGeometry { | ||||||
|     Vector2 vertices[4]; |     Vector2 vertices[4]; | ||||||
| @@ -48,167 +51,26 @@ typedef struct LightInfo { | |||||||
|     int shadowCount; |     int shadowCount; | ||||||
| } LightInfo; | } LightInfo; | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------------ | ||||||
|  | // Global Variables Definition | ||||||
|  | //------------------------------------------------------------------------------------ | ||||||
|  | static LightInfo lights[MAX_LIGHTS] = { 0 }; | ||||||
|  |  | ||||||
| LightInfo lights[MAX_LIGHTS] = { 0 }; | //------------------------------------------------------------------------------------ | ||||||
|  | // Module Functions Declaration | ||||||
|  | //------------------------------------------------------------------------------------ | ||||||
| // Move a light and mark it as dirty so that we update it's mask next frame | // Move a light and mark it as dirty so that we update it's mask next frame | ||||||
| void MoveLight(int slot, float x, float y) | static void MoveLight(int slot, float x, float y); | ||||||
| { |  | ||||||
|     lights[slot].dirty = true; |  | ||||||
|     lights[slot].position.x = x; |  | ||||||
|     lights[slot].position.y = y; |  | ||||||
|  |  | ||||||
|     // update the cached bounds |  | ||||||
|     lights[slot].bounds.x = x - lights[slot].outerRadius; |  | ||||||
|     lights[slot].bounds.y = y - lights[slot].outerRadius; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Compute a shadow volume for the edge | // Compute a shadow volume for the edge | ||||||
| // It takes the edge and projects it back by the light radius and turns it into a quad | static void ComputeShadowVolumeForEdge(int slot, Vector2 sp, Vector2 ep); | ||||||
| void ComputeShadowVolumeForEdge(int slot, Vector2 sp, Vector2 ep) |  | ||||||
| { |  | ||||||
|     if (lights[slot].shadowCount >= MAX_SHADOWS) return; |  | ||||||
|  |  | ||||||
|     float extension = lights[slot].outerRadius*2; |  | ||||||
|  |  | ||||||
|     Vector2 spVector = Vector2Normalize(Vector2Subtract(sp, lights[slot].position)); |  | ||||||
|     Vector2 spProjection = Vector2Add(sp, Vector2Scale(spVector, extension)); |  | ||||||
|  |  | ||||||
|     Vector2 epVector = Vector2Normalize(Vector2Subtract(ep, lights[slot].position)); |  | ||||||
|     Vector2 epProjection = Vector2Add(ep, Vector2Scale(epVector, extension)); |  | ||||||
|  |  | ||||||
|     lights[slot].shadows[lights[slot].shadowCount].vertices[0] = sp; |  | ||||||
|     lights[slot].shadows[lights[slot].shadowCount].vertices[1] = ep; |  | ||||||
|     lights[slot].shadows[lights[slot].shadowCount].vertices[2] = epProjection; |  | ||||||
|     lights[slot].shadows[lights[slot].shadowCount].vertices[3] = spProjection; |  | ||||||
|  |  | ||||||
|     lights[slot].shadowCount++; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Draw the light and shadows to the mask for a light | // Draw the light and shadows to the mask for a light | ||||||
| void DrawLightMask(int slot) | static void DrawLightMask(int slot); | ||||||
| { |  | ||||||
|     // Use the light mask |  | ||||||
|     BeginTextureMode(lights[slot].mask); |  | ||||||
|  |  | ||||||
|         ClearBackground(WHITE); |  | ||||||
|  |  | ||||||
|         // Force the blend mode to only set the alpha of the destination |  | ||||||
|         rlSetBlendFactors(RLGL_SRC_ALPHA, RLGL_SRC_ALPHA, RLGL_MIN); |  | ||||||
|         rlSetBlendMode(BLEND_CUSTOM); |  | ||||||
|  |  | ||||||
|         // If we are valid, then draw the light radius to the alpha mask |  | ||||||
|         if (lights[slot].valid) DrawCircleGradient((int)lights[slot].position.x, (int)lights[slot].position.y, lights[slot].outerRadius, ColorAlpha(WHITE, 0), WHITE); |  | ||||||
|  |  | ||||||
|         rlDrawRenderBatchActive(); |  | ||||||
|  |  | ||||||
|         // Cut out the shadows from the light radius by forcing the alpha to maximum |  | ||||||
|         rlSetBlendMode(BLEND_ALPHA); |  | ||||||
|         rlSetBlendFactors(RLGL_SRC_ALPHA, RLGL_SRC_ALPHA, RLGL_MAX); |  | ||||||
|         rlSetBlendMode(BLEND_CUSTOM); |  | ||||||
|  |  | ||||||
|         // Draw the shadows to the alpha mask |  | ||||||
|         for (int i = 0; i < lights[slot].shadowCount; i++) |  | ||||||
|         { |  | ||||||
|             DrawTriangleFan(lights[slot].shadows[i].vertices, 4, WHITE); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         rlDrawRenderBatchActive(); |  | ||||||
|  |  | ||||||
|         // Go back to normal blend mode |  | ||||||
|         rlSetBlendMode(BLEND_ALPHA); |  | ||||||
|  |  | ||||||
|     EndTextureMode(); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Setup a light | // Setup a light | ||||||
| void SetupLight(int slot, float x, float y, float radius) | static void SetupLight(int slot, float x, float y, float radius); | ||||||
| { |  | ||||||
|     lights[slot].active = true; |  | ||||||
|     lights[slot].valid = false;  // The light must prove it is valid |  | ||||||
|     lights[slot].mask = LoadRenderTexture(GetScreenWidth(), GetScreenHeight()); |  | ||||||
|     lights[slot].outerRadius = radius; |  | ||||||
|  |  | ||||||
|     lights[slot].bounds.width = radius*2; |  | ||||||
|     lights[slot].bounds.height = radius*2; |  | ||||||
|  |  | ||||||
|     MoveLight(slot, x, y); |  | ||||||
|  |  | ||||||
|     // Force the render texture to have something in it |  | ||||||
|     DrawLightMask(slot); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // See if a light needs to update it's mask | // See if a light needs to update it's mask | ||||||
| bool UpdateLight(int slot, Rectangle* boxes, int count) | static bool UpdateLight(int slot, Rectangle* boxes, int count); | ||||||
| { |  | ||||||
|     if (!lights[slot].active || !lights[slot].dirty) return false; |  | ||||||
|  |  | ||||||
|     lights[slot].dirty = false; |  | ||||||
|     lights[slot].shadowCount = 0; |  | ||||||
|     lights[slot].valid = false; |  | ||||||
|  |  | ||||||
|     for (int i = 0; i < count; i++) |  | ||||||
|     { |  | ||||||
|         // Are we in a box? if so we are not valid |  | ||||||
|         if (CheckCollisionPointRec(lights[slot].position, boxes[i])) return false; |  | ||||||
|  |  | ||||||
|         // If this box is outside our bounds, we can skip it |  | ||||||
|         if (!CheckCollisionRecs(lights[slot].bounds, boxes[i])) continue; |  | ||||||
|  |  | ||||||
|         // Check the edges that are on the same side we are, and cast shadow volumes out from them |  | ||||||
|  |  | ||||||
|         // Top |  | ||||||
|         Vector2 sp = (Vector2){ boxes[i].x, boxes[i].y }; |  | ||||||
|         Vector2 ep = (Vector2){ boxes[i].x + boxes[i].width, boxes[i].y }; |  | ||||||
|  |  | ||||||
|         if (lights[slot].position.y > ep.y) ComputeShadowVolumeForEdge(slot, sp, ep); |  | ||||||
|  |  | ||||||
|         // Right |  | ||||||
|         sp = ep; |  | ||||||
|         ep.y += boxes[i].height; |  | ||||||
|         if (lights[slot].position.x < ep.x) ComputeShadowVolumeForEdge(slot, sp, ep); |  | ||||||
|  |  | ||||||
|         // Bottom |  | ||||||
|         sp = ep; |  | ||||||
|         ep.x -= boxes[i].width; |  | ||||||
|         if (lights[slot].position.y < ep.y) ComputeShadowVolumeForEdge(slot, sp, ep); |  | ||||||
|  |  | ||||||
|         // Left |  | ||||||
|         sp = ep; |  | ||||||
|         ep.y -= boxes[i].height; |  | ||||||
|         if (lights[slot].position.x > ep.x) ComputeShadowVolumeForEdge(slot, sp, ep); |  | ||||||
|  |  | ||||||
|         // The box itself |  | ||||||
|         lights[slot].shadows[lights[slot].shadowCount].vertices[0] = (Vector2){ boxes[i].x, boxes[i].y }; |  | ||||||
|         lights[slot].shadows[lights[slot].shadowCount].vertices[1] = (Vector2){ boxes[i].x, boxes[i].y + boxes[i].height }; |  | ||||||
|         lights[slot].shadows[lights[slot].shadowCount].vertices[2] = (Vector2){ boxes[i].x + boxes[i].width, boxes[i].y + boxes[i].height }; |  | ||||||
|         lights[slot].shadows[lights[slot].shadowCount].vertices[3] = (Vector2){ boxes[i].x + boxes[i].width, boxes[i].y }; |  | ||||||
|         lights[slot].shadowCount++; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     lights[slot].valid = true; |  | ||||||
|  |  | ||||||
|     DrawLightMask(slot); |  | ||||||
|  |  | ||||||
|     return true; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Set up some boxes | // Set up some boxes | ||||||
| void SetupBoxes(Rectangle *boxes, int *count) | static void SetupBoxes(Rectangle *boxes, int *count); | ||||||
| { |  | ||||||
|     boxes[0] = (Rectangle){ 150,80, 40, 40 }; |  | ||||||
|     boxes[1] = (Rectangle){ 1200, 700, 40, 40 }; |  | ||||||
|     boxes[2] = (Rectangle){ 200, 600, 40, 40 }; |  | ||||||
|     boxes[3] = (Rectangle){ 1000, 50, 40, 40 }; |  | ||||||
|     boxes[4] = (Rectangle){ 500, 350, 40, 40 }; |  | ||||||
|  |  | ||||||
|     for (int i = 5; i < MAX_BOXES; i++) |  | ||||||
|     { |  | ||||||
|         boxes[i] = (Rectangle){(float)GetRandomValue(0,GetScreenWidth()), (float)GetRandomValue(0,GetScreenHeight()), (float)GetRandomValue(10,100), (float)GetRandomValue(10,100) }; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     *count = MAX_BOXES; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| //------------------------------------------------------------------------------------ | //------------------------------------------------------------------------------------ | ||||||
| // Program main entry point | // Program main entry point | ||||||
| @@ -356,3 +218,165 @@ int main(void) | |||||||
|  |  | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------------ | ||||||
|  | // Module Functions Definition | ||||||
|  | //------------------------------------------------------------------------------------ | ||||||
|  | // Move a light and mark it as dirty so that we update it's mask next frame | ||||||
|  | static void MoveLight(int slot, float x, float y) | ||||||
|  | { | ||||||
|  |     lights[slot].dirty = true; | ||||||
|  |     lights[slot].position.x = x; | ||||||
|  |     lights[slot].position.y = y; | ||||||
|  |  | ||||||
|  |     // update the cached bounds | ||||||
|  |     lights[slot].bounds.x = x - lights[slot].outerRadius; | ||||||
|  |     lights[slot].bounds.y = y - lights[slot].outerRadius; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Compute a shadow volume for the edge | ||||||
|  | // It takes the edge and projects it back by the light radius and turns it into a quad | ||||||
|  | static void ComputeShadowVolumeForEdge(int slot, Vector2 sp, Vector2 ep) | ||||||
|  | { | ||||||
|  |     if (lights[slot].shadowCount >= MAX_SHADOWS) return; | ||||||
|  |  | ||||||
|  |     float extension = lights[slot].outerRadius*2; | ||||||
|  |  | ||||||
|  |     Vector2 spVector = Vector2Normalize(Vector2Subtract(sp, lights[slot].position)); | ||||||
|  |     Vector2 spProjection = Vector2Add(sp, Vector2Scale(spVector, extension)); | ||||||
|  |  | ||||||
|  |     Vector2 epVector = Vector2Normalize(Vector2Subtract(ep, lights[slot].position)); | ||||||
|  |     Vector2 epProjection = Vector2Add(ep, Vector2Scale(epVector, extension)); | ||||||
|  |  | ||||||
|  |     lights[slot].shadows[lights[slot].shadowCount].vertices[0] = sp; | ||||||
|  |     lights[slot].shadows[lights[slot].shadowCount].vertices[1] = ep; | ||||||
|  |     lights[slot].shadows[lights[slot].shadowCount].vertices[2] = epProjection; | ||||||
|  |     lights[slot].shadows[lights[slot].shadowCount].vertices[3] = spProjection; | ||||||
|  |  | ||||||
|  |     lights[slot].shadowCount++; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Setup a light | ||||||
|  | static void SetupLight(int slot, float x, float y, float radius) | ||||||
|  | { | ||||||
|  |     lights[slot].active = true; | ||||||
|  |     lights[slot].valid = false;  // The light must prove it is valid | ||||||
|  |     lights[slot].mask = LoadRenderTexture(GetScreenWidth(), GetScreenHeight()); | ||||||
|  |     lights[slot].outerRadius = radius; | ||||||
|  |  | ||||||
|  |     lights[slot].bounds.width = radius*2; | ||||||
|  |     lights[slot].bounds.height = radius*2; | ||||||
|  |  | ||||||
|  |     MoveLight(slot, x, y); | ||||||
|  |  | ||||||
|  |     // Force the render texture to have something in it | ||||||
|  |     DrawLightMask(slot); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // See if a light needs to update it's mask | ||||||
|  | static bool UpdateLight(int slot, Rectangle* boxes, int count) | ||||||
|  | { | ||||||
|  |     if (!lights[slot].active || !lights[slot].dirty) return false; | ||||||
|  |  | ||||||
|  |     lights[slot].dirty = false; | ||||||
|  |     lights[slot].shadowCount = 0; | ||||||
|  |     lights[slot].valid = false; | ||||||
|  |  | ||||||
|  |     for (int i = 0; i < count; i++) | ||||||
|  |     { | ||||||
|  |         // Are we in a box? if so we are not valid | ||||||
|  |         if (CheckCollisionPointRec(lights[slot].position, boxes[i])) return false; | ||||||
|  |  | ||||||
|  |         // If this box is outside our bounds, we can skip it | ||||||
|  |         if (!CheckCollisionRecs(lights[slot].bounds, boxes[i])) continue; | ||||||
|  |  | ||||||
|  |         // Check the edges that are on the same side we are, and cast shadow volumes out from them | ||||||
|  |  | ||||||
|  |         // Top | ||||||
|  |         Vector2 sp = (Vector2){ boxes[i].x, boxes[i].y }; | ||||||
|  |         Vector2 ep = (Vector2){ boxes[i].x + boxes[i].width, boxes[i].y }; | ||||||
|  |  | ||||||
|  |         if (lights[slot].position.y > ep.y) ComputeShadowVolumeForEdge(slot, sp, ep); | ||||||
|  |  | ||||||
|  |         // Right | ||||||
|  |         sp = ep; | ||||||
|  |         ep.y += boxes[i].height; | ||||||
|  |         if (lights[slot].position.x < ep.x) ComputeShadowVolumeForEdge(slot, sp, ep); | ||||||
|  |  | ||||||
|  |         // Bottom | ||||||
|  |         sp = ep; | ||||||
|  |         ep.x -= boxes[i].width; | ||||||
|  |         if (lights[slot].position.y < ep.y) ComputeShadowVolumeForEdge(slot, sp, ep); | ||||||
|  |  | ||||||
|  |         // Left | ||||||
|  |         sp = ep; | ||||||
|  |         ep.y -= boxes[i].height; | ||||||
|  |         if (lights[slot].position.x > ep.x) ComputeShadowVolumeForEdge(slot, sp, ep); | ||||||
|  |  | ||||||
|  |         // The box itself | ||||||
|  |         lights[slot].shadows[lights[slot].shadowCount].vertices[0] = (Vector2){ boxes[i].x, boxes[i].y }; | ||||||
|  |         lights[slot].shadows[lights[slot].shadowCount].vertices[1] = (Vector2){ boxes[i].x, boxes[i].y + boxes[i].height }; | ||||||
|  |         lights[slot].shadows[lights[slot].shadowCount].vertices[2] = (Vector2){ boxes[i].x + boxes[i].width, boxes[i].y + boxes[i].height }; | ||||||
|  |         lights[slot].shadows[lights[slot].shadowCount].vertices[3] = (Vector2){ boxes[i].x + boxes[i].width, boxes[i].y }; | ||||||
|  |         lights[slot].shadowCount++; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     lights[slot].valid = true; | ||||||
|  |  | ||||||
|  |     DrawLightMask(slot); | ||||||
|  |  | ||||||
|  |     return true; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Draw the light and shadows to the mask for a light | ||||||
|  | static void DrawLightMask(int slot) | ||||||
|  | { | ||||||
|  |     // Use the light mask | ||||||
|  |     BeginTextureMode(lights[slot].mask); | ||||||
|  |  | ||||||
|  |         ClearBackground(WHITE); | ||||||
|  |  | ||||||
|  |         // Force the blend mode to only set the alpha of the destination | ||||||
|  |         rlSetBlendFactors(RLGL_SRC_ALPHA, RLGL_SRC_ALPHA, RLGL_MIN); | ||||||
|  |         rlSetBlendMode(BLEND_CUSTOM); | ||||||
|  |  | ||||||
|  |         // If we are valid, then draw the light radius to the alpha mask | ||||||
|  |         if (lights[slot].valid) DrawCircleGradient((int)lights[slot].position.x, (int)lights[slot].position.y, lights[slot].outerRadius, ColorAlpha(WHITE, 0), WHITE); | ||||||
|  |  | ||||||
|  |         rlDrawRenderBatchActive(); | ||||||
|  |  | ||||||
|  |         // Cut out the shadows from the light radius by forcing the alpha to maximum | ||||||
|  |         rlSetBlendMode(BLEND_ALPHA); | ||||||
|  |         rlSetBlendFactors(RLGL_SRC_ALPHA, RLGL_SRC_ALPHA, RLGL_MAX); | ||||||
|  |         rlSetBlendMode(BLEND_CUSTOM); | ||||||
|  |  | ||||||
|  |         // Draw the shadows to the alpha mask | ||||||
|  |         for (int i = 0; i < lights[slot].shadowCount; i++) | ||||||
|  |         { | ||||||
|  |             DrawTriangleFan(lights[slot].shadows[i].vertices, 4, WHITE); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         rlDrawRenderBatchActive(); | ||||||
|  |  | ||||||
|  |         // Go back to normal blend mode | ||||||
|  |         rlSetBlendMode(BLEND_ALPHA); | ||||||
|  |  | ||||||
|  |     EndTextureMode(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Set up some boxes | ||||||
|  | static void SetupBoxes(Rectangle *boxes, int *count) | ||||||
|  | { | ||||||
|  |     boxes[0] = (Rectangle){ 150,80, 40, 40 }; | ||||||
|  |     boxes[1] = (Rectangle){ 1200, 700, 40, 40 }; | ||||||
|  |     boxes[2] = (Rectangle){ 200, 600, 40, 40 }; | ||||||
|  |     boxes[3] = (Rectangle){ 1000, 50, 40, 40 }; | ||||||
|  |     boxes[4] = (Rectangle){ 500, 350, 40, 40 }; | ||||||
|  |  | ||||||
|  |     for (int i = 5; i < MAX_BOXES; i++) | ||||||
|  |     { | ||||||
|  |         boxes[i] = (Rectangle){(float)GetRandomValue(0,GetScreenWidth()), (float)GetRandomValue(0,GetScreenHeight()), (float)GetRandomValue(10,100), (float)GetRandomValue(10,100) }; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     *count = MAX_BOXES; | ||||||
|  | } | ||||||
|   | |||||||
| @@ -23,6 +23,9 @@ | |||||||
| // this text will be scanned to get all the required codepoints | // this text will be scanned to get all the required codepoints | ||||||
| static char *text = "いろはにほへと ちりぬるを\nわかよたれそ つねならむ\nうゐのおくやま けふこえて\nあさきゆめみし ゑひもせす"; | static char *text = "いろはにほへと ちりぬるを\nわかよたれそ つねならむ\nうゐのおくやま けふこえて\nあさきゆめみし ゑひもせす"; | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------------ | ||||||
|  | // Module Functions Declaration | ||||||
|  | //------------------------------------------------------------------------------------ | ||||||
| // Remove codepoint duplicates if requested | // Remove codepoint duplicates if requested | ||||||
| static int *CodepointRemoveDuplicates(int *codepoints, int codepointCount, int *codepointResultCount); | static int *CodepointRemoveDuplicates(int *codepoints, int codepointCount, int *codepointResultCount); | ||||||
|  |  | ||||||
| @@ -128,6 +131,9 @@ int main(void) | |||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------------ | ||||||
|  | // Module Functions Definition | ||||||
|  | //------------------------------------------------------------------------------------ | ||||||
| // Remove codepoint duplicates if requested | // Remove codepoint duplicates if requested | ||||||
| // WARNING: This process could be a bit slow if there text to process is very long | // WARNING: This process could be a bit slow if there text to process is very long | ||||||
| static int *CodepointRemoveDuplicates(int *codepoints, int codepointCount, int *codepointsResultCount) | static int *CodepointRemoveDuplicates(int *codepoints, int codepointCount, int *codepointsResultCount) | ||||||
|   | |||||||
| @@ -25,7 +25,7 @@ | |||||||
| #define EMOJI_PER_HEIGHT 4 | #define EMOJI_PER_HEIGHT 4 | ||||||
|  |  | ||||||
| //-------------------------------------------------------------------------------------- | //-------------------------------------------------------------------------------------- | ||||||
| // Global variables | // Global Variables Definition | ||||||
| //-------------------------------------------------------------------------------------- | //-------------------------------------------------------------------------------------- | ||||||
| // Arrays that holds the random emojis | // Arrays that holds the random emojis | ||||||
| struct { | struct { | ||||||
| @@ -34,7 +34,8 @@ struct { | |||||||
|     Color color;    // Emoji color |     Color color;    // Emoji color | ||||||
| } emoji[EMOJI_PER_WIDTH*EMOJI_PER_HEIGHT] = { 0 }; | } emoji[EMOJI_PER_WIDTH*EMOJI_PER_HEIGHT] = { 0 }; | ||||||
|  |  | ||||||
| static int hovered = -1, selected = -1; | static int hovered = -1; | ||||||
|  | static int selected = -1; | ||||||
|  |  | ||||||
| // String containing 180 emoji codepoints separated by a '\0' char | // String containing 180 emoji codepoints separated by a '\0' char | ||||||
| const char *const emojiCodepoints = "\xF0\x9F\x8C\x80\x00\xF0\x9F\x98\x80\x00\xF0\x9F\x98\x82\x00\xF0\x9F\xA4\xA3\x00\xF0\x9F\x98\x83\x00\xF0\x9F\x98\x86\x00\xF0\x9F\x98\x89\x00" | const char *const emojiCodepoints = "\xF0\x9F\x8C\x80\x00\xF0\x9F\x98\x80\x00\xF0\x9F\x98\x82\x00\xF0\x9F\xA4\xA3\x00\xF0\x9F\x98\x83\x00\xF0\x9F\x98\x86\x00\xF0\x9F\x98\x89\x00" | ||||||
|   | |||||||
| @@ -149,7 +149,7 @@ int main(void) | |||||||
|                 (Rectangle){ 400, 16, font.texture.width*atlasScale, font.texture.height*atlasScale }, (Vector2){ 0, 0 }, 0.0f, WHITE); |                 (Rectangle){ 400, 16, font.texture.width*atlasScale, font.texture.height*atlasScale }, (Vector2){ 0, 0 }, 0.0f, WHITE); | ||||||
|             DrawRectangleLines(400, 16, 380, 380, RED); |             DrawRectangleLines(400, 16, 380, 380, RED); | ||||||
|  |  | ||||||
|             DrawText(TextFormat("ATLAS SIZE: %ix%i px (x%02.1f)", font.texture.width, font.texture.height, atlasScale), 20, 380, 20, BLUE); |             DrawText(TextFormat("ATLAS SIZE: %ix%i px (x%02.2f)", font.texture.width, font.texture.height, atlasScale), 20, 380, 20, BLUE); | ||||||
|  |  | ||||||
|             // Display font attribution |             // Display font attribution | ||||||
|             DrawText("Font: Noto Sans TC. License: SIL Open Font License 1.1", screenWidth - 300, screenHeight - 20, 10, GRAY); |             DrawText("Font: Noto Sans TC. License: SIL Open Font License 1.1", screenWidth - 300, screenHeight - 20, 10, GRAY); | ||||||
|   | |||||||
| @@ -23,6 +23,9 @@ | |||||||
| // NOTE: This value is defined in [rlgl] module and can be changed there | // NOTE: This value is defined in [rlgl] module and can be changed there | ||||||
| #define MAX_BATCH_ELEMENTS  8192 | #define MAX_BATCH_ELEMENTS  8192 | ||||||
|  |  | ||||||
|  | //---------------------------------------------------------------------------------- | ||||||
|  | // Types and Structures Definition | ||||||
|  | //---------------------------------------------------------------------------------- | ||||||
| typedef struct Bunny { | typedef struct Bunny { | ||||||
|     Vector2 position; |     Vector2 position; | ||||||
|     Vector2 speed; |     Vector2 speed; | ||||||
|   | |||||||
| @@ -21,6 +21,9 @@ | |||||||
| #define PLAYER_SIZE      16         // Player size | #define PLAYER_SIZE      16         // Player size | ||||||
| #define PLAYER_TILE_VISIBILITY  2   // Player can see 2 tiles around its position | #define PLAYER_TILE_VISIBILITY  2   // Player can see 2 tiles around its position | ||||||
|  |  | ||||||
|  | //---------------------------------------------------------------------------------- | ||||||
|  | // Types and Structures Definition | ||||||
|  | //---------------------------------------------------------------------------------- | ||||||
| // Map data type | // Map data type | ||||||
| typedef struct Map { | typedef struct Map { | ||||||
|     unsigned int tilesX;            // Number of tiles in X axis |     unsigned int tilesX;            // Number of tiles in X axis | ||||||
|   | |||||||
| @@ -17,7 +17,10 @@ | |||||||
|  |  | ||||||
| #define MAX_PARTICLES 200 | #define MAX_PARTICLES 200 | ||||||
|  |  | ||||||
| // Particle structure with basic data | //---------------------------------------------------------------------------------- | ||||||
|  | // Types and Structures Definition | ||||||
|  | //---------------------------------------------------------------------------------- | ||||||
|  | // Particle structure | ||||||
| typedef struct { | typedef struct { | ||||||
|     Vector2 position; |     Vector2 position; | ||||||
|     Color color; |     Color color; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Ray
					Ray