Maintainers
Pricing
Enterprise
More
More
Documentation
Try Live
Rankings
Install
Blog
Docs7
Ask
New
Add Docs
raylib
https://www.raylib.com/
Admin
raylib is a simple and easy-to-use library to enjoy videogames programming.
Tokens:
509,826
Snippets:
1,709
Trust Score:
9.4
Update:
2 weeks ago
Context
Chat
Benchmark
77.13
Latest
Show doc for...
Code
Info
Show Results
Tokens:
Raw
Copy
Link
Tokens:
Raw
Copy
Link
### Basic window example in C Source: https://www.raylib.com/examples/core/loader.html?name=core_basic_window Creates a window with raylib, sets the target FPS to 60, and runs a loop that draws text until the window is closed. The example is rated 1/4 complexity and is the starting point for learning raylib. ```c /******************************************************************************************* * * raylib [core] example - basic window * * Example complexity rating: [★☆☆☆] 1/4 * * Welcome to raylib! * * To test examples, just press F6 and execute 'raylib_compile_execute' script * Note that compiled executable is placed in the same folder as .c file * * To test the examples on Web, press F6 and execute 'raylib_compile_execute_web' script * Web version of the program is generated in the same folder as .c file * * You can find all basic examples on C:\raylib\raylib\examples folder or * raylib official webpage: www.raylib.com * * Enjoy using raylib. :) * * Example originally created with raylib 1.0, last time updated with raylib 1.0 * * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * BSD-like license that allows static linking with closed source software * * Copyright (c) 2013-2026 Ramon Santamaria (@raysan5) * ********************************************************************************************/ #include "raylib.h" //------------------------------------------------------------------------------------ // Program main entry point //------------------------------------------------------------------------------------ int main(void) { // Initialization //-------------------------------------------------------------------------------------- const int screenWidth = 800; const int screenHeight = 450; InitWindow(screenWidth, screenHeight, "raylib [core] example - basic window"); SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- // Main game loop while (!WindowShouldClose()) // Detect window close button or ESC key { // Update //---------------------------------------------------------------------------------- // TODO: Update your variables here //---------------------------------------------------------------------------------- // Draw //---------------------------------------------------------------------------------- BeginDrawing(); ClearBackground(RAYWHITE); DrawText("Congrats! You created your first window!", 190, 200, 20, LIGHTGRAY); EndDrawing(); //---------------------------------------------------------------------------------- } // De-Initialization //-------------------------------------------------------------------------------------- CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- return 0; } ``` -------------------------------- ### Decal example initialization and setup Source: https://www.raylib.com/examples/models/loader.html?name=models_decals Sets up the raylib window, camera, model, textures, and decal materials. It loads a character model, applies a diffuse texture, and prepares a placement cube and decal texture. ```c /******************************************************************************************* * * raylib [models] example - decals * * Example complexity rating: [★★★★] 4/4 * * Example originally created with raylib 6.0, last time updated with raylib 6.0 * * Example contributed by JP Mortiboys (@themushroompirates) and reviewed by Ramon Santamaria (@raysan5) * Based on previous work by @mrdoob * * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * BSD-like license that allows static linking with closed source software * * Copyright (c) 2025 JP Mortiboys (@themushroompirates) and Ramon Santamaria (@raysan5) * ********************************************************************************************/ #include "raylib.h" #include "raymath.h" #include <string.h> // Required for: memcpy() #undef FLT_MAX #define FLT_MAX 340282346638528859811704183484516925440.0f // Maximum value of a float, from bit pattern 01111111011111111111111111111111 #define MAX_DECALS 256 //---------------------------------------------------------------------------------- // Types and Structures Definition //---------------------------------------------------------------------------------- typedef struct MeshBuilder { int vertexCount; int vertexCapacity; Vector3 *vertices; Vector2 *uvs; } MeshBuilder; //------------------------------------------------------------------------------------ // Module Functions Declaration //------------------------------------------------------------------------------------ static void AddTriangleToMeshBuilder(MeshBuilder *mb, Vector3 vertices[3]); static void FreeMeshBuilder(MeshBuilder *mb); static Mesh BuildMesh(MeshBuilder *mb); static Mesh GenMeshDecal(Model inputModel, Matrix projection, float decalSize, float decalOffset); static Vector3 ClipSegment(Vector3 v0, Vector3 v1, Vector3 p, float s); static void FreeDecalMeshData(void) { GenMeshDecal((Model){ .meshCount = -1 }, (Matrix){ 0 }, 0.0f, 0.0f); } static bool GuiButton(Rectangle rec, const char *label); //------------------------------------------------------------------------------------ // Program main entry point //------------------------------------------------------------------------------------ int main(void) { // Initialization //-------------------------------------------------------------------------------------- const int screenWidth = 800; const int screenHeight = 450; SetConfigFlags(FLAG_MSAA_4X_HINT); InitWindow(screenWidth, screenHeight, "raylib [models] example - decals"); // Define the camera to look into our 3d world Camera camera = { 0 }; camera.position = (Vector3){ 5.0f, 5.0f, 5.0f }; // Camera position camera.target = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera looking at point camera.up = (Vector3){ 0.0f, 1.6f, 0.0f }; // Camera up vector (rotation towards target) camera.fovy = 45.0f; // Camera field-of-view Y camera.projection = CAMERA_PERSPECTIVE; // Camera projection type // Load character model Model model = LoadModel("resources/models/obj/character.obj"); // Apply character skin Texture2D modelTexture = LoadTexture("resources/models/obj/character_diffuse.png"); SetTextureFilter(modelTexture, TEXTURE_FILTER_BILINEAR); model.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = modelTexture; BoundingBox modelBBox = GetMeshBoundingBox(model.meshes[0]); // Get mesh bounding box camera.target = Vector3Lerp(modelBBox.min, modelBBox.max, 0.5f); camera.position = Vector3Scale(modelBBox.max, 1.0f); camera.position.x *= 0.1f; float modelSize = fminf( fminf(fabsf(modelBBox.max.x - modelBBox.min.x), fabsf(modelBBox.max.y - modelBBox.min.y)), fabsf(modelBBox.max.z - modelBBox.min.z)); camera.position = (Vector3){ 0.0f, modelBBox.max.y*1.2f, modelSize*3.0f }; float decalSize = modelSize*0.25f; float decalOffset = 0.01f; Model placementCube = LoadModelFromMesh(GenMeshCube(decalSize, decalSize, decalSize)); placementCube.materials[0].maps[0].color = LIME; Material decalMaterial = LoadMaterialDefault(); decalMaterial.maps[0].color = YELLOW; Image decalImage = LoadImage("resources/raylib_logo.png"); ImageResizeNN(&decalImage, decalImage.width/4, decalImage.height/4); Texture decalTexture = LoadTextureFromImage(decalImage); UnloadImage(decalImage); SetTextureFilter(decalTexture, TEXTURE_FILTER_BILINEAR); decalMaterial.maps[MATERIAL_MAP_DIFFUSE].texture = decalTexture; decalMaterial.maps[MATERIAL_MAP_DIFFUSE].color = RAYWHITE; bool showModel = true; static Model decalModels[MAX_DECALS] = { 0 }; int decalCount = 0; SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- ``` -------------------------------- ### Hybrid rendering example main setup and loop Source: https://www.raylib.com/examples/shaders/loader.html?name=shaders_hybrid_rendering Initialization and main loop for the hybrid rendering example. Loads the raymarch and raster shaders, sets up the camera and a custom depth texture, and updates the camera position in the shader each frame. ```c /******************************************************************************************* * * raylib [shaders] example - hybrid rendering * * Example complexity rating: [★★★★] 4/4 * * Example originally created with raylib 4.2, last time updated with raylib 4.2 * * Example contributed by Buğra Alptekin Sarı (@BugraAlptekinSari) and reviewed by Ramon Santamaria (@raysan5) * * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * BSD-like license that allows static linking with closed source software * * Copyright (c) 2022-2025 Buğra Alptekin Sarı (@BugraAlptekinSari) * ********************************************************************************************/ #include "raylib.h" #include "rlgl.h" #include "raymath.h" #include <math.h> // Required for: tanf() #if defined(PLATFORM_DESKTOP) #define GLSL_VERSION 330 #else // PLATFORM_ANDROID, PLATFORM_WEB #define GLSL_VERSION 100 #endif //---------------------------------------------------------------------------------- // Types and Structures Definition //---------------------------------------------------------------------------------- typedef struct { unsigned int camPos; unsigned int camDir; unsigned int screenCenter; } RayLocs; //------------------------------------------------------------------------------------ // Module Functions Declaration //------------------------------------------------------------------------------------ // Load custom render texture, create a writable depth texture buffer static RenderTexture2D LoadRenderTextureDepthTex(int width, int height); // Unload render texture from GPU memory (VRAM) static void UnloadRenderTextureDepthTex(RenderTexture2D target); //------------------------------------------------------------------------------------ // Program main entry point //------------------------------------------------------------------------------------ int main(void) { // Initialization //-------------------------------------------------------------------------------------- const int screenWidth = 800; const int screenHeight = 450; InitWindow(screenWidth, screenHeight, "raylib [shaders] example - hybrid rendering"); // This Shader calculates pixel depth and color using raymarch Shader shdrRaymarch = LoadShader(0, TextFormat("resources/shaders/glsl%i/hybrid_raymarch.fs", GLSL_VERSION)); // This Shader is a standard rasterization fragment shader with the addition of depth writing // You are required to write depth for all shaders if one shader does it Shader shdrRaster = LoadShader(0, TextFormat("resources/shaders/glsl%i/hybrid_raster.fs", GLSL_VERSION)); // Declare Struct used to store camera locs RayLocs marchLocs = { 0 }; // Fill the struct with shader locs marchLocs.camPos = GetShaderLocation(shdrRaymarch, "camPos"); marchLocs.camDir = GetShaderLocation(shdrRaymarch, "camDir"); marchLocs.screenCenter = GetShaderLocation(shdrRaymarch, "screenCenter"); // Transfer screenCenter position to shader. Which is used to calculate ray direction Vector2 screenCenter = {.x = screenWidth/2.0f, .y = screenHeight/2.0f}; SetShaderValue(shdrRaymarch, marchLocs.screenCenter , &screenCenter , SHADER_UNIFORM_VEC2); // Use Customized function to create writable depth texture buffer RenderTexture2D target = LoadRenderTextureDepthTex(screenWidth, screenHeight); // Define the camera to look into our 3d world Camera camera = { .position = (Vector3){ 0.5f, 1.0f, 1.5f }, // Camera position .target = (Vector3){ 0.0f, 0.5f, 0.0f }, // Camera looking at point .up = (Vector3){ 0.0f, 1.0f, 0.0f }, // Camera up vector (rotation towards target) .fovy = 45.0f, // Camera field-of-view Y .projection = CAMERA_PERSPECTIVE // Camera projection type }; // Camera FOV is pre-calculated in the camera distance float camDist = 1.0f/(tanf(camera.fovy*0.5f*DEG2RAD)); SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- // Main game loop while (!WindowShouldClose()) // Detect window close button or ESC key { // Update //---------------------------------------------------------------------------------- UpdateCamera(&camera, CAMERA_ORBITAL); // Update Camera Postion in the ray march shader SetShaderValue(shdrRaymarch, marchLocs.camPos, &(camera.position), RL_SHADER_UNIFORM_VEC3); ``` -------------------------------- ### Top-down lights example: setup and main loop Source: https://www.raylib.com/examples/shapes/loader.html?name=shapes_top_down_lights Initialization and main loop for the top-down lights example. Sets up a checkerboard background, a global light mask, and an initial light. Handles dragging light 0 with the left mouse button, creating new lights with the right mouse button (up to MAX_LIGHTS), and toggling debug lines with F1. ```c /******************************************************************************************* * * raylib [shapes] example - top down lights * * Example complexity rating: [★★★★] 4/4 * * Example originally created with raylib 4.2, last time updated with raylib 4.2 * * Example contributed by Jeffery Myers (@JeffM2501) and reviewed by Ramon Santamaria (@raysan5) * * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * BSD-like license that allows static linking with closed source software * * Copyright (c) 2022-2025 Jeffery Myers (@JeffM2501) * ********************************************************************************************/ #include "raylib.h" #include "raymath.h" #include "rlgl.h" // Custom Blend Modes #define RLGL_SRC_ALPHA 0x0302 #define RLGL_MIN 0x8007 #define RLGL_MAX 0x8008 #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_LIGHTS 16 //---------------------------------------------------------------------------------- // Types and Structures Definition //---------------------------------------------------------------------------------- // Shadow geometry type typedef struct ShadowGeometry { Vector2 vertices[4]; } ShadowGeometry; // Light info type typedef struct LightInfo { bool active; // Is this light slot active? bool dirty; // Does this light need to be updated? bool valid; // Is this light in a valid position? Vector2 position; // Light position RenderTexture mask; // Alpha mask for the light float outerRadius; // The distance the light touches Rectangle bounds; // A cached rectangle of the light bounds to help with culling ShadowGeometry shadows[MAX_SHADOWS]; int shadowCount; } LightInfo; //------------------------------------------------------------------------------------ // Global Variables Definition //------------------------------------------------------------------------------------ static 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 static void MoveLight(int slot, float x, float y); // Compute a shadow volume for the edge static void ComputeShadowVolumeForEdge(int slot, Vector2 sp, Vector2 ep); // Draw the light and shadows to the mask for a light static void DrawLightMask(int slot); // Setup a light static void SetupLight(int slot, float x, float y, float radius); // See if a light needs to update it's mask static bool UpdateLight(int slot, Rectangle* boxes, int count); // Set up some boxes static void SetupBoxes(Rectangle *boxes, int *count); //------------------------------------------------------------------------------------ // Program main entry point //------------------------------------------------------------------------------------ int main(void) { // Initialization //-------------------------------------------------------------------------------------- const int screenWidth = 800; const int screenHeight = 450; InitWindow(screenWidth, screenHeight, "raylib [shapes] example - top down lights"); // Initialize our 'world' of boxes int boxCount = 0; Rectangle boxes[MAX_BOXES] = { 0 }; SetupBoxes(boxes, &boxCount); // Create a checkerboard ground texture Image img = GenImageChecked(64, 64, 32, 32, DARKBROWN, DARKGRAY); Texture2D backgroundTexture = LoadTextureFromImage(img); UnloadImage(img); // Create a global light mask to hold all the blended lights RenderTexture lightMask = LoadRenderTexture(GetScreenWidth(), GetScreenHeight()); // Setup initial light SetupLight(0, 600, 400, 300); int nextLight = 1; bool showLines = false; SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- // Main game loop while (!WindowShouldClose()) // Detect window close button or ESC key { // Update //---------------------------------------------------------------------------------- // Drag light 0 if (IsMouseButtonDown(MOUSE_BUTTON_LEFT)) MoveLight(0, GetMousePosition().x, GetMousePosition().y); // Make a new light if (IsMouseButtonPressed(MOUSE_BUTTON_RIGHT) && (nextLight < MAX_LIGHTS)) { SetupLight(nextLight, GetMousePosition().x, GetMousePosition().y, 200); nextLight++; } // Toggle debug info if (IsKeyPressed(KEY_F1)) showLines = !showLines; ``` -------------------------------- ### Lightmap rendering setup Source: https://www.raylib.com/examples/shaders/loader.html?name=shaders_lightmap_rendering This code sets up the lightmap rendering example. It initializes the window, camera, and mesh, generates texture coordinates, loads the lightmap shader and textures, creates a render texture, and configures the material with the lightmap. ```c /******************************************************************************************* * * raylib [shaders] example - lightmap rendering * * Example complexity rating: [★★★☆] 3/4 * * NOTE: This example requires raylib OpenGL 3.3 or ES2 versions for shaders support, * OpenGL 1.1 does not support shaders, recompile raylib to OpenGL 3.3 version * * NOTE: Shaders used in this example are #version 330 (OpenGL 3.3) * * Example originally created with raylib 4.5, last time updated with raylib 4.5 * * Example contributed by Jussi Viitala (@nullstare) and reviewed by Ramon Santamaria (@raysan5) * * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * BSD-like license that allows static linking with closed source software * * Copyright (c) 2019-2025 Jussi Viitala (@nullstare) and Ramon Santamaria (@raysan5) * ********************************************************************************************/ #include <stdio.h> #include <stdlib.h> #include "raylib.h" #include "raymath.h" #include "rlgl.h" #if defined(PLATFORM_DESKTOP) #define GLSL_VERSION 330 #else // PLATFORM_ANDROID, PLATFORM_WEB #define GLSL_VERSION 100 #endif #define MAP_SIZE 16 //------------------------------------------------------------------------------------ // Program main entry point //------------------------------------------------------------------------------------ int main(void) { // Initialization //-------------------------------------------------------------------------------------- const int screenWidth = 800; const int screenHeight = 450; SetConfigFlags(FLAG_MSAA_4X_HINT); // Enable Multi Sampling Anti Aliasing 4x (if available) InitWindow(screenWidth, screenHeight, "raylib [shaders] example - lightmap rendering"); // Define the camera to look into our 3d world Camera camera = { 0 }; camera.position = (Vector3){ 4.0f, 6.0f, 8.0f }; // Camera position camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera looking at point camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target) camera.fovy = 45.0f; // Camera field-of-view Y camera.projection = CAMERA_PERSPECTIVE; // Camera projection type Mesh mesh = GenMeshPlane((float)MAP_SIZE, (float)MAP_SIZE, 1, 1); // GenMeshPlane doesn't generate texcoords2 so we will upload them separately mesh.texcoords2 = (float *)RL_MALLOC(mesh.vertexCount*2*sizeof(float)); // X // Y mesh.texcoords2[0] = 0.0f; mesh.texcoords2[1] = 0.0f; mesh.texcoords2[2] = 1.0f; mesh.texcoords2[3] = 0.0f; mesh.texcoords2[4] = 0.0f; mesh.texcoords2[5] = 1.0f; mesh.texcoords2[6] = 1.0f; mesh.texcoords2[7] = 1.0f; // Load a new texcoords2 attributes buffer mesh.vboId[SHADER_LOC_VERTEX_TEXCOORD02] = rlLoadVertexBuffer(mesh.texcoords2, mesh.vertexCount*2*sizeof(float), false); rlEnableVertexArray(mesh.vaoId); // Index 5 is for texcoords2 rlSetVertexAttribute(5, 2, RL_FLOAT, 0, 0, 0); rlEnableVertexAttribute(5); rlDisableVertexArray(); // Load lightmap shader Shader shader = LoadShader(TextFormat("resources/shaders/glsl%i/lightmap.vs", GLSL_VERSION), TextFormat("resources/shaders/glsl%i/lightmap.fs", GLSL_VERSION)); Texture texture = LoadTexture("resources/cubicmap_atlas.png"); Texture light = LoadTexture("resources/spark_flame.png"); GenTextureMipmaps(&texture); SetTextureFilter(texture, TEXTURE_FILTER_TRILINEAR); RenderTexture lightmap = LoadRenderTexture(MAP_SIZE, MAP_SIZE); Material material = LoadMaterialDefault(); material.shader = shader; material.maps[MATERIAL_MAP_ALBEDO].texture = texture; material.maps[MATERIAL_MAP_METALNESS].texture = lightmap.texture; // Drawing to lightmap BeginTextureMode(lightmap); ClearBackground(BLACK); ``` -------------------------------- ### Initialize window, shaders, and lights for lights_bloom example Source: https://www.raylib.com/examples/shaders/loader.html?name=shaders_lights_bloom Initialization and setup for the raylib lights bloom example: creates an 800x450 window with MSAA and VSYNC, loads the forward lighting and bloom post-process shaders from resources/shaders/glsl{100,330}, and prepares a cube and floor model with the light shader. It also defines 8 light colors and uploads them via SetShaderValueV with SHADER_UNIFORM_VEC3. The GLSL version is chosen by PLATFORM_DESKTOP (330) or other platforms (100). ```c /******************************************************************************************* * * raylib [shaders] example - lights bloom * * Example demonstrates forward multi-point lighting (8 point lights, attenuation and * Blinn-Phong specular) combined with a threshold-based bloom pass and Reinhard tone * mapping, applied as a full-screen post-process pass * * Example complexity rating: [★★★☆] 3/4 * * Example uses resources/shaders/glsl100 and resources/shaders/glsl330, shared with the * rest of the shaders examples * * Example originally created with raylib 6.0, last time updated with raylib 6.0 * * Example contributed by PanicTitan (@PanicTitan) and reviewed by Ramon Santamaria (@raysan5) * * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * BSD-like license that allows static linking with closed source software * * Copyright (c) 2025 PanicTitan (@PanicTitan) * ********************************************************************************************/ #include "raylib.h" #include "raymath.h" #include "rlgl.h" #include <math.h> // Required for: sinf(), cosf() #if defined(PLATFORM_DESKTOP) #define GLSL_VERSION 330 #else // PLATFORM_ANDROID, PLATFORM_WEB #define GLSL_VERSION 100 #endif //-------------------------------------------------------------------------------------- // Global Definitions //-------------------------------------------------------------------------------------- #define MAX_LIGHTS 8 //------------------------------------------------------------------------------------ // Program main entry point //------------------------------------------------------------------------------------ int main(void) { // Initialization //-------------------------------------------------------------------------------------- const int screenWidth = 800; const int screenHeight = 450; SetConfigFlags(FLAG_MSAA_4X_HINT | FLAG_VSYNC_HINT); InitWindow(screenWidth, screenHeight, "raylib [shaders] example - lights bloom"); Camera3D camera = { 0 }; camera.position = (Vector3){ 0.0f, 5.0f, 9.0f }; camera.target = (Vector3){ 0.0f, 0.5f, 0.0f }; camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; camera.fovy = 45.0f; camera.projection = CAMERA_PERSPECTIVE; RenderTexture2D target = LoadRenderTexture(screenWidth, screenHeight); // Forward multi-light shader and bloom post-process shader, both loaded from the // resources folder shared with the rest of the shaders examples. If the GLSL version // guessed from the PLATFORM_DESKTOP build flag turns out to be wrong for whatever // raylib was built against, linking fails and silently falls back to the default // shader - so this retries once with the other version, and either way the result // is checked explicitly and reported on screen rather than staying silently wrong Shader lightShader = LoadShader(TextFormat("resources/shaders/glsl%i/lights_bloom.vs", GLSL_VERSION), TextFormat("resources/shaders/glsl%i/lights_bloom.fs", GLSL_VERSION)); Shader bloomShader = LoadShader(0, TextFormat("resources/shaders/glsl%i/lights_bloom_post.fs", GLSL_VERSION)); // Load models from generated cube mesh and plane // NOTE: Meshes are automatically unloaded on UnloadModel() Model cube = LoadModelFromMesh(GenMeshCube(2.0f, 2.0f, 2.0f)); Model floor = LoadModelFromMesh(GenMeshPlane(14.0f, 14.0f, 1, 1)); cube.materials[0].shader = lightShader; floor.materials[0].shader = lightShader; int lightPosLoc = GetShaderLocation(lightShader, "lightPositions"); int lightColLoc = GetShaderLocation(lightShader, "lightColors"); int viewPosLoc = GetShaderLocation(lightShader, "viewPos"); Vector3 lightPositions[MAX_LIGHTS] = { 0 }; Vector3 lightColors[MAX_LIGHTS] = { { 1.0f, 0.2f, 0.2f }, // Red { 0.2f, 1.0f, 0.3f }, // Green { 0.2f, 0.5f, 1.0f }, // Blue { 1.0f, 0.8f, 0.1f }, // Yellow { 1.0f, 0.1f, 0.8f }, // Magenta { 0.1f, 1.0f, 1.0f }, // Cyan { 1.0f, 0.4f, 0.1f }, // Orange { 0.7f, 0.2f, 1.0f }, // Purple }; SetShaderValueV(lightShader, lightColLoc, lightColors, SHADER_UNIFORM_VEC3, MAX_LIGHTS); SetTargetFPS(60); //-------------------------------------------------------------------------------------- // Main game loop while (!WindowShouldClose()) // Detect window close button or ESC key { // Update //---------------------------------------------------------------------------------- UpdateCamera(&camera, CAMERA_ORBITAL); float time = (float)GetTime(); ``` -------------------------------- ### raylib [core] example - smooth pixelperfect: Setup and update Source: https://www.raylib.com/examples/core/loader.html?name=core_smooth_pixelperfect Initializes a 160x90 virtual render texture and two cameras: a world-space camera and a screen-space smoothing camera. The example uses a 800x450 window and a virtual ratio to demonstrate smooth pixel-perfect rendering. ```c "#include \"raylib.h\"\n\n#include <math.h> // Required for: sinf(), cosf()\n\n//------------------------------------------------------------------------------------\n// Program main entry point\n//------------------------------------------------------------------------------------\nint main(void)\n{\n // Initialization\n //--------------------------------------------------------------------------------------\n const int screenWidth = 800;\n const int screenHeight = 450;\n\n const int virtualScreenWidth = 160;\n const int virtualScreenHeight = 90;\n\n const float virtualRatio = (float)screenWidth/(float)virtualScreenWidth;\n\n InitWindow(screenWidth, screenHeight, \"raylib [core] example - smooth pixelperfect\");\n\n Camera2D worldSpaceCamera = { 0 }; // Game world camera\n worldSpaceCamera.zoom = 1.0f;\n\n Camera2D screenSpaceCamera = { 0 }; // Smoothing camera\n screenSpaceCamera.zoom = 1.0f;\n\n // Load render texture to draw all our objects\n RenderTexture2D target = LoadRenderTexture(virtualScreenWidth, virtualScreenHeight);\n\n Rectangle rec01 = { 70.0f, 35.0f, 20.0f, 20.0f };\n Rectangle rec02 = { 90.0f, 55.0f, 30.0f, 10.0f };\n Rectangle rec03 = { 80.0f, 65.0f, 15.0f, 25.0f };\n\n // The target's height is flipped (in the source Rectangle), due to OpenGL reasons\n Rectangle sourceRec = { 0.0f, 0.0f, (float)target.texture.width, -(float)target.texture.height };\n Rectangle destRec = { (screenWidth - screenWidth/1.25f)/2.0f, (screenHeight - screenHeight/1.25f)/2.0f, screenWidth/1.25f, screenHeight/1.25f };\n\n Vector2 origin = { 0.0f, 0.0f };\n\n float rotation = 0.0f;\n\n float cameraX = 0.0f;\n float cameraY = 0.0f;\n\n bool smoothOn = true;\n bool overscan = false;\n\n SetTargetFPS(60);\n //--------------------------------------------------------------------------------------\n\n // Main game loop\n while (!WindowShouldClose()) // Detect window close button or ESC key\n {\n // Update\n //----------------------------------------------------------------------------------\n rotation += 60.0f*GetFrameTime(); // Rotate the rectangles, 60 degrees per second\n\n // Make the camera move to demonstrate the effect\n cameraX = (sinf((float)GetTime())*50.0f) - 10.0f;\n cameraY = cosf((float)GetTime())*30.0f;\n\n // Set the camera's target to the values computed above\n screenSpaceCamera.target = (Vector2){ cameraX, cameraY };\n\n // Round worldSpace coordinates, keep decimals into screenSpace coordinates\n worldSpaceCamera.target.x = truncf(screenSpaceCamera.target.x);\n screenSpaceCamera.target.x -= worldSpaceCamera.target.x;\n screenSpaceCamera.target.x *= virtualRatio;\n\n worldSpaceCamera.target.y = truncf(screenSpaceCamera.target.y);\n screenSpaceCamera.target.y -= worldSpaceCamera.target.y;\n screenSpaceCamera.target.y *= virtualRatio;\n\n if (IsKeyPressed(KEY_S)) smoothOn = !smoothOn;\n if (IsKeyPressed(KEY_O)) overscan = !overscan;\n\n if (overscan)\n {\n destRec = (Rectangle) { -virtualRatio, -virtualRatio, screenWidth + (virtualRatio*2), screenHeight + (virtualRatio*2) };\n }\n else\n {\n destRec = (Rectangle) { (screenWidth - screenWidth/1.25f)/2.0f, (screenHeight - screenHeight/1.25f)/2.0f, screenWidth/1.25f, screenHeight/1.25f };\n }\n //----------------------------------------------------------------------------------\n\n // Draw\n //----------------------------------------------------------------------------------\n BeginTextureMode(target);\n ClearBackground(RAYWHITE);\n\n BeginMode2D(worldSpaceCamera);\n DrawRectanglePro(rec01, origin, rotation, BLACK);\n DrawRectanglePro(rec02, origin, -rotation, RED);\n DrawRectanglePro(rec03, origin, rotation + 45.0f, BLUE);\n EndMode2D();\n EndTextureMode();\n\n BeginDrawing();\n ClearBackground(LIGHTGRAY);\n\n" ``` -------------------------------- ### Procedural decals example - full C source Source: https://www.raylib.com/examples/models/loader.html?name=models_procedural_decals Complete raylib example showing procedural decal projection onto a generated mesh. It includes setup of the camera, model, textures, and the decal generation logic. The example uses only procedural geometry and textures, with no external resource files. It requires raylib 6.0 and raygui. ```c /******************************************************************************************* * * raylib [models] example - procedural decals * * Example demonstrates projecting decals onto a 3D mesh surface by transforming the * mesh's own triangles into the decal's local space and clipping them against a box, * using only procedurally generated geometry and textures (no external resource files) * * NOTE: This is the same clip-space decal projection idea used by models_decals.c * (in turn based on three.js' DecalGeometry), applied here to a generated mesh and * generated textures instead of a loaded model, so the example is fully self-contained * * Example complexity rating: [★★★★] 4/4 * * Example originally created with raylib 6.0, last time updated with raylib 6.0 * * Example contributed by PanicTitan (@PanicTitan) and reviewed by Ramon Santamaria (@raysan5) * * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * BSD-like license that allows static linking with closed source software * * Copyright (c) 2025 PanicTitan (@PanicTitan) * ********************************************************************************************/ #include "raylib.h" #define RAYGUI_IMPLEMENTATION #include "raygui.h" #include "raymath.h" #include <stddef.h> // Required for: NULL #include <string.h> // Required for: memcpy() #include <math.h> // Required for: fabsf(), fminf() //-------------------------------------------------------------------------------------- // Global Definitions //-------------------------------------------------------------------------------------- #define MAX_DECALS 256 //-------------------------------------------------------------------------------------- // Types and Structures Definition //-------------------------------------------------------------------------------------- // Growable triangle-soup buffer used while building a clipped decal mesh typedef struct MeshBuilder { int vertexCount; int vertexCapacity; Vector3 *vertices; Vector2 *uvs; } MeshBuilder; //------------------------------------------------------------------------------------ // Module Functions Declaration //------------------------------------------------------------------------------------ static void AddTriangleToMeshBuilder(MeshBuilder *mb, Vector3 v0, Vector3 v1, Vector3 v2); static void FreeMeshBuilder(MeshBuilder *mb); static Mesh BuildMesh(MeshBuilder *mb); static Vector3 ClipSegment(Vector3 v0, Vector3 v1, Vector3 p, float s); static Mesh GenMeshDecal(Model model, Matrix projection, float decalSize, float decalOffset); //------------------------------------------------------------------------------------ // Program main entry point //------------------------------------------------------------------------------------ int main(void) { // Initialization //-------------------------------------------------------------------------------------- const int screenWidth = 800; const int screenHeight = 450; SetConfigFlags(FLAG_MSAA_4X_HINT); InitWindow(screenWidth, screenHeight, "raylib [models] example - procedural decals"); Camera3D camera = { 0 }; camera.position = (Vector3){ 0.0f, 2.5f, 5.0f }; camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; camera.fovy = 45.0f; camera.projection = CAMERA_PERSPECTIVE; // Target model: a procedurally generated knot with a checkerboard skin Model model = LoadModelFromMesh(GenMeshTorus(0.8f, 1.8f, 32, 64)); Image checkerImage = GenImageChecked(512, 512, 32, 32, LIGHTGRAY, GRAY); Texture2D modelTexture = LoadTextureFromImage(checkerImage); UnloadImage(checkerImage); SetTextureFilter(modelTexture, TEXTURE_FILTER_BILINEAR); model.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = modelTexture; BoundingBox modelBBox = GetMeshBoundingBox(model.meshes[0]); camera.target = Vector3Lerp(modelBBox.min, modelBBox.max, 0.5f); float modelSize = fminf(fminf(fabsf(modelBBox.max.x - modelBBox.min.x), fabsf(modelBBox.max.y - modelBBox.min.y)), fabsf(modelBBox.max.z - modelBBox.min.z)); float decalSize = modelSize*0.35f; float decalOffset = 0.01f; // Translucent cube previewing where the next decal will land Model placementCube = LoadModelFromMesh(GenMeshCube(decalSize, decalSize, decalSize)); placementCube.materials[0].maps[0].color = LIME; // Decal texture: a procedurally drawn target/bullseye, no image file needed Image decalImage = GenImageColor(128, 128, BLANK); ImageDrawCircle(&decalImage, 64, 64, 60, RED); ImageDrawCircle(&decalImage, 64, 64, 45, WHITE); ImageDrawCircle(&decalImage, 64, 64, 30, RED); ImageDrawCircle(&decalImage, 64, 64, 15, YELLOW); Texture2D decalTexture = LoadTextureFromImage(decalImage); UnloadImage(decalImage); SetTextureFilter(decalTexture, TEXTURE_FILTER_BILINEAR); ``` -------------------------------- ### Initialize spotlight shader and spot locations in C Source: https://www.raylib.com/examples/shaders/loader.html?name=shaders_spotlight_rendering Initialization and setup for the raylib spotlight rendering example. It loads the spotlight fragment shader, retrieves uniform locations for each spot, and sets the screen width uniform. The code is incomplete as the source text is truncated mid-loop. ```c /******************************************************************************************* * * raylib [shaders] example - spotlight rendering * * Example complexity rating: [★★☆☆] 2/4 * * Example originally created with raylib 2.5, last time updated with raylib 3.7 * * Example contributed by Chris Camacho (@chriscamacho) and reviewed by Ramon Santamaria (@raysan5) * * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * BSD-like license that allows static linking with closed source software * * Copyright (c) 2019-2025 Chris Camacho (@chriscamacho) and Ramon Santamaria (@raysan5) * ******************************************************************************************** * * The shader makes alpha holes in the forground to give the appearance of a top * down look at a spotlight casting a pool of light... * * The right hand side of the screen there is just enough light to see whats * going on without the spot light, great for a stealth type game where you * have to avoid the spotlights * * The left hand side of the screen is in pitch dark except for where the spotlights are * * Although this example doesn't scale like the letterbox example, you could integrate * the two techniques, but by scaling the actual colour of the render texture rather * than using alpha as a mask * ********************************************************************************************/ #include "raylib.h" #include "raymath.h" #if defined(PLATFORM_DESKTOP) #define GLSL_VERSION 330 #else // PLATFORM_ANDROID, PLATFORM_WEB #define GLSL_VERSION 100 #endif #define MAX_SPOTS 3 // NOTE: It must be the same as define in shader #define MAX_STARS 400 //---------------------------------------------------------------------------------- // Types and Structures Definition //---------------------------------------------------------------------------------- // Spot data typedef struct Spot { Vector2 position; Vector2 speed; float inner; float radius; // Shader locations unsigned int positionLoc; unsigned int innerLoc; unsigned int radiusLoc; } Spot; // Stars in the star field have a position and velocity typedef struct Star { Vector2 position; Vector2 speed; } Star; //-------------------------------------------------------------------------------------- // Module Functions Declaration //-------------------------------------------------------------------------------------- static void UpdateStar(Star *star); static void ResetStar(Star *star); //------------------------------------------------------------------------------------ // Program main entry point //------------------------------------------------------------------------------------ int main(void) { // Initialization //-------------------------------------------------------------------------------------- const int screenWidth = 800; const int screenHeight = 450; InitWindow(screenWidth, screenHeight, "raylib [shaders] example - spotlight rendering"); HideCursor(); Texture texRay = LoadTexture("resources/raysan.png"); Star stars[MAX_STARS] = { 0 }; for (int n = 0; n < MAX_STARS; n++) ResetStar(&stars[n]); // Progress all the stars on, so they don't all start in the centre for (int m = 0; m < screenWidth/2.0; m++) { for (int n = 0; n < MAX_STARS; n++) UpdateStar(&stars[n]); } int frameCounter = 0; // Use default vert shader Shader shdrSpot = LoadShader(0, TextFormat("resources/shaders/glsl%i/spotlight.fs", GLSL_VERSION)); // Get the locations of spots in the shader Spot spots[MAX_SPOTS]; for (int i = 0; i < MAX_SPOTS; i++) { char posName[32] = "spots[x].pos\0"; char innerName[32] = "spots[x].inner\0"; char radiusName[32] = "spots[x].radius\0"; posName[6] = '0' + i; innerName[6] = '0' + i; radiusName[6] = '0' + i; spots[i].positionLoc = GetShaderLocation(shdrSpot, posName); spots[i].innerLoc = GetShaderLocation(shdrSpot, innerName); spots[i].radiusLoc = GetShaderLocation(shdrSpot, radiusName); } // Tell the shader how wide the screen is so we can have // a pitch black half and a dimly lit half unsigned int wLoc = GetShaderLocation(shdrSpot, "screenWidth"); float sw = (float)GetScreenWidth(); SetShaderValue(shdrSpot, wLoc, &sw, SHADER_UNIFORM_FLOAT); // Randomize the locations and velocities of the spotlights // and initialize the shader locations for (int i = 0; i < MAX_SPOTS; i++) { spots[i].position.x = (float)GetRandomValue(64, screenWidth - 64); spots[i].position.y = (float)GetRandomValue(64, screenHeight - 64); spots[i].speed = (Vector2){ 0, 0 }; ``` -------------------------------- ### Particles blending example source code Source: https://www.raylib.com/examples/textures/loader.html?name=textures_particles_blending Complete raylib example showing particle blending. It loads a smoke texture, creates particles, and toggles between BLEND_ALPHA and BLEND_ADDITIVE. The code includes window setup, main loop, drawing, and cleanup. ```c if (blending == BLEND_ALPHA) DrawText("ALPHA BLENDING", 290, screenHeight - 40, 20, BLACK); else DrawText("ADDITIVE BLENDING", 280, screenHeight - 40, 20, RAYWHITE); EndDrawing(); //---------------------------------------------------------------------------------- } // De-Initialization //-------------------------------------------------------------------------------------- UnloadTexture(smoke); CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- return 0; } ```