Watch
2
0
Fork
You've already forked raylib-cs
0

WASM examples (+ backports of new official examples) (#344)

* chg: New build system that uses the officially distributed binaries, bumped version to 8.0.0, simplified git workflow, removed deprecated OpenGL 1.1 functionality.

* chg: Modernize CI workflow, enable SourceLink

- Bump workflow actions to latest majors (Node 24); drop deprecated softprops/action-gh-release@v1
- Trigger push builds on main instead of master
- Create local nuget feed dir before pack (fixes NU1301)
- Enable Microsoft.SourceLink.GitHub for debugging symbols (ref PR #340)

* fix: centralized version data in Directory.build.props, and fixed various interop details that had incorrect function signatures

* chore: updated readme

* fix: version the native extract marker and chain download via DependsOnTargets

The .extracted marker now includes the raylib package name, so bumping
TargetRaylibTag re-extracts the new archive instead of silently keeping
(and packing/copying) the previous version's files.

_PrepareNativeLibrary and _StageWasmNative now depend directly on
_DownloadAndExtractInternal instead of CallTarget-ing it; dependency
targets run in the same project instance, so the resolved properties
(RaylibPackageName etc.) propagate naturally.

* fix: let the binding build for browser-wasm on both net8.0 and net10.0

The net8-era wasm workload (Microsoft.NET.Runtime.WebAssembly.Sdk 8.0.x,
auto-imported for RID browser-wasm) treats every browser-wasm project as
a wasm app: it forces OutputType=Exe after project evaluation (CS5001
for a classlib) and hooks its app-bundle build after Build, which errors
because a library has no assemblies to bundle. Opt Raylib-cs out via
DisableAutoWasmBuildApp (props time, before the workload defaults its
trigger) and pin OutputType back to Library in Directory.Build.targets
(evaluated after the workload props, so the assignment wins). net10's
wasm SDK needs neither workaround.

* chore: readme updated

* chg: simplifying build logic - a simple line in the documentation should save us the code here

* fix: Wrong signature of FrameBufferComplete

* chore: readme update

* feat: samples default to local project reference, and can optionally use the nuget package

* feat: backporting existing raylib-cs examples and new official raylib examples to WASM, adopting raylib's original code style

* chore: readme, gitignore, and targets backport.

* fix: Examples.csproj runs the download task when building locally

* feat: backporting existing raylib-cs examples and new official raylib examples to WASM, adopting raylib's original code style

* chore: readme, gitignore, and targets backport.

* chore: clean up linter warnings

* feat: html harness focuses the example and allows quick navigation with J/K instead.

* chore: readme mentions the property to use nuget vs. the local project reference

* feat: replaced the J/K navigation with good old HTML buttons

* chore: run dotnet format scoped default (was previously scoped to just 'style')
This commit is contained in:
tiger tiger tiger 2026-07-30 19:34:34 +02:00 committed by GitHub
commit 8c22e68c2a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
236 changed files with 40405 additions and 10896 deletions

View file

@ -1,114 +1,140 @@
/*******************************************************************************************
*
* raylib [textures] example - Background scrolling
* raylib [textures] example - background scrolling
*
* This example has been created using raylib 2.0 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
* Example complexity rating: [] 1/4
*
* Copyright (c) 2019 Ramon Santamaria (@raysan5)
* Example originally created with raylib 2.0, last time updated with raylib 2.5
*
* 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 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
using System.Numerics;
using static Raylib_cs.Raylib;
namespace Examples.Textures;
public class BackgroundScrolling
public partial class BackgroundScrolling : IExample
{
private const int screenWidth = 800;
private const int screenHeight = 450;
public string Name => "Textures / Background Scrolling";
public string Title => "raylib [textures] example - background scrolling";
private Texture2D background;
private Texture2D midground;
private Texture2D foreground;
private float scrollingBack;
private float scrollingMid;
private float scrollingFore;
public void Init()
{
// NOTE: Be careful, background width must be equal or bigger than screen width
// if not, texture should be draw more than two times for scrolling effect
background = LoadTexture("resources/cyberpunk_street_background.png");
midground = LoadTexture("resources/cyberpunk_street_midground.png");
foreground = LoadTexture("resources/cyberpunk_street_foreground.png");
scrollingBack = 0.0f;
scrollingMid = 0.0f;
scrollingFore = 0.0f;
}
public void Update()
{
// Update
//----------------------------------------------------------------------------------
scrollingBack -= 0.1f;
scrollingMid -= 0.5f;
scrollingFore -= 1.0f;
// NOTE: Texture is scaled twice its size, so it sould be considered on scrolling
if (scrollingBack <= -background.Width * 2)
{
scrollingBack = 0;
}
if (scrollingMid <= -midground.Width * 2)
{
scrollingMid = 0;
}
if (scrollingFore <= -foreground.Width * 2)
{
scrollingFore = 0;
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(GetColor(0x052c46ff));
// Draw background image twice
// NOTE: Texture is scaled twice its size
DrawTextureEx(background, new Vector2(scrollingBack, 20), 0.0f, 2.0f, Color.White);
DrawTextureEx(
background,
new Vector2(background.Width * 2 + scrollingBack, 20),
0.0f,
2.0f,
Color.White
);
// Draw midground image twice
DrawTextureEx(midground, new Vector2(scrollingMid, 20), 0.0f, 2.0f, Color.White);
DrawTextureEx(midground, new Vector2(midground.Width * 2 + scrollingMid, 20), 0.0f, 2.0f, Color.White);
// Draw foreground image twice
DrawTextureEx(foreground, new Vector2(scrollingFore, 70), 0.0f, 2.0f, Color.White);
DrawTextureEx(
foreground,
new Vector2(foreground.Width * 2 + scrollingFore, 70),
0.0f,
2.0f,
Color.White
);
DrawText("BACKGROUND SCROLLING & PARALLAX", 10, 10, 20, Color.Red);
DrawText("(c) Cyberpunk Street Environment by Luis Zuno (@ansimuz)", screenWidth - 330, screenHeight - 20, 10, Color.RayWhite);
EndDrawing();
//----------------------------------------------------------------------------------
}
public void Unload()
{
UnloadTexture(background); // Unload background texture
UnloadTexture(midground); // Unload midground texture
UnloadTexture(foreground); // Unload foreground texture
}
public static int Main()
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [textures] example - background scrolling");
// NOTE: Be careful, background width must be equal or bigger than screen width
// if not, texture should be draw more than two times for scrolling effect
Texture2D background = LoadTexture("resources/cyberpunk_street_background.png");
Texture2D midground = LoadTexture("resources/cyberpunk_street_midground.png");
Texture2D foreground = LoadTexture("resources/cyberpunk_street_foreground.png");
float scrollingBack = 0.0f;
float scrollingMid = 0.0f;
float scrollingFore = 0.0f;
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
var game = new BackgroundScrolling();
game.Init();
// Main game loop
while (!WindowShouldClose())
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
scrollingBack -= 0.1f;
scrollingMid -= 0.5f;
scrollingFore -= 1.0f;
// NOTE: Texture is scaled twice its size, so it sould be considered on scrolling
if (scrollingBack <= -background.Width * 2)
{
scrollingBack = 0;
}
if (scrollingMid <= -midground.Width * 2)
{
scrollingMid = 0;
}
if (scrollingFore <= -foreground.Width * 2)
{
scrollingFore = 0;
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(GetColor(0x052c46ff));
// Draw background image twice
// NOTE: Texture is scaled twice its size
DrawTextureEx(background, new Vector2(scrollingBack, 20), 0.0f, 2.0f, Color.White);
DrawTextureEx(
background,
new Vector2(background.Width * 2 + scrollingBack, 20),
0.0f,
2.0f,
Color.White
);
// Draw midground image twice
DrawTextureEx(midground, new Vector2(scrollingMid, 20), 0.0f, 2.0f, Color.White);
DrawTextureEx(midground, new Vector2(midground.Width * 2 + scrollingMid, 20), 0.0f, 2.0f, Color.White);
// Draw foreground image twice
DrawTextureEx(foreground, new Vector2(scrollingFore, 70), 0.0f, 2.0f, Color.White);
DrawTextureEx(
foreground,
new Vector2(foreground.Width * 2 + scrollingFore, 70),
0.0f,
2.0f,
Color.White
);
DrawText("BACKGROUND SCROLLING & PARALLAX", 10, 10, 20, Color.Red);
int x = screenWidth - 330;
int y = screenHeight - 20;
DrawText("(c) Cyberpunk Street Environment by Luis Zuno (@ansimuz)", x, y, 10, Color.RayWhite);
EndDrawing();
//----------------------------------------------------------------------------------
game.Update();
}
game.Unload();
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadTexture(background);
UnloadTexture(midground);
UnloadTexture(foreground);
CloseWindow();
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;

View file

@ -2,114 +2,145 @@
*
* raylib [textures] example - blend modes
*
* Example complexity rating: [] 1/4
*
* NOTE: Images are loaded in CPU memory (RAM); textures are loaded in GPU memory (VRAM)
*
* This example has been created using raylib 3.5 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
* Example originally created with raylib 3.5, last time updated with raylib 3.5
*
* Example contributed by Karlo Licudine (@accidentalrebel) and reviewed by Ramon Santamaria (@raysan5)
*
* Copyright (c) 2020 Karlo Licudine (@accidentalrebel)
* 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) 2020-2025 Karlo Licudine (@accidentalrebel)
*
********************************************************************************************/
using static Raylib_cs.Raylib;
namespace Examples.Textures;
public class BlendModes
public partial class BlendModes : IExample
{
public static int Main()
private const int screenWidth = 800;
private const int screenHeight = 450;
private const int blendCountMax = 4;
public string Name => "Textures / Blend Modes";
public string Title => "raylib [textures] example - blend modes";
private Texture2D bgTexture;
private Texture2D fgTexture;
private BlendMode blendMode;
public void Init()
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [textures] example - blend modes");
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
Image bgImage = LoadImage("resources/cyberpunk_street_background.png");
Texture2D bgTexture = LoadTextureFromImage(bgImage);
var bgImage = LoadImage("resources/cyberpunk_street_background.png");
bgTexture = LoadTextureFromImage(bgImage);
Image fgImage = LoadImage("resources/cyberpunk_street_foreground.png");
Texture2D fgTexture = LoadTextureFromImage(fgImage);
var fgImage = LoadImage("resources/cyberpunk_street_foreground.png");
fgTexture = LoadTextureFromImage(fgImage);
// Once image has been converted to texture and uploaded to VRAM, it can be unloaded from RAM
UnloadImage(bgImage);
UnloadImage(fgImage);
const int blendCountMax = 4;
BlendMode blendMode = 0;
blendMode = 0;
}
public void Update()
{
// Update
//----------------------------------------------------------------------------------
if (IsKeyPressed(KeyboardKey.Space))
{
if ((int)blendMode >= (blendCountMax - 1))
{
blendMode = 0;
}
else
{
blendMode++;
}
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
var bgX = screenWidth / 2 - bgTexture.Width / 2;
var bgY = screenHeight / 2 - bgTexture.Height / 2;
DrawTexture(bgTexture, bgX, bgY, Color.White);
// Apply the blend mode and then draw the foreground texture
BeginBlendMode(blendMode);
var fgX = screenWidth / 2 - fgTexture.Width / 2;
var fgY = screenHeight / 2 - fgTexture.Height / 2;
DrawTexture(fgTexture, fgX, fgY, Color.White);
EndBlendMode();
// Draw the texts
DrawText("Press SPACE to change blend modes.", 310, 350, 10, Color.Gray);
switch (blendMode)
{
case BlendMode.Alpha:
DrawText("Current: BLEND_ALPHA", (screenWidth / 2) - 60, 370, 10, Color.Gray);
break;
case BlendMode.Additive:
DrawText("Current: BLEND_ADDITIVE", (screenWidth / 2) - 60, 370, 10, Color.Gray);
break;
case BlendMode.Multiplied:
DrawText("Current: BLEND_MULTIPLIED", (screenWidth / 2) - 60, 370, 10, Color.Gray);
break;
case BlendMode.AddColors:
DrawText("Current: BLEND_ADD_COLORS", (screenWidth / 2) - 60, 370, 10, Color.Gray);
break;
default:
break;
}
var text = "(c) Cyberpunk Street Environment by Luis Zuno (@ansimuz)";
DrawText(text, screenWidth - 330, screenHeight - 20, 10, Color.Gray);
EndDrawing();
//----------------------------------------------------------------------------------
}
public void Unload()
{
UnloadTexture(fgTexture); // Unload foreground texture
UnloadTexture(bgTexture); // Unload background texture
}
public static int Main()
{
// Initialization
//--------------------------------------------------------------------------------------
InitWindow(screenWidth, screenHeight, "raylib [textures] example - blend modes");
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//---------------------------------------------------------------------------------------
var game = new BlendModes();
game.Init();
// Main game loop
while (!WindowShouldClose())
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
if (IsKeyPressed(KeyboardKey.Space))
{
if ((int)blendMode >= (blendCountMax - 1))
{
blendMode = 0;
}
else
{
blendMode++;
}
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
int bgX = screenWidth / 2 - bgTexture.Width / 2;
int bgY = screenHeight / 2 - bgTexture.Height / 2;
DrawTexture(bgTexture, bgX, bgY, Color.White);
// Apply the blend mode and then draw the foreground texture
BeginBlendMode(blendMode);
int fgX = screenWidth / 2 - fgTexture.Width / 2;
int fgY = screenHeight / 2 - fgTexture.Height / 2;
DrawTexture(fgTexture, fgX, fgY, Color.White);
EndBlendMode();
// Draw the texts
DrawText("Press SPACE to change blend modes.", 310, 350, 10, Color.Gray);
switch (blendMode)
{
case BlendMode.Alpha:
DrawText("Current: BLEND_ALPHA", (screenWidth / 2) - 60, 370, 10, Color.Gray);
break;
case BlendMode.Additive:
DrawText("Current: BLEND_ADDITIVE", (screenWidth / 2) - 60, 370, 10, Color.Gray);
break;
case BlendMode.Multiplied:
DrawText("Current: BLEND_MULTIPLIED", (screenWidth / 2) - 60, 370, 10, Color.Gray);
break;
case BlendMode.AddColors:
DrawText("Current: BLEND_ADD_COLORS", (screenWidth / 2) - 60, 370, 10, Color.Gray);
break;
default:
break;
}
string text = "(c) Cyberpunk Street Environment by Luis Zuno (@ansimuz)";
DrawText(text, screenWidth - 330, screenHeight - 20, 10, Color.Gray);
EndDrawing();
//----------------------------------------------------------------------------------
game.Update();
}
game.Unload();
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadTexture(fgTexture);
UnloadTexture(bgTexture);
CloseWindow();
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;

View file

@ -1,23 +1,27 @@
/*******************************************************************************************
*
* raylib [textures] example - Bunnymark
* raylib [textures] example - bunnymark
*
* This example has been created using raylib 1.6 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
* Example complexity rating: [] 3/4
*
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5), 2024 Moritz Voss (@thygrrr)
* Example originally created with raylib 1.6, last time updated with raylib 2.5
*
* 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) 2014-2025 Ramon Santamaria (@raysan5), 2024 Moritz Voss (@thygrrr)
*
********************************************************************************************/
using System.Diagnostics;
using System.Numerics;
using static Raylib_cs.Raylib;
namespace Examples.Textures;
public static class Bunnymark
public partial class Bunnymark : IExample
{
private const int screenWidth = 800;
private const int screenHeight = 450;
// limits
private const int MaxBunnies = 500_000;
private const int BunnyIncrement = 500;
@ -28,6 +32,10 @@ public static class Bunnymark
// This is the maximum amount of elements (quads) per batch
private const int MAX_BATCH_ELEMENTS = Rlgl.DEFAULT_BATCH_BUFFER_ELEMENTS;
public string Name => "Textures / Bunnymark";
public string Title => "raylib [textures] example - bunnymark";
private record struct Bunny()
{
public Vector2 Position { get; set; } = GetMousePosition();
@ -46,99 +54,123 @@ public static class Bunnymark
GetRandomValue(100, 240), 255);
}
private Texture2D texBunny;
private Vector2 halfSize;
private Bunny[] bunnies;
private int bunniesCount;
public void Init()
{
// Load bunny texture
texBunny = LoadTexture("resources/wabbit_alpha.png");
halfSize = new Vector2(texBunny.Width, texBunny.Height) / 2;
// Initialize bunnies storage
bunnies = new Bunny[MaxBunnies];
bunniesCount = 0;
}
public void Update()
{
// Update
//----------------------------------------------------------------------------------
Span<Bunny> bunnies = this.bunnies;
if (IsMouseButtonDown(MouseButton.Left) && bunniesCount < MaxBunnies)
{
// Add a range of new bunnies
foreach (ref var bunny in bunnies[bunniesCount..(bunniesCount + BunnyIncrement)])
{
bunny = new();
}
bunniesCount += BunnyIncrement;
}
else if (IsMouseButtonDown(MouseButton.Right))
{
// Remove the oldest bunnies, shifting them back in the span
if (bunniesCount > BunnyDecrement)
{
bunnies[BunnyDecrement..bunniesCount].CopyTo(bunnies);
}
bunniesCount = Math.Max(0, bunniesCount - BunnyDecrement);
}
// Update bunnies
foreach (ref var bunny in bunnies[..bunniesCount])
{
// Integrate position
bunny.Position += bunny.Speed;
// Bounce bunnies off the screen borders
bunny.Speed *= (bunny.Position + halfSize) switch
{
{ X: < 0 or > screenWidth, Y: < 40 or > screenHeight } => new(-1, -1),
{ X: < 0 or > screenWidth } => new(-1, 1),
{ Y: < 40 or > screenHeight } => new(1, -1),
_ => Vector2.One,
};
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
foreach (var bunny in bunnies[..bunniesCount])
{
// NOTE: When internal batch buffer limit is reached (MAX_BATCH_ELEMENTS),
// a draw call is launched and buffer starts being filled again;
// before issuing a draw call, updated vertex data from internal CPU buffer is send to GPU...
// Process of sending data is costly and it could happen that GPU data has not been completely
// processed for drawing while new data is tried to be sent (updating current in-use buffers)
// it could generates a stall and consequently a frame drop, limiting the number of drawn bunnies
DrawTexture(texBunny, (int)bunny.Position.X, (int)bunny.Position.Y, bunny.Color);
}
DrawRectangle(0, 0, screenWidth, 40, Color.Black);
DrawText($"bunnies: {bunniesCount}", 120, 10, 20, Color.Green);
DrawText($"batched draw calls: {1 + bunniesCount / MAX_BATCH_ELEMENTS}", 320, 10, 20, Color.Maroon);
DrawText("Left Mouse: Add Bunnies!!! :D", 10, 400, 20, Color.LightGray);
DrawText("Right Mouse: Remove Bunnies", 10, 420, 20, Color.LightGray);
DrawFPS(10, 10);
EndDrawing();
//----------------------------------------------------------------------------------
}
public void Unload()
{
UnloadTexture(texBunny);
#if BROWSER
bunnies = null;
bunniesCount = 0;
#endif
}
public static int Main()
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [textures] example - bunnymark");
// Load bunny texture
Texture2D texBunny = LoadTexture("resources/wabbit_alpha.png");
Vector2 halfSize = new Vector2(texBunny.Width, texBunny.Height) / 2;
// Initialize bunnies storage
Span<Bunny> bunnies = new Bunny[MaxBunnies];
int bunniesCount = 0;
SetTargetFPS(TARGET_FPS);
//--------------------------------------------------------------------------------------
var game = new Bunnymark();
game.Init();
// Main game loop
while (!WindowShouldClose())
{
// Update
//----------------------------------------------------------------------------------
if (IsMouseButtonDown(MouseButton.Left) && bunniesCount < MaxBunnies)
{
// Add a range of new bunnies
foreach (ref var bunny in bunnies[bunniesCount..(bunniesCount + BunnyIncrement)])
{
bunny = new();
}
bunniesCount += BunnyIncrement;
}
else if (IsMouseButtonDown(MouseButton.Right))
{
// Remove the oldest bunnies, shifting them back in the span
if (bunniesCount > BunnyDecrement)
{
bunnies[BunnyDecrement..bunniesCount].CopyTo(bunnies);
}
bunniesCount = Math.Max(0, bunniesCount - BunnyDecrement);
}
// Update bunnies
foreach (ref var bunny in bunnies[..bunniesCount])
{
// Integrate position
bunny.Position += bunny.Speed;
// Bounce bunnies off the screen borders
bunny.Speed *= (bunny.Position + halfSize) switch
{
{ X: < 0 or > screenWidth, Y: < 40 or > screenHeight } => new(-1, -1),
{ X: < 0 or > screenWidth } => new(-1, 1),
{ Y: < 40 or > screenHeight } => new(1, -1),
_ => Vector2.One,
};
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
foreach (var bunny in bunnies[..bunniesCount])
{
// NOTE: When internal batch buffer limit is reached (MAX_BATCH_ELEMENTS),
// a draw call is launched and buffer starts being filled again;
// before issuing a draw call, updated vertex data from internal CPU buffer is send to GPU...
// Process of sending data is costly, and it could happen that GPU data has not been completely
// processed for drawing while new data is tried to be sent (updating current in-use buffers)
// it could generate a stall and consequently a frame drop, limiting the number of drawn bunnies
DrawTexture(texBunny, (int)bunny.Position.X, (int)bunny.Position.Y, bunny.Color);
}
DrawRectangle(0, 0, screenWidth, 40, Color.Black);
DrawText($"bunnies: {bunniesCount}", 120, 10, 20, Color.Green);
DrawText($"batched draw calls: {1 + bunniesCount / MAX_BATCH_ELEMENTS}", 320, 10, 20, Color.Maroon);
DrawText("Left Mouse: Add Bunnies!!! :D", 10, 400, 20, Color.LightGray);
DrawText("Right Mouse: Remove Bunnies", 10, 420, 20, Color.LightGray);
DrawFPS(10, 10);
EndDrawing();
//----------------------------------------------------------------------------------
game.Update();
}
game.Unload();
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadTexture(texBunny);
CloseWindow();
//--------------------------------------------------------------------------------------

View file

@ -0,0 +1,246 @@
/*******************************************************************************************
*
* raylib [textures] example - cellular automata
*
* Example complexity rating: [] 2/4
*
* Example originally created with raylib 5.6, last time updated with raylib 5.6
*
* Example contributed by Jordi Santonja (@JordSant) 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 Jordi Santonja (@JordSant)
*
********************************************************************************************/
namespace Examples.Textures;
public partial class CellularAutomata : IExample
{
// Initialization constants
//--------------------------------------------------------------------------------------
private const int screenWidth = 800;
private const int screenHeight = 450;
private const int imageWidth = 800;
private const int imageHeight = 800 / 2;
// Rule button sizes and positions
private const int drawRuleStartX = 585;
private const int drawRuleStartY = 10;
private const int drawRuleSpacing = 15;
private const int drawRuleGroupSpacing = 50;
private const int drawRuleSize = 14;
private const int drawRuleInnerSize = 10;
// Preset button sizes
private const int presetsSizeX = 42;
private const int presetsSizeY = 22;
private const int linesUpdatedPerFrame = 4;
public string Name => "Textures / Cellular Automata";
public string Title => "raylib [textures] example - cellular automata";
// Some interesting rules
private static readonly int[] presetValues = { 18, 30, 60, 86, 102, 124, 126, 150, 182, 225 };
private const int presetsCount = 10;
private Image image;
private Texture2D texture;
private int rule;
private int line;
private static void ComputeLine(ref Image image, int line, int rule)
{
// Compute next line pixels. Boundaries are not computed, always 0
for (var i = 1; i < imageWidth - 1; i++)
{
// Get, from the previous line, the 3 pixels states as a binary value
var prevValue = ((GetImageColor(image, i - 1, line - 1).R < 5) ? 4 : 0) + // Left pixel
((GetImageColor(image, i, line - 1).R < 5) ? 2 : 0) + // Center pixel
((GetImageColor(image, i + 1, line - 1).R < 5) ? 1 : 0); // Right pixel
// Get next value from rule bitmask
var currValue = (rule & (1 << prevValue)) != 0;
// Update pixel color
ImageDrawPixel(ref image, i, line, currValue ? Color.Black : Color.RayWhite);
}
}
public void Init()
{
// Image that contains the cellular automaton
image = GenImageColor(imageWidth, imageHeight, Color.RayWhite);
// The top central pixel set as black
ImageDrawPixel(ref image, imageWidth / 2, 0, Color.Black);
texture = LoadTextureFromImage(image);
// Variables
rule = 30; // Starting rule
line = 1; // Line to compute, starting from line 1. One point in line 0 is already set
}
public unsafe void Update()
{
// Update
//----------------------------------------------------------------------------------
// Handle mouse
var mouse = GetMousePosition();
var mouseInCell = -1; // -1: outside any button; 0-7: rule cells; 8+: preset cells
// Check mouse on rule cells
for (var i = 0; i < 8; i++)
{
var cellX = drawRuleStartX - drawRuleGroupSpacing * i + drawRuleSpacing;
var cellY = drawRuleStartY + drawRuleSpacing;
if ((mouse.X >= cellX) && (mouse.X <= cellX + drawRuleSize) &&
(mouse.Y >= cellY) && (mouse.Y <= cellY + drawRuleSize))
{
mouseInCell = i; // 0-7: rule cells
break;
}
}
// Check mouse on preset cells
if (mouseInCell < 0)
{
for (var i = 0; i < presetsCount; i++)
{
var cellX = 4 + (presetsSizeX + 2) * (i / 2);
var cellY = 2 + (presetsSizeY + 2) * (i % 2);
if ((mouse.X >= cellX) && (mouse.X <= cellX + presetsSizeX) &&
(mouse.Y >= cellY) && (mouse.Y <= cellY + presetsSizeY))
{
mouseInCell = i + 8; // 8+: preset cells
break;
}
}
}
if (IsMouseButtonPressed(MouseButton.Left) && (mouseInCell >= 0))
{
// Rule changed both by selecting a preset or toggling a bit
if (mouseInCell < 8)
{
rule ^= (1 << mouseInCell);
}
else
{
rule = presetValues[mouseInCell - 8];
}
// Reset image
ImageClearBackground(ref image, Color.RayWhite);
ImageDrawPixel(ref image, imageWidth / 2, 0, Color.Black);
line = 1;
}
// Compute next lines
//----------------------------------------------------------------------------------
if (line < imageHeight)
{
for (var i = 0; (i < linesUpdatedPerFrame) && (line + i < imageHeight); i++)
{
ComputeLine(ref image, line + i, rule);
}
line += linesUpdatedPerFrame;
UpdateTexture(texture, image.Data);
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
// Draw cellular automaton texture
DrawTexture(texture, 0, screenHeight - imageHeight, Color.White);
// Draw preset values
for (var i = 0; i < presetsCount; i++)
{
DrawText($"{presetValues[i]}", 8 + (presetsSizeX + 2) * (i / 2), 4 + (presetsSizeY + 2) * (i % 2), 20, Color.Gray);
DrawRectangleLines(4 + (presetsSizeX + 2) * (i / 2), 2 + (presetsSizeY + 2) * (i % 2), presetsSizeX, presetsSizeY, Color.Blue);
// If the mouse is on this preset, highlight it
if (mouseInCell == i + 8)
{
DrawRectangleLinesEx(new Rectangle(2 + (presetsSizeX + 2.0f) * (i / 2),
(presetsSizeY + 2.0f) * (i % 2),
presetsSizeX + 4.0f, presetsSizeY + 4.0f), 3, Color.Red);
}
}
// Draw rule bits
for (var i = 0; i < 8; i++)
{
// The three input bits
for (var j = 0; j < 3; j++)
{
DrawRectangleLines(drawRuleStartX - drawRuleGroupSpacing * i + drawRuleSpacing * j, drawRuleStartY, drawRuleSize, drawRuleSize, Color.Gray);
if ((i & (4 >> j)) != 0)
{
DrawRectangle(drawRuleStartX + 2 - drawRuleGroupSpacing * i + drawRuleSpacing * j, drawRuleStartY + 2, drawRuleInnerSize, drawRuleInnerSize, Color.Black);
}
}
// The output bit
DrawRectangleLines(drawRuleStartX - drawRuleGroupSpacing * i + drawRuleSpacing, drawRuleStartY + drawRuleSpacing, drawRuleSize, drawRuleSize, Color.Blue);
if ((rule & (1 << i)) != 0)
{
DrawRectangle(drawRuleStartX + 2 - drawRuleGroupSpacing * i + drawRuleSpacing, drawRuleStartY + 2 + drawRuleSpacing, drawRuleInnerSize, drawRuleInnerSize, Color.Black);
}
// If the mouse is on this rule bit, highlight it
if (mouseInCell == i)
{
DrawRectangleLinesEx(new Rectangle(drawRuleStartX - drawRuleGroupSpacing * i + drawRuleSpacing - 2.0f,
drawRuleStartY + drawRuleSpacing - 2.0f,
drawRuleSize + 4.0f, drawRuleSize + 4.0f), 3, Color.Red);
}
}
DrawText($"RULE: {rule}", drawRuleStartX + drawRuleSpacing * 4, drawRuleStartY + 1, 30, Color.Gray);
EndDrawing();
//----------------------------------------------------------------------------------
}
public void Unload()
{
UnloadImage(image);
UnloadTexture(texture);
}
public static int Main()
{
// Initialization
//--------------------------------------------------------------------------------------
InitWindow(screenWidth, screenHeight, "raylib [textures] example - cellular automata");
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
var game = new CellularAutomata();
game.Init();
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
game.Update();
}
game.Unload();
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
}

View file

@ -0,0 +1,141 @@
/*******************************************************************************************
*
* raylib [textures] example - clipboard image
*
* Example complexity rating: [] 1/4
*
* Example originally created with raylib 6.0, last time updated with raylib 6.0
*
* Example contributed by Maicon Santana (@maiconpintoabreu) 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) 2026 Maicon Santana (@maiconpintoabreu)
*
********************************************************************************************/
namespace Examples.Textures;
[ExcludeFromBrowser("GetClipboardImage() is a desktop-only OS clipboard feature")]
public partial class ClipboardImage : IExample
{
private const int screenWidth = 800;
private const int screenHeight = 450;
private const int MaxTextureCollection = 20;
public string Name => "Textures / Clipboard Image";
public string Title => "raylib [textures] example - clipboard image";
private struct TextureCollection
{
public Texture2D Texture;
public Vector2 Position;
}
private TextureCollection[] collection;
private int currentCollectionIndex;
public void Init()
{
collection = new TextureCollection[MaxTextureCollection];
currentCollectionIndex = 0;
}
public void Update()
{
// Update
//----------------------------------------------------------------------------------
if (IsKeyPressed(KeyboardKey.R)) // Reset image collection
{
// Unload textures to avoid memory leaks
for (var i = 0; i < MaxTextureCollection; i++)
{
UnloadTexture(collection[i].Texture);
}
currentCollectionIndex = 0;
}
if (IsKeyDown(KeyboardKey.LeftControl) && IsKeyPressed(KeyboardKey.V) &&
(currentCollectionIndex < MaxTextureCollection))
{
var image = GetClipboardImage();
if (IsImageValid(image))
{
collection[currentCollectionIndex].Texture = LoadTextureFromImage(image);
collection[currentCollectionIndex].Position = GetMousePosition();
currentCollectionIndex++;
UnloadImage(image);
}
else
{
TraceLog(TraceLogLevel.Info, "IMAGE: Could not retrieve image from clipboard");
}
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
for (var i = 0; i < currentCollectionIndex; i++)
{
if (IsTextureValid(collection[i].Texture))
{
DrawTexturePro(collection[i].Texture,
new Rectangle(0, 0, collection[i].Texture.Width, collection[i].Texture.Height),
new Rectangle(collection[i].Position.X, collection[i].Position.Y, collection[i].Texture.Width, collection[i].Texture.Height),
new Vector2(collection[i].Texture.Width * 0.5f, collection[i].Texture.Height * 0.5f),
0.0f, Color.White);
}
}
DrawRectangle(0, 0, screenWidth, 40, Color.Black);
DrawText("Clipboard Image - Ctrl+V to Paste and R to Reset ", 120, 10, 20, Color.LightGray);
EndDrawing();
//----------------------------------------------------------------------------------
}
public void Unload()
{
for (var i = 0; i < MaxTextureCollection; i++)
{
UnloadTexture(collection[i].Texture);
}
}
public static int Main()
{
// Initialization
//--------------------------------------------------------------------------------------
InitWindow(screenWidth, screenHeight, "raylib [textures] example - clipboard image");
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
var game = new ClipboardImage();
game.Init();
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
game.Update();
}
game.Unload();
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
}

View file

@ -1,66 +1,85 @@
/*******************************************************************************************
*
* raylib [textures] example - Draw part of the texture tiled
* raylib [textures] example - tiled drawing
*
* This example has been created using raylib 3.0 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
* Example complexity rating: [] 3/4
*
* Copyright (c) 2020 Vlad Adrian (@demizdor) and Ramon Santamaria (@raysan5)
* Example originally created with raylib 3.0, last time updated with raylib 4.2
*
* Example contributed by Vlad Adrian (@demizdor) 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) 2020-2025 Vlad Adrian (@demizdor) and Ramon Santamaria (@raysan5)
*
********************************************************************************************/
using System.Numerics;
using static Raylib_cs.Raylib;
namespace Examples.Textures;
public class DrawTiled
public partial class DrawTiled : IExample
{
const int OptWidth = 220;
const int MarginSize = 8;
const int ColorSize = 16;
private const int OptWidth = 220;
private const int MarginSize = 8;
private const int ColorSize = 16;
public static int Main()
public string Name => "Textures / Draw Tiled";
public string Title => "raylib [textures] example - tiled drawing";
public ConfigFlags ConfigFlags => ConfigFlags.ResizableWindow;
private int screenWidth;
private int screenHeight;
private Texture2D texPattern;
// Coordinates for all patterns inside the texture
private Rectangle[] recPattern;
// Setup colors
private Color[] colors;
private Rectangle[] colorRec;
private int activePattern;
private int activeCol;
private float scale;
private float rotation;
public void Init()
{
// Initialization
//--------------------------------------------------------------------------------------
int screenWidth = 800;
int screenHeight = 450;
SetConfigFlags(ConfigFlags.ResizableWindow);
InitWindow(screenWidth, screenHeight, "raylib [textures] example - Draw part of a texture tiled");
screenWidth = 800;
screenHeight = 450;
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
Texture2D texPattern = LoadTexture("resources/patterns.png");
// Makes the texture smoother when upscaled
SetTextureFilter(texPattern, TextureFilter.Trilinear);
texPattern = LoadTexture("resources/patterns.png");
SetTextureFilter(texPattern, TextureFilter.Bilinear); // Makes the texture smoother when upscaled
// Coordinates for all patterns inside the texture
Rectangle[] recPattern = new[] {
new Rectangle(3, 3, 66, 66),
new Rectangle(75, 3, 100, 100),
new Rectangle(3, 75, 66, 66),
new Rectangle(7, 156, 50, 50),
new Rectangle(85, 106, 90, 45),
new Rectangle(75, 154, 100, 60)
};
recPattern = new[] {
new Rectangle(3, 3, 66, 66),
new Rectangle(75, 3, 100, 100),
new Rectangle(3, 75, 66, 66),
new Rectangle(7, 156, 50, 50),
new Rectangle(85, 106, 90, 45),
new Rectangle(75, 154, 100, 60)
};
// Setup colors
Color[] colors = new[]
colors = new[]
{
Color.Black,
Color.Maroon,
Color.Orange,
Color.Blue,
Color.Purple,
Color.Beige,
Color.Lime,
Color.Red,
Color.DarkGray,
Color.SkyBlue
};
Rectangle[] colorRec = new Rectangle[colors.Length];
Color.Black,
Color.Maroon,
Color.Orange,
Color.Blue,
Color.Purple,
Color.Beige,
Color.Lime,
Color.Red,
Color.DarkGray,
Color.SkyBlue
};
colorRec = new Rectangle[colors.Length];
// Calculate rectangle for each color
for (int i = 0, x = 0, y = 0; i < colors.Length; i++)
@ -81,155 +100,176 @@ public class DrawTiled
}
}
int activePattern = 0, activeCol = 0;
float scale = 1.0f, rotation = 0.0f;
activePattern = 0;
activeCol = 0;
scale = 1.0f;
rotation = 0.0f;
}
public void Update()
{
// Update
//----------------------------------------------------------------------------------
screenWidth = GetScreenWidth();
screenHeight = GetScreenHeight();
// Handle mouse
if (IsMouseButtonPressed(MouseButton.Left))
{
var mouse = GetMousePosition();
// Check which pattern was clicked and set it as the active pattern
for (var i = 0; i < recPattern.Length; i++)
{
Rectangle rec = new(
2 + MarginSize + recPattern[i].X,
40 + MarginSize + recPattern[i].Y,
recPattern[i].Width,
recPattern[i].Height
);
if (CheckCollisionPointRec(mouse, rec))
{
activePattern = i;
break;
}
}
// Check to see which color was clicked and set it as the active color
for (var i = 0; i < colors.Length; ++i)
{
if (CheckCollisionPointRec(mouse, colorRec[i]))
{
activeCol = i;
break;
}
}
}
// Handle keys: change scale
if (IsKeyPressed(KeyboardKey.Up))
{
scale += 0.25f;
}
if (IsKeyPressed(KeyboardKey.Down))
{
scale -= 0.25f;
}
if (scale > 10.0f)
{
scale = 10.0f;
}
else if (scale <= 0.0f)
{
scale = 0.25f;
}
// Handle keys: change rotation
if (IsKeyPressed(KeyboardKey.Left))
{
rotation -= 25.0f;
}
if (IsKeyPressed(KeyboardKey.Right))
{
rotation += 25.0f;
}
// Handle keys: reset
if (IsKeyPressed(KeyboardKey.Space))
{
rotation = 0.0f;
scale = 1.0f;
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
// Draw the tiled area
var source = recPattern[activePattern];
Rectangle dest = new(
OptWidth + MarginSize,
MarginSize,
screenWidth - OptWidth - 2 * MarginSize,
screenHeight - 2 * MarginSize
);
DrawTextureTiled(texPattern, source, dest, Vector2.Zero, rotation, scale, colors[activeCol]);
// Draw options
var color = ColorAlpha(Color.LightGray, 0.5f);
DrawRectangle(MarginSize, MarginSize, OptWidth - MarginSize, screenHeight - 2 * MarginSize, color);
DrawText("Select Pattern", 2 + MarginSize, 30 + MarginSize, 10, Color.Black);
DrawTexture(texPattern, 2 + MarginSize, 40 + MarginSize, Color.Black);
DrawRectangle(
2 + MarginSize + (int)recPattern[activePattern].X,
40 + MarginSize + (int)recPattern[activePattern].Y,
(int)recPattern[activePattern].Width,
(int)recPattern[activePattern].Height,
ColorAlpha(Color.DarkBlue, 0.3f)
);
DrawText("Select Color", 2 + MarginSize, 10 + 256 + MarginSize, 10, Color.Black);
for (var i = 0; i < colors.Length; i++)
{
DrawRectangleRec(colorRec[i], colors[i]);
if (activeCol == i)
{
DrawRectangleLinesEx(colorRec[i], 3, ColorAlpha(Color.White, 0.5f));
}
}
DrawText("Scale (UP/DOWN to change)", 2 + MarginSize, 80 + 256 + MarginSize, 10, Color.Black);
DrawText($"{scale:F2}x", 2 + MarginSize, 92 + 256 + MarginSize, 20, Color.Black);
DrawText("Rotation (LEFT/RIGHT to change)", 2 + MarginSize, 122 + 256 + MarginSize, 10, Color.Black);
DrawText($"{rotation:F0} degrees", 2 + MarginSize, 134 + 256 + MarginSize, 20, Color.Black);
DrawText("Press [SPACE] to reset", 2 + MarginSize, 164 + 256 + MarginSize, 10, Color.DarkBlue);
// Draw FPS
DrawText($"{GetFPS()} FPS", 2 + MarginSize, 2 + MarginSize, 20, Color.Black);
EndDrawing();
//----------------------------------------------------------------------------------
}
public void Unload()
{
UnloadTexture(texPattern); // Unload texture
}
public static int Main()
{
// Initialization
//--------------------------------------------------------------------------------------
SetConfigFlags(ConfigFlags.ResizableWindow); // Make the window resizable
InitWindow(800, 450, "raylib [textures] example - tiled drawing");
SetTargetFPS(60);
//---------------------------------------------------------------------------------------
var game = new DrawTiled();
game.Init();
// Main game loop
while (!WindowShouldClose())
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
screenWidth = GetScreenWidth();
screenHeight = GetScreenHeight();
// Handle mouse
if (IsMouseButtonPressed(MouseButton.Left))
{
Vector2 mouse = GetMousePosition();
// Check which pattern was clicked and set it as the active pattern
for (int i = 0; i < recPattern.Length; i++)
{
Rectangle rec = new(
2 + MarginSize + recPattern[i].X,
40 + MarginSize + recPattern[i].Y,
recPattern[i].Width,
recPattern[i].Height
);
if (CheckCollisionPointRec(mouse, rec))
{
activePattern = i;
break;
}
}
// Check to see which color was clicked and set it as the active color
for (int i = 0; i < colors.Length; ++i)
{
if (CheckCollisionPointRec(mouse, colorRec[i]))
{
activeCol = i;
break;
}
}
}
// Handle keys
// Change scale
if (IsKeyPressed(KeyboardKey.Up))
{
scale += 0.25f;
}
if (IsKeyPressed(KeyboardKey.Down))
{
scale -= 0.25f;
}
if (scale > 10.0f)
{
scale = 10.0f;
}
else if (scale <= 0.0f)
{
scale = 0.25f;
}
// Change rotation
if (IsKeyPressed(KeyboardKey.Left))
{
rotation -= 25.0f;
}
if (IsKeyPressed(KeyboardKey.Right))
{
rotation += 25.0f;
}
// Reset
if (IsKeyPressed(KeyboardKey.Space))
{
rotation = 0.0f;
scale = 1.0f;
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
// Draw the tiled area
Rectangle source = recPattern[activePattern];
Rectangle dest = new(
OptWidth + MarginSize,
MarginSize,
screenWidth - OptWidth - 2 * MarginSize,
screenHeight - 2 * MarginSize
);
DrawTextureTiled(texPattern, source, dest, Vector2.Zero, rotation, scale, colors[activeCol]);
// Draw options
Color color = ColorAlpha(Color.LightGray, 0.5f);
DrawRectangle(MarginSize, MarginSize, OptWidth - MarginSize, screenHeight - 2 * MarginSize, color);
DrawText("Select Pattern", 2 + MarginSize, 30 + MarginSize, 10, Color.Black);
DrawTexture(texPattern, 2 + MarginSize, 40 + MarginSize, Color.Black);
DrawRectangle(
2 + MarginSize + (int)recPattern[activePattern].X,
40 + MarginSize + (int)recPattern[activePattern].Y,
(int)recPattern[activePattern].Width,
(int)recPattern[activePattern].Height,
ColorAlpha(Color.DarkBlue, 0.3f)
);
DrawText("Select Color", 2 + MarginSize, 10 + 256 + MarginSize, 10, Color.Black);
for (int i = 0; i < colors.Length; i++)
{
DrawRectangleRec(colorRec[i], colors[i]);
if (activeCol == i)
{
DrawRectangleLinesEx(colorRec[i], 3, ColorAlpha(Color.White, 0.5f));
}
}
DrawText("Scale (UP/DOWN to change)", 2 + MarginSize, 80 + 256 + MarginSize, 10, Color.Black);
DrawText($"{scale}x", 2 + MarginSize, 92 + 256 + MarginSize, 20, Color.Black);
DrawText("Rotation (LEFT/RIGHT to change)", 2 + MarginSize, 122 + 256 + MarginSize, 10, Color.Black);
DrawText($"{rotation} degrees", 2 + MarginSize, 134 + 256 + MarginSize, 20, Color.Black);
DrawText("Press [SPACE] to reset", 2 + MarginSize, 164 + 256 + MarginSize, 10, Color.DarkBlue);
// Draw FPS
DrawText($"{GetFPS()}", 2 + MarginSize, 2 + MarginSize, 20, Color.Black);
EndDrawing();
//----------------------------------------------------------------------------------
game.Update();
}
game.Unload();
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadTexture(texPattern);
CloseWindow();
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
// Draw part of a texture (defined by a rectangle) with rotation and scale tiled into dest.
static void DrawTextureTiled(
private static void DrawTextureTiled(
Texture2D texture,
Rectangle source,
Rectangle dest,
@ -268,7 +308,7 @@ public class DrawTiled
else if (dest.Width <= tileWidth)
{
// Tiled vertically (one column)
int dy = 0;
var dy = 0;
for (; dy + tileHeight < dest.Height; dy += tileHeight)
{
DrawTexturePro(
@ -307,7 +347,7 @@ public class DrawTiled
else if (dest.Height <= tileHeight)
{
// Tiled horizontally (one row)
int dx = 0;
var dx = 0;
for (; dx + tileWidth < dest.Width; dx += tileWidth)
{
DrawTexturePro(
@ -351,10 +391,10 @@ public class DrawTiled
else
{
// Tiled both horizontally and vertically (rows and columns)
int dx = 0;
var dx = 0;
for (; dx + tileWidth < dest.Width; dx += tileWidth)
{
int dy = 0;
var dy = 0;
for (; dy + tileHeight < dest.Height; dy += tileHeight)
{
DrawTexturePro(
@ -397,7 +437,7 @@ public class DrawTiled
// Fit last column of tiles
if (dx < dest.Width)
{
int dy = 0;
var dy = 0;
for (; dy + tileHeight < dest.Height; dy += tileHeight)
{
DrawTexturePro(
@ -446,4 +486,3 @@ public class DrawTiled
}
}
}

View file

@ -0,0 +1,230 @@
/*******************************************************************************************
*
* raylib [textures] example - fog of war
*
* Example complexity rating: [] 3/4
*
* Example originally created with raylib 4.2, last time updated with raylib 4.2
*
* 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) 2018-2025 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
namespace Examples.Textures;
public partial class FogOfWar : IExample
{
private const int screenWidth = 800;
private const int screenHeight = 450;
private const int MapTileSize = 32; // Tiles size 32x32 pixels
private const int PlayerSize = 16; // Player size
private const int PlayerTileVisibility = 2; // Player can see 2 tiles around its position
public string Name => "Textures / Fog of War";
public string Title => "raylib [textures] example - fog of war";
// Map data type
private struct Map
{
public uint TilesX; // Number of tiles in X axis
public uint TilesY; // Number of tiles in Y axis
public byte[] TileIds; // Tile ids (tilesX*tilesY), defines type of tile to draw
public byte[] TileFog; // Tile fog state (tilesX*tilesY), defines if a tile has fog or half-fog
}
private Map map;
private Vector2 playerPosition;
private int playerTileX;
private int playerTileY;
private RenderTexture2D fogOfWar;
public void Init()
{
map = new Map();
map.TilesX = 25;
map.TilesY = 15;
// NOTE: We can have up to 256 values for tile ids and for tile fog state,
// probably we don't need that many values for fog state, it can be optimized
// to use only 2 bits per fog state (reducing size by 4) but logic will be a bit more complex
map.TileIds = new byte[map.TilesX * map.TilesY];
map.TileFog = new byte[map.TilesX * map.TilesY];
// Load map tiles (generating 2 random tile ids for testing)
// NOTE: Map tile ids should be probably loaded from an external map file
for (uint i = 0; i < map.TilesY * map.TilesX; i++)
{
map.TileIds[i] = (byte)GetRandomValue(0, 1);
}
// Player position on the screen (pixel coordinates, not tile coordinates)
playerPosition = new Vector2(180, 130);
playerTileX = 0;
playerTileY = 0;
// Render texture to render fog of war
// NOTE: To get an automatic smooth-fog effect we use a render texture to render fog
// at a smaller size (one pixel per tile) and scale it on drawing with bilinear filtering
fogOfWar = LoadRenderTexture((int)map.TilesX, (int)map.TilesY);
SetTextureFilter(fogOfWar.Texture, TextureFilter.Bilinear);
SetTextureWrap(fogOfWar.Texture, TextureWrap.Clamp);
}
public void Update()
{
// Update
//----------------------------------------------------------------------------------
// Move player around
if (IsKeyDown(KeyboardKey.Right))
{
playerPosition.X += 5;
}
if (IsKeyDown(KeyboardKey.Left))
{
playerPosition.X -= 5;
}
if (IsKeyDown(KeyboardKey.Down))
{
playerPosition.Y += 5;
}
if (IsKeyDown(KeyboardKey.Up))
{
playerPosition.Y -= 5;
}
// Check player position to avoid moving outside tilemap limits
if (playerPosition.X < 0)
{
playerPosition.X = 0;
}
else if ((playerPosition.X + PlayerSize) > (map.TilesX * MapTileSize))
{
playerPosition.X = (float)map.TilesX * MapTileSize - PlayerSize;
}
if (playerPosition.Y < 0)
{
playerPosition.Y = 0;
}
else if ((playerPosition.Y + PlayerSize) > (map.TilesY * MapTileSize))
{
playerPosition.Y = (float)map.TilesY * MapTileSize - PlayerSize;
}
// Previous visited tiles are set to partial fog
for (uint i = 0; i < map.TilesX * map.TilesY; i++)
{
if (map.TileFog[i] == 1)
{
map.TileFog[i] = 2;
}
}
// Get current tile position from player pixel position
playerTileX = (int)((playerPosition.X + (float)MapTileSize / 2) / MapTileSize);
playerTileY = (int)((playerPosition.Y + (float)MapTileSize / 2) / MapTileSize);
// Check visibility and update fog
// NOTE: We check tilemap limits to avoid processing tiles out-of-array-bounds (it could crash program)
for (var y = (playerTileY - PlayerTileVisibility); y < (playerTileY + PlayerTileVisibility); y++)
{
for (var x = (playerTileX - PlayerTileVisibility); x < (playerTileX + PlayerTileVisibility); x++)
{
if ((x >= 0) && (x < (int)map.TilesX) && (y >= 0) && (y < (int)map.TilesY))
{
map.TileFog[y * map.TilesX + x] = 1;
}
}
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
// Draw fog of war to a small render texture for automatic smoothing on scaling
BeginTextureMode(fogOfWar);
ClearBackground(Color.Blank);
for (uint y = 0; y < map.TilesY; y++)
{
for (uint x = 0; x < map.TilesX; x++)
{
if (map.TileFog[y * map.TilesX + x] == 0)
{
DrawRectangle((int)x, (int)y, 1, 1, Color.Black);
}
else if (map.TileFog[y * map.TilesX + x] == 2)
{
DrawRectangle((int)x, (int)y, 1, 1, Fade(Color.Black, 0.8f));
}
}
}
EndTextureMode();
BeginDrawing();
ClearBackground(Color.RayWhite);
for (uint y = 0; y < map.TilesY; y++)
{
for (uint x = 0; x < map.TilesX; x++)
{
// Draw tiles from id (and tile borders)
DrawRectangle((int)x * MapTileSize, (int)y * MapTileSize, MapTileSize, MapTileSize,
(map.TileIds[y * map.TilesX + x] == 0) ? Color.Blue : Fade(Color.Blue, 0.9f));
DrawRectangleLines((int)x * MapTileSize, (int)y * MapTileSize, MapTileSize, MapTileSize, Fade(Color.DarkBlue, 0.5f));
}
}
// Draw player
DrawRectangleV(playerPosition, new Vector2(PlayerSize, PlayerSize), Color.Red);
// Draw fog of war (scaled to full map, bilinear filtering)
DrawTexturePro(fogOfWar.Texture,
new Rectangle(0, 0, (float)fogOfWar.Texture.Width, (float)-fogOfWar.Texture.Height),
new Rectangle(0, 0, (float)map.TilesX * MapTileSize, (float)map.TilesY * MapTileSize),
new Vector2(0, 0), 0.0f, Color.White);
// Draw player current tile
DrawText($"Current tile: [{playerTileX},{playerTileY}]", 10, 10, 20, Color.RayWhite);
DrawText("ARROW KEYS to move", 10, screenHeight - 25, 20, Color.RayWhite);
EndDrawing();
//----------------------------------------------------------------------------------
}
public void Unload()
{
UnloadRenderTexture(fogOfWar); // Unload render texture
}
public static int Main()
{
// Initialization
//--------------------------------------------------------------------------------------
InitWindow(screenWidth, screenHeight, "raylib [textures] example - fog of war");
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
var game = new FogOfWar();
game.Init();
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
game.Update();
}
game.Unload();
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
}

View file

@ -0,0 +1,246 @@
/*******************************************************************************************
*
* raylib [textures] example - framebuffer rendering
*
* Example complexity rating: [] 2/4
*
* Example originally created with raylib 5.6, last time updated with raylib 5.6
*
* Example contributed by Jack Boakes (@jackboakes) 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) 2026 Jack Boakes (@jackboakes)
*
********************************************************************************************/
using static Raylib_cs.Raymath;
namespace Examples.Textures;
public partial class FramebufferRendering : IExample
{
private const int screenWidth = 800;
private const int screenHeight = 450;
private const int splitWidth = screenWidth / 2;
public string Name => "Textures / Framebuffer Rendering";
public string Title => "raylib [textures] example - framebuffer rendering";
public bool CursorDisabled => true;
private Camera3D subjectCamera;
private Camera3D observerCamera;
private RenderTexture2D observerTarget;
private Rectangle observerSource;
private Rectangle observerDest;
private RenderTexture2D subjectTarget;
private Rectangle subjectSource;
private Rectangle subjectDest;
private float textureAspectRatio;
private const float captureSize = 128.0f;
private Rectangle cropSource;
private Rectangle cropDest;
public void Init()
{
// Camera to look at the 3D world
subjectCamera = new Camera3D();
subjectCamera.Position = new Vector3(5.0f, 5.0f, 5.0f);
subjectCamera.Target = new Vector3(0.0f, 0.0f, 0.0f);
subjectCamera.Up = new Vector3(0.0f, 1.0f, 0.0f);
subjectCamera.FovY = 45.0f;
subjectCamera.Projection = CameraProjection.Perspective;
// Camera to observe the subject camera and 3D world
observerCamera = new Camera3D();
observerCamera.Position = new Vector3(10.0f, 10.0f, 10.0f);
observerCamera.Target = new Vector3(0.0f, 0.0f, 0.0f);
observerCamera.Up = new Vector3(0.0f, 1.0f, 0.0f);
observerCamera.FovY = 45.0f;
observerCamera.Projection = CameraProjection.Perspective;
// Set up render textures
observerTarget = LoadRenderTexture(splitWidth, screenHeight);
observerSource = new Rectangle(0.0f, 0.0f, observerTarget.Texture.Width, -observerTarget.Texture.Height);
observerDest = new Rectangle(0.0f, 0.0f, splitWidth, screenHeight);
subjectTarget = LoadRenderTexture(splitWidth, screenHeight);
subjectSource = new Rectangle(0.0f, 0.0f, subjectTarget.Texture.Width, -subjectTarget.Texture.Height);
subjectDest = new Rectangle(splitWidth, 0.0f, splitWidth, screenHeight);
textureAspectRatio = (float)subjectTarget.Texture.Width / subjectTarget.Texture.Height;
// Rectangles for cropping render texture
cropSource = new Rectangle((subjectTarget.Texture.Width - captureSize) / 2.0f, (subjectTarget.Texture.Height - captureSize) / 2.0f, captureSize, -captureSize);
cropDest = new Rectangle(splitWidth + 20.0f, 20.0f, captureSize, captureSize);
}
public void Update()
{
// Update
//----------------------------------------------------------------------------------
UpdateCamera(ref observerCamera, CameraMode.Free);
UpdateCamera(ref subjectCamera, CameraMode.Orbital);
if (IsKeyPressed(KeyboardKey.R))
{
observerCamera.Target = new Vector3(0.0f, 0.0f, 0.0f);
}
// Build LHS observer view texture
BeginTextureMode(observerTarget);
ClearBackground(Color.RayWhite);
BeginMode3D(observerCamera);
DrawGrid(10, 1.0f);
DrawCube(new Vector3(0.0f, 0.0f, 0.0f), 2.0f, 2.0f, 2.0f, Color.Gold);
DrawCubeWires(new Vector3(0.0f, 0.0f, 0.0f), 2.0f, 2.0f, 2.0f, Color.Pink);
DrawCameraPrism(subjectCamera, textureAspectRatio, Color.Green);
EndMode3D();
DrawText("Observer View", 10, observerTarget.Texture.Height - 30, 20, Color.Black);
DrawText("WASD + Mouse to Move", 10, 10, 20, Color.DarkGray);
DrawText("Scroll to Zoom", 10, 30, 20, Color.DarkGray);
DrawText("R to Reset Observer Target", 10, 50, 20, Color.DarkGray);
EndTextureMode();
// Build RHS subject view texture
BeginTextureMode(subjectTarget);
ClearBackground(Color.RayWhite);
BeginMode3D(subjectCamera);
DrawCube(new Vector3(0.0f, 0.0f, 0.0f), 2.0f, 2.0f, 2.0f, Color.Gold);
DrawCubeWires(new Vector3(0.0f, 0.0f, 0.0f), 2.0f, 2.0f, 2.0f, Color.Pink);
DrawGrid(10, 1.0f);
EndMode3D();
DrawRectangleLines((int)((subjectTarget.Texture.Width - captureSize) / 2.0f), (int)((subjectTarget.Texture.Height - captureSize) / 2.0f), (int)captureSize, (int)captureSize, Color.Green);
DrawText("Subject View", 10, subjectTarget.Texture.Height - 30, 20, Color.Black);
EndTextureMode();
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.Black);
// Draw observer texture LHS
DrawTexturePro(observerTarget.Texture, observerSource, observerDest, new Vector2(0.0f, 0.0f), 0.0f, Color.White);
// Draw subject texture RHS
DrawTexturePro(subjectTarget.Texture, subjectSource, subjectDest, new Vector2(0.0f, 0.0f), 0.0f, Color.White);
// Draw the small crop overlay on top
DrawTexturePro(subjectTarget.Texture, cropSource, cropDest, new Vector2(0.0f, 0.0f), 0.0f, Color.White);
DrawRectangleLinesEx(cropDest, 2, Color.Black);
// Draw split screen divider line
DrawLine(splitWidth, 0, splitWidth, screenHeight, Color.Black);
EndDrawing();
//----------------------------------------------------------------------------------
}
public void Unload()
{
UnloadRenderTexture(observerTarget);
UnloadRenderTexture(subjectTarget);
}
//----------------------------------------------------------------------------------
// Module Functions Definition
//----------------------------------------------------------------------------------
private static void DrawCameraPrism(Camera3D camera, float aspect, Color color)
{
float length = Vector3Distance(camera.Position, camera.Target);
// Define the 4 corners of the camera's prism plane sliced at the target in Normalized Device Coordinates
Vector3[] planeNDC =
{
new(-1.0f, -1.0f, 1.0f), // Bottom Left
new( 1.0f, -1.0f, 1.0f), // Bottom Right
new( 1.0f, 1.0f, 1.0f), // Top Right
new(-1.0f, 1.0f, 1.0f) // Top Left
};
// Build the matrices
Matrix4x4 view = GetCameraMatrix(camera);
Matrix4x4 proj = MatrixPerspective(camera.FovY * DEG2RAD, aspect, 0.05f, length);
// Combine view and projection so we can reverse the full camera transform
Matrix4x4 viewProj = MatrixMultiply(view, proj);
// Invert the view-projection matrix to unproject points from NDC space back into world space
Matrix4x4 inverseViewProj = MatrixInvert(viewProj);
// Transform the 4 plane corners from NDC into world space
Vector3[] corners = new Vector3[4];
for (int i = 0; i < 4; i++)
{
float x = planeNDC[i].X;
float y = planeNDC[i].Y;
float z = planeNDC[i].Z;
// Multiply NDC position by the inverse view-projection matrix
// This produces a homogeneous (x, y, z, w) position in world space
float vx = inverseViewProj.M11 * x + inverseViewProj.M12 * y + inverseViewProj.M13 * z + inverseViewProj.M14;
float vy = inverseViewProj.M21 * x + inverseViewProj.M22 * y + inverseViewProj.M23 * z + inverseViewProj.M24;
float vz = inverseViewProj.M31 * x + inverseViewProj.M32 * y + inverseViewProj.M33 * z + inverseViewProj.M34;
float vw = inverseViewProj.M41 * x + inverseViewProj.M42 * y + inverseViewProj.M43 * z + inverseViewProj.M44;
corners[i] = new Vector3(vx / vw, vy / vw, vz / vw);
}
// Draw the far plane sliced at the target
DrawLine3D(corners[0], corners[1], color);
DrawLine3D(corners[1], corners[2], color);
DrawLine3D(corners[2], corners[3], color);
DrawLine3D(corners[3], corners[0], color);
// Draw the prism lines from the far plane to the camera position
for (int i = 0; i < 4; i++)
{
DrawLine3D(camera.Position, corners[i], color);
}
}
public static int Main()
{
// Initialization
//--------------------------------------------------------------------------------------
InitWindow(screenWidth, screenHeight, "raylib [textures] example - framebuffer rendering");
SetTargetFPS(60);
DisableCursor();
//--------------------------------------------------------------------------------------
var game = new FramebufferRendering();
game.Init();
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
game.Update();
}
game.Unload();
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
}

View file

@ -0,0 +1,169 @@
/*******************************************************************************************
*
* raylib [textures] example - gif player
*
* Example complexity rating: [] 3/4
*
* Example originally created with raylib 4.2, last time updated with raylib 4.2
*
* 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) 2021-2025 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
namespace Examples.Textures;
public partial class GifPlayer : IExample
{
private const int screenWidth = 800;
private const int screenHeight = 450;
private const int MaxFrameDelay = 20;
private const int MinFrameDelay = 1;
public string Name => "Textures / Gif Player";
public string Title => "raylib [textures] example - gif player";
private int animFrames;
private Image imScarfyAnim;
private Texture2D texScarfyAnim;
private uint nextFrameDataOffset; // Current byte offset to next frame in image.data
private int currentAnimFrame; // Current animation frame to load and draw
private int frameDelay; // Frame delay to switch between animation frames
private int frameCounter; // General frames counter
public void Init()
{
animFrames = 0;
// Load all GIF animation frames into a single Image
// NOTE: GIF data is always loaded as RGBA (32bit) by default
// NOTE: Frames are just appended one after another in image.data memory
imScarfyAnim = LoadImageAnim("resources/scarfy_run.gif", out animFrames);
// Load texture from image
// NOTE: We will update this texture when required with next frame data
// WARNING: It's not recommended to use this technique for sprites animation,
// use spritesheets instead, like illustrated in textures_sprite_anim example
texScarfyAnim = LoadTextureFromImage(imScarfyAnim);
nextFrameDataOffset = 0;
currentAnimFrame = 0;
frameDelay = 8;
frameCounter = 0;
}
public unsafe void Update()
{
// Update
//----------------------------------------------------------------------------------
frameCounter++;
if (frameCounter >= frameDelay)
{
// Move to next frame
// NOTE: If final frame is reached we return to first frame
currentAnimFrame++;
if (currentAnimFrame >= animFrames)
{
currentAnimFrame = 0;
}
// Get memory offset position for next frame data in image.data
nextFrameDataOffset = (uint)(imScarfyAnim.Width * imScarfyAnim.Height * 4 * currentAnimFrame);
// Update GPU texture data with next frame image data
// WARNING: Data size (frame size) and pixel format must match already created texture
UpdateTexture(texScarfyAnim, (byte*)imScarfyAnim.Data + nextFrameDataOffset);
frameCounter = 0;
}
// Control frames delay
if (IsKeyPressed(KeyboardKey.Right))
{
frameDelay++;
}
else if (IsKeyPressed(KeyboardKey.Left))
{
frameDelay--;
}
if (frameDelay > MaxFrameDelay)
{
frameDelay = MaxFrameDelay;
}
else if (frameDelay < MinFrameDelay)
{
frameDelay = MinFrameDelay;
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
DrawText($"TOTAL GIF FRAMES: {animFrames:D2}", 50, 30, 20, Color.LightGray);
DrawText($"CURRENT FRAME: {currentAnimFrame:D2}", 50, 60, 20, Color.Gray);
DrawText($"CURRENT FRAME IMAGE.DATA OFFSET: {nextFrameDataOffset:D2}", 50, 90, 20, Color.Gray);
DrawText("FRAMES DELAY: ", 100, 305, 10, Color.DarkGray);
DrawText($"{frameDelay:D2} frames", 620, 305, 10, Color.DarkGray);
DrawText("PRESS RIGHT/LEFT KEYS to CHANGE SPEED!", 290, 350, 10, Color.DarkGray);
for (var i = 0; i < MaxFrameDelay; i++)
{
if (i < frameDelay)
{
DrawRectangle(190 + 21 * i, 300, 20, 20, Color.Red);
}
DrawRectangleLines(190 + 21 * i, 300, 20, 20, Color.Maroon);
}
DrawTexture(texScarfyAnim, GetScreenWidth() / 2 - texScarfyAnim.Width / 2, 140, Color.White);
DrawText("(c) Scarfy sprite by Eiden Marsal", screenWidth - 200, screenHeight - 20, 10, Color.Gray);
EndDrawing();
//----------------------------------------------------------------------------------
}
public void Unload()
{
UnloadTexture(texScarfyAnim); // Unload texture
UnloadImage(imScarfyAnim); // Unload image (contains all frames)
}
public static int Main()
{
// Initialization
//--------------------------------------------------------------------------------------
InitWindow(screenWidth, screenHeight, "raylib [textures] example - gif player");
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
var game = new GifPlayer();
game.Init();
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
game.Update();
}
game.Unload();
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
}

View file

@ -0,0 +1,146 @@
/*******************************************************************************************
*
* raylib [textures] example - image channel
*
* NOTE: Images are loaded in CPU memory (RAM); textures are loaded in GPU memory (VRAM)
*
* Example complexity rating: [] 2/4
*
* Example originally created with raylib 5.5, last time updated with raylib 5.5
*
* Example contributed by Bruno Cabral (@brccabral) 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) 2024-2025 Bruno Cabral (@brccabral) and Ramon Santamaria (@raysan5)
*
********************************************************************************************/
namespace Examples.Textures;
public partial class ImageChannel : IExample
{
private const int screenWidth = 800;
private const int screenHeight = 450;
public string Name => "Textures / Image Channel";
public string Title => "raylib [textures] example - image channel";
private Texture2D fudesumiTexture;
private Texture2D textureAlpha;
private Texture2D textureRed;
private Texture2D textureGreen;
private Texture2D textureBlue;
private Texture2D backgroundTexture;
private Rectangle fudesumiRec;
private Rectangle fudesumiPos;
private Rectangle redPos;
private Rectangle greenPos;
private Rectangle bluePos;
private Rectangle alphaPos;
public void Init()
{
var fudesumiImage = LoadImage("resources/fudesumi.png");
var imageAlpha = ImageFromChannel(fudesumiImage, 3);
ImageAlphaMask(ref imageAlpha, imageAlpha);
var imageRed = ImageFromChannel(fudesumiImage, 0);
ImageAlphaMask(ref imageRed, imageAlpha);
var imageGreen = ImageFromChannel(fudesumiImage, 1);
ImageAlphaMask(ref imageGreen, imageAlpha);
var imageBlue = ImageFromChannel(fudesumiImage, 2);
ImageAlphaMask(ref imageBlue, imageAlpha);
var backgroundImage = GenImageChecked(screenWidth, screenHeight, screenWidth / 20, screenHeight / 20, Color.Orange, Color.Yellow);
fudesumiTexture = LoadTextureFromImage(fudesumiImage);
textureAlpha = LoadTextureFromImage(imageAlpha);
textureRed = LoadTextureFromImage(imageRed);
textureGreen = LoadTextureFromImage(imageGreen);
textureBlue = LoadTextureFromImage(imageBlue);
backgroundTexture = LoadTextureFromImage(backgroundImage);
fudesumiRec = new Rectangle(0, 0, fudesumiImage.Width, fudesumiImage.Height);
fudesumiPos = new Rectangle(50, 10, fudesumiImage.Width * 0.8f, fudesumiImage.Height * 0.8f);
redPos = new Rectangle(410, 10, fudesumiPos.Width / 2.0f, fudesumiPos.Height / 2.0f);
greenPos = new Rectangle(600, 10, fudesumiPos.Width / 2.0f, fudesumiPos.Height / 2.0f);
bluePos = new Rectangle(410, 230, fudesumiPos.Width / 2.0f, fudesumiPos.Height / 2.0f);
alphaPos = new Rectangle(600, 230, fudesumiPos.Width / 2.0f, fudesumiPos.Height / 2.0f);
UnloadImage(fudesumiImage);
UnloadImage(imageAlpha);
UnloadImage(imageRed);
UnloadImage(imageGreen);
UnloadImage(imageBlue);
UnloadImage(backgroundImage);
}
public void Update()
{
// Update
//----------------------------------------------------------------------------------
// Nothing to update...
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
DrawTexture(backgroundTexture, 0, 0, Color.White);
DrawTexturePro(fudesumiTexture, fudesumiRec, fudesumiPos, new Vector2(0, 0), 0, Color.White);
DrawTexturePro(textureRed, fudesumiRec, redPos, new Vector2(0, 0), 0, Color.Red);
DrawTexturePro(textureGreen, fudesumiRec, greenPos, new Vector2(0, 0), 0, Color.Green);
DrawTexturePro(textureBlue, fudesumiRec, bluePos, new Vector2(0, 0), 0, Color.Blue);
DrawTexturePro(textureAlpha, fudesumiRec, alphaPos, new Vector2(0, 0), 0, Color.White);
EndDrawing();
//----------------------------------------------------------------------------------
}
public void Unload()
{
UnloadTexture(backgroundTexture);
UnloadTexture(fudesumiTexture);
UnloadTexture(textureRed);
UnloadTexture(textureGreen);
UnloadTexture(textureBlue);
UnloadTexture(textureAlpha);
}
public static int Main()
{
// Initialization
//--------------------------------------------------------------------------------------
InitWindow(screenWidth, screenHeight, "raylib [textures] example - image channel");
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
var game = new ImageChannel();
game.Init();
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
game.Update();
}
game.Unload();
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
}

View file

@ -1,100 +1,115 @@
/*******************************************************************************************
*
* raylib [textures] example - Image loading and drawing on it
* raylib [textures] example - image drawing
*
* Example complexity rating: [] 2/4
*
* NOTE: Images are loaded in CPU memory (RAM); textures are loaded in GPU memory (VRAM)
*
* This example has been created using raylib 1.4 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
* Example originally created with raylib 1.4, last time updated with raylib 1.4
*
* Copyright (c) 2016 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) 2016-2025 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
using System.Numerics;
using static Raylib_cs.Raylib;
namespace Examples.Textures;
public class ImageDrawing
public partial class ImageDrawing : IExample
{
public static int Main()
private const int screenWidth = 800;
private const int screenHeight = 450;
public string Name => "Textures / Image Drawing";
public string Title => "raylib [textures] example - image drawing";
private Texture2D texture;
public void Init()
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [textures] example - image drawing");
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
Image cat = LoadImage("resources/cat.png");
ImageCrop(ref cat, new Rectangle(100, 10, 280, 380));
ImageFlipHorizontal(ref cat);
ImageResize(ref cat, 150, 200);
var cat = LoadImage("resources/cat.png"); // Load image in CPU memory (RAM)
ImageCrop(ref cat, new Rectangle(100, 10, 280, 380)); // Crop an image piece
ImageFlipHorizontal(ref cat); // Flip cropped image horizontally
ImageResize(ref cat, 150, 200); // Resize flipped-cropped image
Image parrots = LoadImage("resources/parrots.png");
var parrots = LoadImage("resources/parrots.png"); // Load image in CPU memory (RAM)
// Draw one image over the other with a scaling of 1.5f
Rectangle src = new(0, 0, cat.Width, cat.Height);
ImageDraw(ref parrots, cat, src, new Rectangle(30, 40, cat.Width * 1.5f, cat.Height * 1.5f), Color.White);
ImageCrop(ref parrots, new Rectangle(0, 50, parrots.Width, parrots.Height - 100));
ImageCrop(ref parrots, new Rectangle(0, 50, parrots.Width, parrots.Height - 100)); // Crop resulting image
// Draw on the image with a few image draw methods
ImageDrawPixel(ref parrots, 10, 10, Color.RayWhite);
ImageDrawCircle(ref parrots, 10, 10, 5, Color.RayWhite);
ImageDrawCircleLines(ref parrots, 10, 10, 5, Color.RayWhite);
ImageDrawRectangle(ref parrots, 5, 20, 10, 10, Color.RayWhite);
UnloadImage(cat);
UnloadImage(cat); // Unload image from RAM
// Load custom font for frawing on image
Font font = LoadFont("resources/fonts/custom_jupiter_crash.png");
// Load custom font for drawing on image
var font = LoadFont("resources/custom_jupiter_crash.png");
// Draw over image using custom font
ImageDrawTextEx(ref parrots, font, "PARROTS & CAT", new Vector2(300, 230), font.BaseSize, -2, Color.White);
// Unload custom spritefont (already drawn used on image)
UnloadFont(font);
UnloadFont(font); // Unload custom font (already drawn used on image)
Texture2D texture = LoadTextureFromImage(parrots);
UnloadImage(parrots);
texture = LoadTextureFromImage(parrots); // Image converted to texture, uploaded to GPU memory (VRAM)
UnloadImage(parrots); // Once image has been converted to texture and uploaded to VRAM, it can be unloaded from RAM
}
public void Update()
{
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
var x = screenWidth / 2 - texture.Width / 2;
var y = screenHeight / 2 - texture.Height / 2;
DrawTexture(texture, x, y - 40, Color.White);
DrawRectangleLines(x, y - 40, texture.Width, texture.Height, Color.DarkGray);
DrawText("We are drawing only one texture from various images composed!", 240, 350, 10, Color.DarkGray);
DrawText("Source images have been cropped, scaled, flipped and copied one over the other.", 190, 370, 10, Color.DarkGray);
EndDrawing();
//----------------------------------------------------------------------------------
}
public void Unload()
{
UnloadTexture(texture); // Texture unloading
}
public static int Main()
{
// Initialization
//--------------------------------------------------------------------------------------
InitWindow(screenWidth, screenHeight, "raylib [textures] example - image drawing");
SetTargetFPS(60);
//---------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
var game = new ImageDrawing();
game.Init();
// Main game loop
while (!WindowShouldClose())
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
// TODO: Update your variables here
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
int x = screenWidth / 2 - texture.Width / 2;
int y = screenHeight / 2 - texture.Height / 2;
DrawTexture(texture, x, y - 40, Color.White);
DrawRectangleLines(x, y - 40, texture.Width, texture.Height, Color.DarkGray);
DrawText("We are drawing only one texture from various images composed!", 240, 350, 10, Color.DarkGray);
string text = "Source images have been cropped, scaled, flipped and copied one over the other.";
DrawText(text, 90, 370, 10, Color.DarkGray);
EndDrawing();
//----------------------------------------------------------------------------------
game.Update();
}
game.Unload();
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadTexture(texture);
CloseWindow();
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;

View file

@ -1,116 +1,163 @@
/*******************************************************************************************
*
* raylib [textures] example - Procedural images generation
* raylib [textures] example - image generation
*
* This example has been created using raylib 1.8 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
* Example complexity rating: [] 2/4
*
* Copyright (c) 2O17 Wilhem Barbier (@nounoursheureux)
* Example originally created with raylib 1.8, last time updated with raylib 1.8
*
* Example contributed by Wilhem Barbier (@nounoursheureux) 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) 2017-2025 Wilhem Barbier (@nounoursheureux) and Ramon Santamaria (@raysan5)
*
********************************************************************************************/
using static Raylib_cs.Raylib;
namespace Examples.Textures;
public class ImageGeneration
public partial class ImageGeneration : IExample
{
public const int NumTextures = 6;
private const int screenWidth = 800;
private const int screenHeight = 450;
// Currently we have 8 generation algorithms but some have multiple purposes (Linear and Square Gradients)
public const int NumTextures = 9;
public string Name => "Textures / Image Generation";
public string Title => "raylib [textures] example - image generation";
private Texture2D[] textures;
private int currentTexture;
public void Init()
{
var verticalGradient = GenImageGradientLinear(screenWidth, screenHeight, 0, Color.Red, Color.Blue);
var horizontalGradient = GenImageGradientLinear(screenWidth, screenHeight, 90, Color.Red, Color.Blue);
var diagonalGradient = GenImageGradientLinear(screenWidth, screenHeight, 45, Color.Red, Color.Blue);
var radialGradient = GenImageGradientRadial(screenWidth, screenHeight, 0.0f, Color.White, Color.Black);
var squareGradient = GenImageGradientSquare(screenWidth, screenHeight, 0.0f, Color.White, Color.Black);
var isChecked = GenImageChecked(screenWidth, screenHeight, 32, 32, Color.Red, Color.Blue);
var whiteNoise = GenImageWhiteNoise(screenWidth, screenHeight, 0.5f);
var perlinNoise = GenImagePerlinNoise(screenWidth, screenHeight, 50, 50, 4.0f);
var cellular = GenImageCellular(screenWidth, screenHeight, 32);
textures = new Texture2D[NumTextures];
textures[0] = LoadTextureFromImage(verticalGradient);
textures[1] = LoadTextureFromImage(horizontalGradient);
textures[2] = LoadTextureFromImage(diagonalGradient);
textures[3] = LoadTextureFromImage(radialGradient);
textures[4] = LoadTextureFromImage(squareGradient);
textures[5] = LoadTextureFromImage(isChecked);
textures[6] = LoadTextureFromImage(whiteNoise);
textures[7] = LoadTextureFromImage(perlinNoise);
textures[8] = LoadTextureFromImage(cellular);
// Unload image data (CPU RAM)
UnloadImage(verticalGradient);
UnloadImage(horizontalGradient);
UnloadImage(diagonalGradient);
UnloadImage(radialGradient);
UnloadImage(squareGradient);
UnloadImage(isChecked);
UnloadImage(whiteNoise);
UnloadImage(perlinNoise);
UnloadImage(cellular);
currentTexture = 0;
}
public void Update()
{
// Update
//----------------------------------------------------------------------------------
if (IsMouseButtonPressed(MouseButton.Left) || IsKeyPressed(KeyboardKey.Right))
{
// Cycle between the textures
currentTexture = (currentTexture + 1) % NumTextures;
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
DrawTexture(textures[currentTexture], 0, 0, Color.White);
DrawRectangle(30, 400, 325, 30, Fade(Color.SkyBlue, 0.5f));
DrawRectangleLines(30, 400, 325, 30, Fade(Color.White, 0.5f));
DrawText("MOUSE LEFT BUTTON to CYCLE PROCEDURAL TEXTURES", 40, 410, 10, Color.White);
switch (currentTexture)
{
case 0:
DrawText("VERTICAL GRADIENT", 560, 10, 20, Color.RayWhite);
break;
case 1:
DrawText("HORIZONTAL GRADIENT", 540, 10, 20, Color.RayWhite);
break;
case 2:
DrawText("DIAGONAL GRADIENT", 540, 10, 20, Color.RayWhite);
break;
case 3:
DrawText("RADIAL GRADIENT", 580, 10, 20, Color.LightGray);
break;
case 4:
DrawText("SQUARE GRADIENT", 580, 10, 20, Color.LightGray);
break;
case 5:
DrawText("CHECKED", 680, 10, 20, Color.RayWhite);
break;
case 6:
DrawText("WHITE NOISE", 640, 10, 20, Color.Red);
break;
case 7:
DrawText("PERLIN NOISE", 640, 10, 20, Color.Red);
break;
case 8:
DrawText("CELLULAR", 670, 10, 20, Color.RayWhite);
break;
default:
break;
}
EndDrawing();
//----------------------------------------------------------------------------------
}
public void Unload()
{
for (var i = 0; i < textures.Length; i++)
{
UnloadTexture(textures[i]);
}
}
public static int Main()
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [textures] example - procedural images generation");
Image verticalGradient = GenImageGradientLinear(screenWidth, screenHeight, 0, Color.Red, Color.Blue);
Image horizontalGradient = GenImageGradientLinear(screenWidth, screenHeight, 90, Color.Red, Color.Blue);
Image radialGradient = GenImageGradientRadial(screenWidth, screenHeight, 0.0f, Color.White, Color.Black);
Image isChecked = GenImageChecked(screenWidth, screenHeight, 32, 32, Color.Red, Color.Blue);
Image whiteNoise = GenImageWhiteNoise(screenWidth, screenHeight, 0.5f);
Image cellular = GenImageCellular(screenWidth, screenHeight, 32);
Texture2D[] textures = new Texture2D[NumTextures];
textures[0] = LoadTextureFromImage(verticalGradient);
textures[1] = LoadTextureFromImage(horizontalGradient);
textures[2] = LoadTextureFromImage(radialGradient);
textures[3] = LoadTextureFromImage(isChecked);
textures[4] = LoadTextureFromImage(whiteNoise);
textures[5] = LoadTextureFromImage(cellular);
UnloadImage(verticalGradient);
UnloadImage(horizontalGradient);
UnloadImage(radialGradient);
UnloadImage(isChecked);
UnloadImage(whiteNoise);
UnloadImage(cellular);
int currentTexture = 0;
InitWindow(screenWidth, screenHeight, "raylib [textures] example - image generation");
SetTargetFPS(60);
//---------------------------------------------------------------------------------------
var game = new ImageGeneration();
game.Init();
// Main game loop
while (!WindowShouldClose())
{
// Update
//----------------------------------------------------------------------------------
if (IsMouseButtonPressed(MouseButton.Left) || IsKeyPressed(KeyboardKey.Right))
{
// Cycle between the textures
currentTexture = (currentTexture + 1) % NumTextures;
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
DrawTexture(textures[currentTexture], 0, 0, Color.White);
DrawRectangle(30, 400, 325, 30, ColorAlpha(Color.SkyBlue, 0.5f));
DrawRectangleLines(30, 400, 325, 30, ColorAlpha(Color.White, 0.5f));
DrawText("MOUSE LEFT BUTTON to CYCLE PROCEDURAL TEXTURES", 40, 410, 10, Color.White);
switch (currentTexture)
{
case 0:
DrawText("VERTICAL GRADIENT", 560, 10, 20, Color.RayWhite);
break;
case 1:
DrawText("HORIZONTAL GRADIENT", 540, 10, 20, Color.RayWhite);
break;
case 2:
DrawText("RADIAL GRADIENT", 580, 10, 20, Color.LightGray);
break;
case 3:
DrawText("CHECKED", 680, 10, 20, Color.RayWhite);
break;
case 4:
DrawText("Color.WHITE NOISE", 640, 10, 20, Color.Red);
break;
case 5:
DrawText("CELLULAR", 670, 10, 20, Color.RayWhite);
break;
default:
break;
}
EndDrawing();
//----------------------------------------------------------------------------------
game.Update();
}
game.Unload();
// De-Initialization
//--------------------------------------------------------------------------------------
for (int i = 0; i < textures.Length; i++)
{
UnloadTexture(textures[i]);
}
CloseWindow();
//--------------------------------------------------------------------------------------

View file

@ -0,0 +1,163 @@
/*******************************************************************************************
*
* raylib [textures] example - image kernel
*
* Example complexity rating: [] 4/4
*
* NOTE: Images are loaded in CPU memory (RAM); textures are loaded in GPU memory (VRAM)
*
* Example contributed by Karim Salem (@kimo-s) and reviewed by Ramon Santamaria (@raysan5)
*
* Example originally created with raylib 1.3, last time updated with raylib 1.3
*
* 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) 2015-2025 Karim Salem (@kimo-s)
*
********************************************************************************************/
namespace Examples.Textures;
public partial class ImageKernel : IExample
{
private const int screenWidth = 800;
private const int screenHeight = 450;
public string Name => "Textures / Image Kernel";
public string Title => "raylib [textures] example - image kernel";
private Texture2D texture;
private Texture2D catSharpendTexture;
private Texture2D catSobelTexture;
private Texture2D catGaussianTexture;
private static void NormalizeKernel(float[] kernel, int size)
{
var sum = 0.0f;
for (var i = 0; i < size; i++)
{
sum += kernel[i];
}
if (sum != 0.0f)
{
for (var i = 0; i < size; i++)
{
kernel[i] /= sum;
}
}
}
public void Init()
{
var image = LoadImage("resources/cat.png"); // Loaded in CPU memory (RAM)
float[] gaussiankernel = {
1.0f, 2.0f, 1.0f,
2.0f, 4.0f, 2.0f,
1.0f, 2.0f, 1.0f
};
float[] sobelkernel = {
1.0f, 0.0f, -1.0f,
2.0f, 0.0f, -2.0f,
1.0f, 0.0f, -1.0f
};
float[] sharpenkernel = {
0.0f, -1.0f, 0.0f,
-1.0f, 5.0f, -1.0f,
0.0f, -1.0f, 0.0f
};
NormalizeKernel(gaussiankernel, 9);
NormalizeKernel(sharpenkernel, 9);
NormalizeKernel(sobelkernel, 9);
var catSharpend = ImageCopy(image);
ImageKernelConvolution(ref catSharpend, sharpenkernel);
var catSobel = ImageCopy(image);
ImageKernelConvolution(ref catSobel, sobelkernel);
var catGaussian = ImageCopy(image);
for (var i = 0; i < 6; i++)
{
ImageKernelConvolution(ref catGaussian, gaussiankernel);
}
ImageCrop(ref image, new Rectangle(0, 0, 200, 450));
ImageCrop(ref catGaussian, new Rectangle(0, 0, 200, 450));
ImageCrop(ref catSobel, new Rectangle(0, 0, 200, 450));
ImageCrop(ref catSharpend, new Rectangle(0, 0, 200, 450));
// Images converted to texture, GPU memory (VRAM)
texture = LoadTextureFromImage(image);
catSharpendTexture = LoadTextureFromImage(catSharpend);
catSobelTexture = LoadTextureFromImage(catSobel);
catGaussianTexture = LoadTextureFromImage(catGaussian);
// Once images have been converted to texture and uploaded to VRAM,
// they can be unloaded from RAM
UnloadImage(image);
UnloadImage(catGaussian);
UnloadImage(catSobel);
UnloadImage(catSharpend);
}
public void Update()
{
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
DrawTexture(catSharpendTexture, 0, 0, Color.White);
DrawTexture(catSobelTexture, 200, 0, Color.White);
DrawTexture(catGaussianTexture, 400, 0, Color.White);
DrawTexture(texture, 600, 0, Color.White);
EndDrawing();
//----------------------------------------------------------------------------------
}
public void Unload()
{
UnloadTexture(texture);
UnloadTexture(catGaussianTexture);
UnloadTexture(catSobelTexture);
UnloadTexture(catSharpendTexture);
}
public static int Main()
{
// Initialization
//--------------------------------------------------------------------------------------
InitWindow(screenWidth, screenHeight, "raylib [textures] example - image kernel");
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
var game = new ImageKernel();
game.Init();
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
game.Update();
}
game.Unload();
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
}

View file

@ -1,70 +1,90 @@
/*******************************************************************************************
*
* raylib [textures] example - Image loading and texture creation
* raylib [textures] example - image loading
*
* Example complexity rating: [] 1/4
*
* NOTE: Images are loaded in CPU memory (RAM); textures are loaded in GPU memory (VRAM)
*
* This example has been created using raylib 1.3 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
* Example originally created with raylib 1.3, last time updated with raylib 1.3
*
* Copyright (c) 2015 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) 2015-2025 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
using static Raylib_cs.Raylib;
namespace Examples.Textures;
public class ImageLoading
public partial class ImageLoading : IExample
{
private const int screenWidth = 800;
private const int screenHeight = 450;
public string Name => "Textures / Image Loading";
public string Title => "raylib [textures] example - image loading";
private Texture2D texture;
public void Init()
{
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
var image = LoadImage("resources/raylib-cs_logo.png"); // Loaded in CPU memory (RAM)
texture = LoadTextureFromImage(image); // Image converted to texture, GPU memory (VRAM)
UnloadImage(image); // Once image has been converted to texture and uploaded to VRAM, it can be unloaded from RAM
}
public void Update()
{
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
DrawTexture(
texture,
screenWidth / 2 - texture.Width / 2,
screenHeight / 2 - texture.Height / 2,
Color.White
);
DrawText("this IS a texture loaded from an image!", 300, 370, 10, Color.Gray);
EndDrawing();
//----------------------------------------------------------------------------------
}
public void Unload()
{
UnloadTexture(texture); // Texture unloading
}
public static int Main()
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [textures] example - image loading");
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
Image image = LoadImage("resources/raylib-cs_logo.png");
Texture2D texture = LoadTextureFromImage(image);
UnloadImage(image);
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//---------------------------------------------------------------------------------------
var game = new ImageLoading();
game.Init();
// Main game loop
while (!WindowShouldClose())
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
// TODO: Update your variables here
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
DrawTexture(
texture,
screenWidth / 2 - texture.Width / 2,
screenHeight / 2 - texture.Height / 2,
Color.White
);
DrawText("this IS a texture loaded from an image!", 300, 370, 10, Color.Gray);
EndDrawing();
//----------------------------------------------------------------------------------
game.Update();
}
game.Unload();
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadTexture(texture);
CloseWindow();
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;

View file

@ -1,25 +1,34 @@
/*******************************************************************************************
*
* raylib [textures] example - Image processing
* raylib [textures] example - image processing
*
* Example complexity rating: [] 3/4
*
* NOTE: Images are loaded in CPU memory (RAM); textures are loaded in GPU memory (VRAM)
*
* This example has been created using raylib 1.4 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
* Example originally created with raylib 1.4, last time updated with raylib 3.5
*
* Copyright (c) 2016 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) 2016-2025 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
using static Raylib_cs.Raylib;
namespace Examples.Textures;
public class ImageProcessing
public partial class ImageProcessing : IExample
{
private const int screenWidth = 800;
private const int screenHeight = 450;
public const int NumProcesses = 9;
enum ImageProcess
public string Name => "Textures / Image Processing";
public string Title => "raylib [textures] example - image processing";
private enum ImageProcess
{
None = 0,
ColorGrayScale,
@ -32,188 +41,210 @@ public class ImageProcessing
FlipHorizontal
}
static string[] processText = {
"NO PROCESSING",
"COLOR GRAYSCALE",
"COLOR TINT",
"COLOR INVERT",
"COLOR CONTRAST",
"COLOR BRIGHTNESS",
"GAUSSIAN BLUR",
"FLIP VERTICAL",
"FLIP HORIZONTAL"
};
private string[] processText = {
"NO PROCESSING",
"COLOR GRAYSCALE",
"COLOR TINT",
"COLOR INVERT",
"COLOR CONTRAST",
"COLOR BRIGHTNESS",
"GAUSSIAN BLUR",
"FLIP VERTICAL",
"FLIP HORIZONTAL"
};
public unsafe static int Main()
private Image imageOrigin;
private Image imageCopy;
private Texture2D texture;
private ImageProcess currentProcess;
private bool textureReload;
private Rectangle[] toggleRecs;
private int mouseHoverRec;
public void Init()
{
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
imageOrigin = LoadImage("resources/parrots.png"); // Loaded in CPU memory (RAM)
ImageFormat(ref imageOrigin, PixelFormat.UncompressedR8G8B8A8); // Format image to RGBA 32bit (required for texture update) <-- ISSUE
texture = LoadTextureFromImage(imageOrigin); // Image converted to texture, GPU memory (VRAM)
imageCopy = ImageCopy(imageOrigin);
currentProcess = ImageProcess.None;
textureReload = false;
toggleRecs = new Rectangle[NumProcesses];
mouseHoverRec = -1;
for (var i = 0; i < NumProcesses; i++)
{
toggleRecs[i] = new Rectangle(40.0f, (float)(50 + 32 * i), 150.0f, 30.0f);
}
}
public unsafe void Update()
{
// Update
//----------------------------------------------------------------------------------
// Mouse toggle group logic
for (var i = 0; i < NumProcesses; i++)
{
if (CheckCollisionPointRec(GetMousePosition(), toggleRecs[i]))
{
mouseHoverRec = i;
if (IsMouseButtonReleased(MouseButton.Left))
{
currentProcess = (ImageProcess)i;
textureReload = true;
}
break;
}
else
{
mouseHoverRec = -1;
}
}
// Keyboard toggle group logic
if (IsKeyPressed(KeyboardKey.Down))
{
currentProcess++;
if ((int)currentProcess > (NumProcesses - 1))
{
currentProcess = 0;
}
textureReload = true;
}
else if (IsKeyPressed(KeyboardKey.Up))
{
currentProcess--;
if (currentProcess < 0)
{
currentProcess = ImageProcess.FlipHorizontal;
}
textureReload = true;
}
// Reload texture when required
if (textureReload)
{
UnloadImage(imageCopy); // Unload image-copy data
imageCopy = ImageCopy(imageOrigin); // Restore image-copy from image-origin
// NOTE: Image processing is a costly CPU process to be done every frame,
// If image processing is required in a frame-basis, it should be done
// with a texture and by shaders
switch (currentProcess)
{
case ImageProcess.ColorGrayScale:
ImageColorGrayscale(ref imageCopy);
break;
case ImageProcess.ColorTint:
ImageColorTint(ref imageCopy, Color.Green);
break;
case ImageProcess.ColorInvert:
ImageColorInvert(ref imageCopy);
break;
case ImageProcess.ColorContrast:
ImageColorContrast(ref imageCopy, -40);
break;
case ImageProcess.ColorBrightness:
ImageColorBrightness(ref imageCopy, -80);
break;
case ImageProcess.GaussianBlur:
ImageBlurGaussian(ref imageCopy, 10);
break;
case ImageProcess.FlipVertical:
ImageFlipVertical(ref imageCopy);
break;
case ImageProcess.FlipHorizontal:
ImageFlipHorizontal(ref imageCopy);
break;
default:
break;
}
var pixels = LoadImageColors(imageCopy); // Load pixel data from image (RGBA 32bit)
UpdateTexture(texture, pixels); // Update texture with new image data
UnloadImageColors(pixels); // Unload pixels data from RAM
textureReload = false;
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
DrawText("IMAGE PROCESSING:", 40, 30, 10, Color.DarkGray);
// Draw rectangles
for (var i = 0; i < NumProcesses; i++)
{
DrawRectangleRec(toggleRecs[i], ((i == (int)currentProcess) || (i == mouseHoverRec)) ? Color.SkyBlue : Color.LightGray);
DrawRectangleLines(
(int)toggleRecs[i].X,
(int)toggleRecs[i].Y,
(int)toggleRecs[i].Width,
(int)toggleRecs[i].Height,
((i == (int)currentProcess) || (i == mouseHoverRec)) ? Color.Blue : Color.Gray
);
var labelX = (int)(toggleRecs[i].X + toggleRecs[i].Width / 2);
DrawText(
processText[i],
(int)(labelX - MeasureText(processText[i], 10) / 2),
(int)toggleRecs[i].Y + 11,
10,
((i == (int)currentProcess) || (i == mouseHoverRec)) ? Color.DarkBlue : Color.DarkGray
);
}
var x = screenWidth - texture.Width - 60;
var y = screenHeight / 2 - texture.Height / 2;
DrawTexture(texture, x, y, Color.White);
DrawRectangleLines(x, y, texture.Width, texture.Height, Color.Black);
EndDrawing();
//----------------------------------------------------------------------------------
}
public void Unload()
{
UnloadTexture(texture); // Unload texture from VRAM
UnloadImage(imageOrigin); // Unload image-origin from RAM
UnloadImage(imageCopy); // Unload image-copy from RAM
}
public static int Main()
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [textures] example - image processing");
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
Image imageOrigin = LoadImage("resources/parrots.png");
ImageFormat(ref imageOrigin, PixelFormat.UncompressedR8G8B8A8);
Texture2D texture = LoadTextureFromImage(imageOrigin);
Image imageCopy = ImageCopy(imageOrigin);
ImageProcess currentProcess = ImageProcess.None;
bool textureReload = false;
Rectangle[] toggleRecs = new Rectangle[NumProcesses];
int mouseHoverRec = -1;
for (int i = 0; i < NumProcesses; i++)
{
toggleRecs[i] = new Rectangle(40, 50 + 32 * i, 150, 30);
}
SetTargetFPS(60);
//---------------------------------------------------------------------------------------
var game = new ImageProcessing();
game.Init();
// Main game loop
while (!WindowShouldClose())
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
// Mouse toggle group logic
for (int i = 0; i < NumProcesses; i++)
{
if (CheckCollisionPointRec(GetMousePosition(), toggleRecs[i]))
{
mouseHoverRec = i;
if (IsMouseButtonReleased(MouseButton.Left))
{
currentProcess = (ImageProcess)i;
textureReload = true;
}
break;
}
else
{
mouseHoverRec = -1;
}
}
// Keyboard toggle group logic
if (IsKeyPressed(KeyboardKey.Down))
{
currentProcess++;
if ((int)currentProcess > (NumProcesses - 1))
{
currentProcess = 0;
}
textureReload = true;
}
else if (IsKeyPressed(KeyboardKey.Up))
{
currentProcess--;
if (currentProcess < 0)
{
currentProcess = ImageProcess.FlipHorizontal;
}
textureReload = true;
}
if (textureReload)
{
UnloadImage(imageCopy);
imageCopy = ImageCopy(imageOrigin);
// NOTE: Image processing is a costly CPU process to be done every frame,
// If image processing is required in a frame-basis, it should be done
// with a texture and by shaders
switch (currentProcess)
{
case ImageProcess.ColorGrayScale:
ImageColorGrayscale(ref imageCopy);
break;
case ImageProcess.ColorTint:
ImageColorTint(ref imageCopy, Color.Green);
break;
case ImageProcess.ColorInvert:
ImageColorInvert(ref imageCopy);
break;
case ImageProcess.ColorContrast:
ImageColorContrast(ref imageCopy, -40);
break;
case ImageProcess.ColorBrightness:
ImageColorBrightness(ref imageCopy, -80);
break;
case ImageProcess.GaussianBlur:
ImageBlurGaussian(ref imageCopy, 10);
break;
case ImageProcess.FlipVertical:
ImageFlipVertical(ref imageCopy);
break;
case ImageProcess.FlipHorizontal:
ImageFlipHorizontal(ref imageCopy);
break;
default:
break;
}
// Get pixel data from image (RGBA 32bit)
Color* pixels = LoadImageColors(imageCopy);
UpdateTexture(texture, pixels);
UnloadImageColors(pixels);
textureReload = false;
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
DrawText("IMAGE PROCESSING:", 40, 30, 10, Color.DarkGray);
// Draw rectangles
for (int i = 0; i < NumProcesses; i++)
{
DrawRectangleRec(toggleRecs[i], (i == (int)currentProcess) ? Color.SkyBlue : Color.LightGray);
DrawRectangleLines(
(int)toggleRecs[i].X,
(int)toggleRecs[i].Y,
(int)toggleRecs[i].Width,
(int)toggleRecs[i].Height,
(i == (int)currentProcess) ? Color.Blue : Color.Gray
);
int labelX = (int)(toggleRecs[i].X + toggleRecs[i].Width / 2);
DrawText(
processText[i],
(int)(labelX - MeasureText(processText[i], 10) / 2),
(int)toggleRecs[i].Y + 11,
10,
(i == (int)currentProcess) ? Color.DarkBlue : Color.DarkGray
);
}
int x = screenWidth - texture.Width - 60;
int y = screenHeight / 2 - texture.Height / 2;
DrawTexture(texture, x, y, Color.White);
DrawRectangleLines(x, y, texture.Width, texture.Height, Color.Black);
EndDrawing();
//----------------------------------------------------------------------------------
game.Update();
}
game.Unload();
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadTexture(texture);
UnloadImage(imageOrigin);
UnloadImage(imageCopy);
CloseWindow();
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;

View file

@ -0,0 +1,119 @@
/*******************************************************************************************
*
* raylib [textures] example - image rotate
*
* Example complexity rating: [] 2/4
*
* 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) 2014-2025 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
namespace Examples.Textures;
public partial class ImageRotate : IExample
{
private const int screenWidth = 800;
private const int screenHeight = 450;
private const int NumTextures = 3;
public string Name => "Textures / Image Rotate";
public string Title => "raylib [textures] example - image rotate";
private Texture2D[] textures;
private int currentTexture;
public void Init()
{
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
var image45 = LoadImage("resources/raylib_logo.png");
var image90 = LoadImage("resources/raylib_logo.png");
var imageNeg90 = LoadImage("resources/raylib_logo.png");
ImageRotate(ref image45, 45);
ImageRotate(ref image90, 90);
ImageRotate(ref imageNeg90, -90);
textures = new Texture2D[NumTextures];
textures[0] = LoadTextureFromImage(image45);
textures[1] = LoadTextureFromImage(image90);
textures[2] = LoadTextureFromImage(imageNeg90);
UnloadImage(image45);
UnloadImage(image90);
UnloadImage(imageNeg90);
currentTexture = 0;
}
public void Update()
{
// Update
//----------------------------------------------------------------------------------
if (IsMouseButtonPressed(MouseButton.Left) || IsKeyPressed(KeyboardKey.Right))
{
currentTexture = (currentTexture + 1) % NumTextures; // Cycle between the textures
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
DrawTexture(
textures[currentTexture],
screenWidth / 2 - textures[currentTexture].Width / 2,
screenHeight / 2 - textures[currentTexture].Height / 2,
Color.White);
DrawText("Press LEFT MOUSE BUTTON to rotate the image clockwise", 250, 420, 10, Color.DarkGray);
EndDrawing();
//----------------------------------------------------------------------------------
}
public void Unload()
{
for (var i = 0; i < NumTextures; i++)
{
UnloadTexture(textures[i]);
}
}
public static int Main()
{
// Initialization
//--------------------------------------------------------------------------------------
InitWindow(screenWidth, screenHeight, "raylib [textures] example - image rotate");
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
var game = new ImageRotate();
game.Init();
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
game.Update();
}
game.Unload();
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
}

View file

@ -1,34 +1,40 @@
/*******************************************************************************************
*
* raylib [texture] example - Image text drawing using TTF generated spritefont
* raylib [textures] example - image text
*
* This example has been created using raylib 1.8 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
* Example complexity rating: [] 2/4
*
* Copyright (c) 2017 Ramon Santamaria (@raysan5)
* Example originally created with raylib 1.8, last time updated with raylib 4.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) 2017-2025 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
using System.Numerics;
using static Raylib_cs.Raylib;
namespace Examples.Textures;
public class ImageText
public partial class ImageText : IExample
{
public static int Main()
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
private const int screenWidth = 800;
private const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [texture] example - image text drawing");
public string Name => "Textures / Image Text";
public string Title => "raylib [textures] example - image text";
private Font font;
private Texture2D texture;
private Vector2 position;
private bool showFont;
public void Init()
{
var parrots = LoadImage("resources/parrots.png"); // Load image in CPU memory (RAM)
// TTF Font loading with custom generation parameters
Font font = LoadFontEx("resources/fonts/KAISG.ttf", 64, null, 95);
Image parrots = LoadImage("resources/parrots.png");
font = LoadFontEx("resources/fonts/KAISG.ttf", 64, null, 0);
// Draw over image using custom font
ImageDrawTextEx(
@ -38,69 +44,89 @@ public class ImageText
new Vector2(20, 20),
font.BaseSize,
0,
Color.White
Color.Red
);
// Image converted to texture, uploaded to GPU memory (VRAM)
Texture2D texture = LoadTextureFromImage(parrots);
UnloadImage(parrots);
texture = LoadTextureFromImage(parrots); // Image converted to texture, uploaded to GPU memory (VRAM)
UnloadImage(parrots); // Once image has been converted to texture and uploaded to VRAM, it can be unloaded from RAM
Vector2 position = new(
position = new(
screenWidth / 2 - texture.Width / 2,
screenHeight / 2 - texture.Height / 2 - 20
);
bool showFont = false;
showFont = false;
}
public void Update()
{
// Update
//----------------------------------------------------------------------------------
if (IsKeyDown(KeyboardKey.Space))
{
showFont = true;
}
else
{
showFont = false;
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
if (!showFont)
{
// Draw texture with text already drawn inside
DrawTextureV(texture, position, Color.White);
// Draw text directly using sprite font
Vector2 textPosition = new(position.X + 20, position.Y + 20 + 280);
DrawTextEx(font, "[Parrots font drawing]", textPosition, font.BaseSize, 0, Color.White);
}
else
{
DrawTexture(font.Texture, screenWidth / 2 - font.Texture.Width / 2, 50, Color.Black);
}
DrawText("PRESS SPACE to SHOW FONT ATLAS USED", 290, 420, 10, Color.DarkGray);
EndDrawing();
//----------------------------------------------------------------------------------
}
public void Unload()
{
UnloadTexture(texture); // Texture unloading
UnloadFont(font); // Unload custom font
}
public static int Main()
{
// Initialization
//--------------------------------------------------------------------------------------
InitWindow(screenWidth, screenHeight, "raylib [textures] example - image text");
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
var game = new ImageText();
game.Init();
// Main game loop
while (!WindowShouldClose())
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
if (IsKeyDown(KeyboardKey.Space))
{
showFont = true;
}
else
{
showFont = false;
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
if (!showFont)
{
// Draw texture with text already drawn inside
DrawTextureV(texture, position, Color.White);
// Draw text directly using sprite font
Vector2 textPosition = new(position.X + 20, position.Y + 20 + 280);
DrawTextEx(font, "[Parrots font drawing]", textPosition, font.BaseSize, 0, Color.White);
}
else
{
DrawTexture(font.Texture, screenWidth / 2 - font.Texture.Width / 2, 50, Color.Black);
}
DrawText("PRESS SPACE to SEE USED SPRITEFONT ", 290, 420, 10, Color.DarkGray);
EndDrawing();
//----------------------------------------------------------------------------------
game.Update();
}
game.Unload();
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadTexture(texture);
UnloadFont(font);
CloseWindow();
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;

View file

@ -1,64 +1,85 @@
/*******************************************************************************************
*
* raylib [textures] example - Texture loading and drawing
* raylib [textures] example - logo raylib
*
* This example has been created using raylib 1.0 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
* Example complexity rating: [] 1/4
*
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
* 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) 2014-2025 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
using static Raylib_cs.Raylib;
namespace Examples.Textures;
public class LogoRaylibTexture
public partial class LogoRaylibTexture : IExample
{
private const int screenWidth = 800;
private const int screenHeight = 450;
public string Name => "Textures / Logo Raylib Texture";
public string Title => "raylib [textures] example - logo raylib";
private Texture2D texture;
public void Init()
{
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
texture = LoadTexture("resources/raylib-cs_logo.png"); // Texture loading
}
public void Update()
{
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
DrawTexture(
texture,
screenWidth / 2 - texture.Width / 2,
screenHeight / 2 - texture.Height / 2,
Color.White
);
DrawText("this IS a texture!", 360, 370, 10, Color.Gray);
EndDrawing();
//----------------------------------------------------------------------------------
}
public void Unload()
{
UnloadTexture(texture); // Texture unloading
}
public static int Main()
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [textures] example - logo raylib");
InitWindow(screenWidth, screenHeight, "raylib [textures] example - texture loading and drawing");
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
Texture2D texture = LoadTexture("resources/raylib-cs_logo.png");
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//---------------------------------------------------------------------------------------
var game = new LogoRaylibTexture();
game.Init();
// Main game loop
while (!WindowShouldClose())
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
// TODO: Update your variables here
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
DrawTexture(
texture,
screenWidth / 2 - texture.Width / 2,
screenHeight / 2 - texture.Height / 2,
Color.White
);
DrawText("this IS a texture!", 360, 370, 10, Color.Gray);
EndDrawing();
//----------------------------------------------------------------------------------
game.Update();
}
game.Unload();
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadTexture(texture);
CloseWindow();
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;

View file

@ -0,0 +1,157 @@
/*******************************************************************************************
*
* raylib textures example - magnifying glass
*
* Example complexity rating: [] 3/4
*
* Example originally created with raylib 5.6, last time updated with raylib 5.6
*
* Example contributed by Luke Vaughan (@badram) 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) 2026 Luke Vaughan (@badram)
*
********************************************************************************************/
namespace Examples.Textures;
public partial class MagnifyingGlass : IExample
{
private const int screenWidth = 800;
private const int screenHeight = 450;
public string Name => "Textures / Magnifying Glass";
public string Title => "raylib [textures] example - magnifying glass";
private Texture2D bunny;
private Texture2D parrots;
private Texture2D mask;
private RenderTexture2D magnifiedWorld;
private Camera2D camera;
public void Init()
{
bunny = LoadTexture("resources/raybunny.png");
parrots = LoadTexture("resources/parrots.png");
// Use image draw to generate a mask texture instead of loading it from a file.
var circle = GenImageColor(256, 256, Color.Blank);
ImageDrawCircle(ref circle, 128, 128, 128, Color.White);
mask = LoadTextureFromImage(circle); // Copy the mask image from RAM to VRAM
UnloadImage(circle); // Unload the image from RAM
magnifiedWorld = LoadRenderTexture(256, 256);
camera = new Camera2D();
// Set magnifying glass zoom
camera.Zoom = 2;
// Offset by half the size of the magnifying glass to counteract drawing the texture centered on the mouse position
camera.Offset = new Vector2(128, 128);
}
public void Update()
{
// Update
//----------------------------------------------------------------------------------
var mPos = GetMousePosition();
camera.Target = mPos;
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
// Draw the normal version of the world
DrawTexture(parrots, 144, 33, Color.White);
DrawText("Use the magnifying glass to find hidden bunnies!", 154, 6, 20, Color.Black);
// Render to a the magnifying glass
BeginTextureMode(magnifiedWorld);
ClearBackground(Color.RayWhite);
BeginMode2D(camera);
// Draw the same things in the magnified world as were in the normal version
DrawTexture(parrots, 144, 33, Color.White);
DrawText("Use the magnifying glass to find hidden bunnies!", 154, 6, 20, Color.Black);
// Draw bunnies only in the magnified world.
// BLEND_MULTIPLIED lets them take on the color of the image below them.
BeginBlendMode(BlendMode.Multiplied);
DrawTexture(bunny, 250, 350, Color.White);
DrawTexture(bunny, 500, 100, Color.White);
DrawTexture(bunny, 420, 300, Color.White);
DrawTexture(bunny, 650, 10, Color.White);
EndBlendMode();
EndMode2D();
// Mask the magnifying glass view texture to a circle
// To make the mask affect only alpha, a CUSTOM blend mode is used with SEPARATE color/alpha functions
BeginBlendMode(BlendMode.CustomSeparate);
// C: Color, A: Alpha, s: source (texture to draw), d: destination (texture drawn to)
// glSrcRGB: RL_ZERO - Cs * 0 = 0 - discard source rgb because we don't want to draw our texture's colors at all
// glDstRGB: RL_ONE - Cd * 1 = Cd - use destination colors unmodified
// glSrcAlpha: RL_ONE - As * 1 = As - use source alpha unmodified
// glDstAlpha: RL_ZERO - Ad * 0 = 0 - discard destination alpha
// glEqRGB: RL_FUNC_ADD - Cs(0) + Cd = Cd - destination color is unmodified
// glEqAlpha: RL_FUNC_ADD - As + Ad(0) = As - destination alpha is set to source alpha
Rlgl.SetBlendFactorsSeparate(Rlgl.ZERO, Rlgl.ONE, Rlgl.ONE, Rlgl.ZERO, Rlgl.FUNC_ADD, Rlgl.FUNC_ADD);
DrawTexture(mask, 0, 0, Color.White);
EndBlendMode();
EndTextureMode();
// Draw magnifiedWorld to screen, centered on cursor
DrawTextureRec(magnifiedWorld.Texture, new Rectangle(0, 0, 256, -256), new Vector2(mPos.X - 128, mPos.Y - 128), Color.White);
// Draw the outer ring of the magnifying glass
DrawRing(mPos, 126, 130, 0, 360, 64, Color.Black);
// Draw floating specular highlight on the glass
var rx = mPos.X / 800;
var ry = mPos.Y / 800;
DrawCircle((int)(mPos.X - 64 * rx) - 32, (int)(mPos.Y - 64 * ry) - 32, 4, ColorAlpha(Color.White, 0.5f));
EndDrawing();
//----------------------------------------------------------------------------------
}
public void Unload()
{
UnloadTexture(parrots);
UnloadTexture(bunny);
UnloadTexture(mask);
UnloadRenderTexture(magnifiedWorld);
}
public static int Main()
{
// Initialization
//--------------------------------------------------------------------------------------
InitWindow(screenWidth, screenHeight, "raylib [textures] example - magnifying glass");
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
var game = new MagnifyingGlass();
game.Init();
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
game.Update();
}
game.Unload();
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
}

View file

@ -1,63 +1,82 @@
/*******************************************************************************************
*
* raylib [textures] example - Mouse painting
* raylib [textures] example - mouse painting
*
* This example has been created using raylib 2.5 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
* Example complexity rating: [] 3/4
*
* Example originally created with raylib 3.0, last time updated with raylib 3.0
*
* Example contributed by Chris Dill (@MysteriousSpace) and reviewed by Ramon Santamaria (@raysan5)
*
* Copyright (c) 2019 Chris Dill (@MysteriousSpace) and 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 Dill (@MysteriousSpace) and Ramon Santamaria (@raysan5)
*
********************************************************************************************/
using System.Numerics;
using static Raylib_cs.Raylib;
namespace Examples.Textures;
public class MousePainting
public partial class MousePainting : IExample
{
public static int Main()
private const int screenWidth = 800;
private const int screenHeight = 450;
public string Name => "Textures / Mouse Painting";
public string Title => "raylib [textures] example - mouse painting";
public int TargetFps => 120;
private Color[] colors;
private Rectangle[] colorsRecs;
private int colorSelected;
private int colorSelectedPrev;
private int colorMouseHover;
private float brushSize;
private bool mouseWasPressed;
private Rectangle btnSaveRec;
private bool btnSaveMouseHover;
private bool showSaveMessage;
private int saveMessageCounter;
private RenderTexture2D target;
public void Init()
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [textures] example - mouse painting");
// Colours to choose from
Color[] colors = new Color[] {
Color.RayWhite,
Color.Yellow,
Color.Gold,
Color.Orange,
Color.Pink,
Color.Red,
Color.Maroon,
Color.Green,
Color.Lime,
Color.DarkGreen,
Color.SkyBlue,
Color.Blue,
Color.DarkBlue,
Color.Purple,
Color.Violet,
Color.DarkPurple,
Color.Beige,
Color.Brown,
Color.DarkBrown,
Color.LightGray,
Color.Gray,
Color.DarkGray,
Color.Black
};
// Colors to choose from
colors = new Color[] {
Color.RayWhite,
Color.Yellow,
Color.Gold,
Color.Orange,
Color.Pink,
Color.Red,
Color.Maroon,
Color.Green,
Color.Lime,
Color.DarkGreen,
Color.SkyBlue,
Color.Blue,
Color.DarkBlue,
Color.Purple,
Color.Violet,
Color.DarkPurple,
Color.Beige,
Color.Brown,
Color.DarkBrown,
Color.LightGray,
Color.Gray,
Color.DarkGray,
Color.Black
};
// Define colorsRecs data (for every rectangle)
Rectangle[] colorsRecs = new Rectangle[colors.Length];
colorsRecs = new Rectangle[colors.Length];
for (int i = 0; i < colorsRecs.Length; i++)
for (var i = 0; i < colorsRecs.Length; i++)
{
colorsRecs[i].X = 10 + 30 * i + 2 * i;
colorsRecs[i].Y = 10;
@ -65,226 +84,255 @@ public class MousePainting
colorsRecs[i].Height = 30;
}
int colorSelected = 0;
int colorSelectedPrev = colorSelected;
int colorMouseHover = 0;
int brushSize = 20;
colorSelected = 0;
colorSelectedPrev = colorSelected;
colorMouseHover = 0;
brushSize = 20.0f;
mouseWasPressed = false;
Rectangle btnSaveRec = new(750, 10, 40, 30);
bool btnSaveMouseHover = false;
bool showSaveMessage = false;
int saveMessageCounter = 0;
btnSaveRec = new(750, 10, 40, 30);
btnSaveMouseHover = false;
showSaveMessage = false;
saveMessageCounter = 0;
// Create a RenderTexture2D to use as a canvas
RenderTexture2D target = LoadRenderTexture(screenWidth, screenHeight);
target = LoadRenderTexture(screenWidth, screenHeight);
// Clear render texture before entering the game loop
BeginTextureMode(target);
ClearBackground(colors[0]);
EndTextureMode();
}
public void Update()
{
// Update
//----------------------------------------------------------------------------------
var mousePos = GetMousePosition();
// Move between colors with keys
if (IsKeyPressed(KeyboardKey.Right))
{
colorSelected++;
}
else if (IsKeyPressed(KeyboardKey.Left))
{
colorSelected--;
}
if (colorSelected >= colors.Length)
{
colorSelected = colors.Length - 1;
}
else if (colorSelected < 0)
{
colorSelected = 0;
}
// Choose color with mouse
for (var i = 0; i < colors.Length; i++)
{
if (CheckCollisionPointRec(mousePos, colorsRecs[i]))
{
colorMouseHover = i;
break;
}
else
{
colorMouseHover = -1;
}
}
if ((colorMouseHover >= 0) && IsMouseButtonPressed(MouseButton.Left))
{
colorSelected = colorMouseHover;
colorSelectedPrev = colorSelected;
}
// Change brush size
brushSize += GetMouseWheelMove() * 5;
if (brushSize < 2)
{
brushSize = 2;
}
if (brushSize > 50)
{
brushSize = 50;
}
if (IsKeyPressed(KeyboardKey.C))
{
// Clear render texture to clear color
BeginTextureMode(target);
ClearBackground(colors[0]);
EndTextureMode();
}
if (IsMouseButtonDown(MouseButton.Left) || (GetGestureDetected() == Gesture.Drag))
{
// Paint circle into render texture
// NOTE: To avoid discontinuous circles, we could store
// previous-next mouse points and just draw a line using brush size
BeginTextureMode(target);
if (mousePos.Y > 50)
{
DrawCircle((int)mousePos.X, (int)mousePos.Y, brushSize, colors[colorSelected]);
}
EndTextureMode();
}
if (IsMouseButtonDown(MouseButton.Right))
{
if (!mouseWasPressed)
{
colorSelectedPrev = colorSelected;
colorSelected = 0;
}
mouseWasPressed = true;
// Erase circle from render texture
BeginTextureMode(target);
if (mousePos.Y > 50)
{
DrawCircle((int)mousePos.X, (int)mousePos.Y, brushSize, colors[0]);
}
EndTextureMode();
}
else if (IsMouseButtonReleased(MouseButton.Right) && mouseWasPressed)
{
colorSelected = colorSelectedPrev;
mouseWasPressed = false;
}
// Check mouse hover save button
if (CheckCollisionPointRec(mousePos, btnSaveRec))
{
btnSaveMouseHover = true;
}
else
{
btnSaveMouseHover = false;
}
// Image saving logic
// NOTE: Saving painted texture to a default named image
if ((btnSaveMouseHover && IsMouseButtonReleased(MouseButton.Left)) ||
IsKeyPressed(KeyboardKey.S))
{
var image = LoadImageFromTexture(target.Texture);
ImageFlipVertical(ref image);
ExportImage(image, "my_amazing_texture_painting.png");
UnloadImage(image);
showSaveMessage = true;
}
if (showSaveMessage)
{
// On saving, show a full screen message for 2 seconds
saveMessageCounter++;
if (saveMessageCounter > 240)
{
showSaveMessage = false;
saveMessageCounter = 0;
}
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
// NOTE: Render texture must be y-flipped due to default OpenGL coordinates (left-bottom)
Rectangle source = new(0, 0, target.Texture.Width, -target.Texture.Height);
DrawTextureRec(target.Texture, source, new Vector2(0, 0), Color.White);
// Draw drawing circle for reference
if (mousePos.Y > 50)
{
if (IsMouseButtonDown(MouseButton.Right))
{
DrawCircleLines((int)mousePos.X, (int)mousePos.Y, brushSize, Color.Gray);
}
else
{
DrawCircle(GetMouseX(), GetMouseY(), brushSize, colors[colorSelected]);
}
}
// Draw top panel
DrawRectangle(0, 0, GetScreenWidth(), 50, Color.RayWhite);
DrawLine(0, 50, GetScreenWidth(), 50, Color.LightGray);
// Draw color selection rectangles
for (var i = 0; i < colors.Length; i++)
{
DrawRectangleRec(colorsRecs[i], colors[i]);
}
DrawRectangleLines(10, 10, 30, 30, Color.LightGray);
if (colorMouseHover >= 0)
{
DrawRectangleRec(colorsRecs[colorMouseHover], Fade(Color.White, 0.6f));
}
Rectangle rec = new(
colorsRecs[colorSelected].X - 2,
colorsRecs[colorSelected].Y - 2,
colorsRecs[colorSelected].Width + 4,
colorsRecs[colorSelected].Height + 4
);
DrawRectangleLinesEx(rec, 2, Color.Black);
// Draw save image button
DrawRectangleLinesEx(btnSaveRec, 2, btnSaveMouseHover ? Color.Red : Color.Black);
DrawText("SAVE!", 755, 20, 10, btnSaveMouseHover ? Color.Red : Color.Black);
// Draw save image message
if (showSaveMessage)
{
DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), Fade(Color.RayWhite, 0.8f));
DrawRectangle(0, 150, GetScreenWidth(), 80, Color.Black);
DrawText("IMAGE SAVED!", 150, 180, 20, Color.RayWhite);
}
EndDrawing();
//----------------------------------------------------------------------------------
}
public void Unload()
{
UnloadRenderTexture(target); // Unload render texture
}
public static int Main()
{
// Initialization
//--------------------------------------------------------------------------------------
InitWindow(screenWidth, screenHeight, "raylib [textures] example - mouse painting");
SetTargetFPS(120); // Set our game to run at 120 frames-per-second
//--------------------------------------------------------------------------------------
var game = new MousePainting();
game.Init();
// Main game loop
while (!WindowShouldClose())
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
Vector2 mousePos = GetMousePosition();
// Move between colors with keys
if (IsKeyPressed(KeyboardKey.Right))
{
colorSelected++;
}
else if (IsKeyPressed(KeyboardKey.Left))
{
colorSelected--;
}
if (colorSelected >= colors.Length)
{
colorSelected = colors.Length - 1;
}
else if (colorSelected < 0)
{
colorSelected = 0;
}
// Choose color with mouse
for (int i = 0; i < colors.Length; i++)
{
if (CheckCollisionPointRec(mousePos, colorsRecs[i]))
{
colorMouseHover = i;
break;
}
else
{
colorMouseHover = -1;
}
}
if ((colorMouseHover >= 0) && IsMouseButtonPressed(MouseButton.Left))
{
colorSelected = colorMouseHover;
colorSelectedPrev = colorSelected;
}
// Change brush size
brushSize += (int)(GetMouseWheelMove() * 5);
if (brushSize < 2)
{
brushSize = 2;
}
if (brushSize > 50)
{
brushSize = 50;
}
if (IsKeyPressed(KeyboardKey.C))
{
// Clear render texture to clear color
BeginTextureMode(target);
ClearBackground(colors[0]);
EndTextureMode();
}
if (IsMouseButtonDown(MouseButton.Left))
{
// Paint circle into render texture
// NOTE: To avoid discontinuous circles, we could store
// previous-next mouse points and just draw a line using brush size
BeginTextureMode(target);
if (mousePos.Y > 50)
{
DrawCircle((int)mousePos.X, (int)mousePos.Y, brushSize, colors[colorSelected]);
}
EndTextureMode();
}
else if (IsMouseButtonDown(MouseButton.Right))
{
colorSelected = 0;
// Erase circle from render texture
BeginTextureMode(target);
if (mousePos.Y > 50)
{
DrawCircle((int)mousePos.X, (int)mousePos.Y, brushSize, colors[0]);
}
EndTextureMode();
}
else
{
colorSelected = colorSelectedPrev;
}
// Check mouse hover save button
if (CheckCollisionPointRec(mousePos, btnSaveRec))
{
btnSaveMouseHover = true;
}
else
{
btnSaveMouseHover = false;
}
// Image saving logic
// NOTE: Saving painted texture to a default named image
if ((btnSaveMouseHover && IsMouseButtonReleased(MouseButton.Left)) ||
IsKeyPressed(KeyboardKey.S))
{
Image image = LoadImageFromTexture(target.Texture);
ImageFlipVertical(ref image);
ExportImage(image, "my_amazing_texture_painting.png");
UnloadImage(image);
showSaveMessage = true;
}
if (showSaveMessage)
{
// On saving, show a full screen message for 2 seconds
saveMessageCounter++;
if (saveMessageCounter > 240)
{
showSaveMessage = false;
saveMessageCounter = 0;
}
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
// NOTE: Render texture must be y-flipped due to default OpenGL coordinates (left-bottom)
Rectangle source = new(0, 0, target.Texture.Width, -target.Texture.Height);
DrawTextureRec(target.Texture, source, new Vector2(0, 0), Color.White);
// Draw drawing circle for reference
if (mousePos.Y > 50)
{
if (IsMouseButtonDown(MouseButton.Right))
{
DrawCircleLines((int)mousePos.X, (int)mousePos.Y, brushSize, colors[colorSelected]);
}
else
{
DrawCircle(GetMouseX(), GetMouseY(), brushSize, colors[colorSelected]);
}
}
// Draw top panel
DrawRectangle(0, 0, GetScreenWidth(), 50, Color.RayWhite);
DrawLine(0, 50, GetScreenWidth(), 50, Color.LightGray);
// Draw color selection rectangles
for (int i = 0; i < colors.Length; i++)
{
DrawRectangleRec(colorsRecs[i], colors[i]);
}
DrawRectangleLines(10, 10, 30, 30, Color.LightGray);
if (colorMouseHover >= 0)
{
DrawRectangleRec(colorsRecs[colorMouseHover], ColorAlpha(Color.White, 0.6f));
}
Rectangle rec = new(
colorsRecs[colorSelected].X - 2,
colorsRecs[colorSelected].Y - 2,
colorsRecs[colorSelected].Width + 4,
colorsRecs[colorSelected].Height + 4
);
DrawRectangleLinesEx(rec, 2, Color.Black);
// Draw save image button
DrawRectangleLinesEx(btnSaveRec, 2, btnSaveMouseHover ? Color.Red : Color.Black);
DrawText("SAVE!", 755, 20, 10, btnSaveMouseHover ? Color.Red : Color.Black);
// Draw save image message
if (showSaveMessage)
{
DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), ColorAlpha(Color.RayWhite, 0.8f));
DrawRectangle(0, 150, GetScreenWidth(), 80, Color.Black);
DrawText("IMAGE SAVED: my_amazing_texture_painting.png", 150, 180, 20, Color.RayWhite);
}
EndDrawing();
//----------------------------------------------------------------------------------
game.Update();
}
game.Unload();
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadRenderTexture(target);
CloseWindow();
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;

View file

@ -1,49 +1,64 @@
/*******************************************************************************************
*
* raylib [textures] example - N-patch drawing
* raylib [textures] example - npatch drawing
*
* Example complexity rating: [] 3/4
*
* NOTE: Images are loaded in CPU memory (RAM); textures are loaded in GPU memory (VRAM)
*
* This example has been created using raylib 2.0 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
* Example originally created with raylib 2.0, last time updated with raylib 2.5
*
* Example contributed by Jorge A. Gomes (@overdev) and reviewed by Ramon Santamaria (@raysan5)
*
* Copyright (c) 2018 Jorge A. Gomes (@overdev) and 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) 2018-2025 Jorge A. Gomes (@overdev) and Ramon Santamaria (@raysan5)
*
********************************************************************************************/
using System;
using System.Numerics;
using static Raylib_cs.Raylib;
namespace Examples.Textures;
public class NpatchDrawing
public partial class NpatchDrawing : IExample
{
public static int Main()
private const int screenWidth = 800;
private const int screenHeight = 450;
public string Name => "Textures / N-patch Drawing";
public string Title => "raylib [textures] example - npatch drawing";
private Texture2D nPatchTexture;
private Vector2 mousePosition;
private Vector2 origin;
private Rectangle dstRec1;
private Rectangle dstRec2;
private Rectangle dstRecH;
private Rectangle dstRecV;
private NPatchInfo ninePatchInfo1;
private NPatchInfo ninePatchInfo2;
private NPatchInfo h3PatchInfo;
private NPatchInfo v3PatchInfo;
public void Init()
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [textures] example - N-patch drawing");
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
Texture2D nPatchTexture = LoadTexture("resources/ninepatch_button.png");
nPatchTexture = LoadTexture("resources/ninepatch_button.png");
Vector2 mousePosition = new(0.0f, 0.0f);
Vector2 origin = new(0.0f, 0.0f);
mousePosition = new(0.0f, 0.0f);
origin = new(0.0f, 0.0f);
// Position and size of the n-patches
Rectangle dstRec1 = new(480.0f, 160.0f, 32.0f, 32.0f);
Rectangle dstRec2 = new(160.0f, 160.0f, 32.0f, 32.0f);
Rectangle dstRecH = new(160.0f, 93.0f, 32.0f, 32.0f);
Rectangle dstRecV = new(92.0f, 160.0f, 32.0f, 32.0f);
dstRec1 = new(480.0f, 160.0f, 32.0f, 32.0f);
dstRec2 = new(160.0f, 160.0f, 32.0f, 32.0f);
dstRecH = new(160.0f, 93.0f, 32.0f, 32.0f);
dstRecV = new(92.0f, 160.0f, 32.0f, 32.0f);
// A 9-patch (NPT_9PATCH) changes its sizes in both axis
NPatchInfo ninePatchInfo1 = new NPatchInfo
// A 9-patch (NPATCH_NINE_PATCH) changes its sizes in both axis
ninePatchInfo1 = new NPatchInfo
{
Source = new Rectangle(0.0f, 0.0f, 64.0f, 64.0f),
Left = 12,
@ -52,7 +67,7 @@ public class NpatchDrawing
Bottom = 12,
Layout = NPatchLayout.NinePatch
};
NPatchInfo ninePatchInfo2 = new NPatchInfo
ninePatchInfo2 = new NPatchInfo
{
Source = new Rectangle(0.0f, 128.0f, 64.0f, 64.0f),
Left = 16,
@ -62,8 +77,8 @@ public class NpatchDrawing
Layout = NPatchLayout.NinePatch
};
// A horizontal 3-patch (NPT_3PATCH_HORIZONTAL) changes its sizes along the x axis only
NPatchInfo h3PatchInfo = new NPatchInfo
// A horizontal 3-patch (NPATCH_THREE_PATCH_HORIZONTAL) changes its sizes along the x axis only
h3PatchInfo = new NPatchInfo
{
Source = new Rectangle(0.0f, 64.0f, 64.0f, 64.0f),
Left = 8,
@ -73,8 +88,8 @@ public class NpatchDrawing
Layout = NPatchLayout.ThreePatchHorizontal
};
// A vertical 3-patch (NPT_3PATCH_VERTICAL) changes its sizes along the y axis only
NPatchInfo v3PatchInfo = new NPatchInfo
// A vertical 3-patch (NPATCH_THREE_PATCH_VERTICAL) changes its sizes along the y axis only
v3PatchInfo = new NPatchInfo
{
Source = new Rectangle(0.0f, 192.0f, 64.0f, 64.0f),
Left = 6,
@ -83,61 +98,81 @@ public class NpatchDrawing
Bottom = 6,
Layout = NPatchLayout.ThreePatchVertical
};
}
public void Update()
{
// Update
//----------------------------------------------------------------------------------
mousePosition = GetMousePosition();
// Resize the n-patches based on mouse position
dstRec1.Width = mousePosition.X - dstRec1.X;
dstRec1.Height = mousePosition.Y - dstRec1.Y;
dstRec2.Width = mousePosition.X - dstRec2.X;
dstRec2.Height = mousePosition.Y - dstRec2.Y;
dstRecH.Width = mousePosition.X - dstRecH.X;
dstRecV.Height = mousePosition.Y - dstRecV.Y;
// Set a minimum width and/or height
dstRec1.Width = Math.Clamp(dstRec1.Width, 1.0f, 300.0f);
dstRec1.Height = MathF.Max(dstRec1.Height, 1.0f);
dstRec2.Width = Math.Clamp(dstRec2.Width, 1.0f, 300.0f);
dstRec2.Height = MathF.Max(dstRec2.Height, 1.0f);
dstRecH.Width = MathF.Max(dstRecH.Width, 1.0f);
dstRecV.Height = MathF.Max(dstRecV.Height, 1.0f);
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
// Draw the n-patches
DrawTextureNPatch(nPatchTexture, ninePatchInfo2, dstRec2, origin, 0.0f, Color.White);
DrawTextureNPatch(nPatchTexture, ninePatchInfo1, dstRec1, origin, 0.0f, Color.White);
DrawTextureNPatch(nPatchTexture, h3PatchInfo, dstRecH, origin, 0.0f, Color.White);
DrawTextureNPatch(nPatchTexture, v3PatchInfo, dstRecV, origin, 0.0f, Color.White);
// Draw the source texture
DrawRectangleLines(5, 88, 74, 266, Color.Blue);
DrawTexture(nPatchTexture, 10, 93, Color.White);
DrawText("TEXTURE", 15, 360, 10, Color.DarkGray);
DrawText("Move the mouse to stretch or shrink the n-patches", 10, 20, 20, Color.DarkGray);
EndDrawing();
//----------------------------------------------------------------------------------
}
public void Unload()
{
UnloadTexture(nPatchTexture); // Texture unloading
}
public static int Main()
{
// Initialization
//--------------------------------------------------------------------------------------
InitWindow(screenWidth, screenHeight, "raylib [textures] example - npatch drawing");
SetTargetFPS(60);
//---------------------------------------------------------------------------------------
var game = new NpatchDrawing();
game.Init();
// Main game loop
while (!WindowShouldClose())
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
mousePosition = GetMousePosition();
// Resize the n-patches based on mouse position
dstRec1.Width = mousePosition.X - dstRec1.X;
dstRec1.Height = mousePosition.Y - dstRec1.Y;
dstRec2.Width = mousePosition.X - dstRec2.X;
dstRec2.Height = mousePosition.Y - dstRec2.Y;
dstRecH.Width = mousePosition.X - dstRecH.X;
dstRecV.Height = mousePosition.Y - dstRecV.Y;
// Set a minimum width and/or height
dstRec1.Width = Math.Clamp(dstRec1.Width, 1.0f, 300.0f);
dstRec1.Height = MathF.Max(dstRec1.Height, 1.0f);
dstRec2.Width = Math.Clamp(dstRec2.Width, 1.0f, 300.0f);
dstRec2.Height = MathF.Max(dstRec2.Height, 1.0f);
dstRecH.Width = MathF.Max(dstRecH.Width, 1.0f);
dstRecV.Height = MathF.Max(dstRecV.Height, 1.0f);
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
// Draw the n-patches
DrawTextureNPatch(nPatchTexture, ninePatchInfo2, dstRec2, origin, 0.0f, Color.White);
DrawTextureNPatch(nPatchTexture, ninePatchInfo1, dstRec1, origin, 0.0f, Color.White);
DrawTextureNPatch(nPatchTexture, h3PatchInfo, dstRecH, origin, 0.0f, Color.White);
DrawTextureNPatch(nPatchTexture, v3PatchInfo, dstRecV, origin, 0.0f, Color.White);
// Draw the source texture
DrawRectangleLines(5, 88, 74, 266, Color.Blue);
DrawTexture(nPatchTexture, 10, 93, Color.White);
DrawText("TEXTURE", 15, 360, 10, Color.DarkGray);
DrawText("Move the mouse to stretch or shrink the n-patches", 10, 20, 20, Color.DarkGray);
EndDrawing();
//----------------------------------------------------------------------------------
game.Update();
}
game.Unload();
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadTexture(nPatchTexture);
CloseWindow();
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;

View file

@ -1,25 +1,33 @@
/*******************************************************************************************
*
* raylib example - particles blending
* raylib [textures] example - particles blending
*
* This example has been created using raylib 1.7 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
* Example complexity rating: [] 1/4
*
* Copyright (c) 2017 Ramon Santamaria (@raysan5)
* Example originally created with raylib 1.7, last time updated with raylib 3.5
*
* 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) 2017-2025 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
using System.Numerics;
using static Raylib_cs.Raylib;
namespace Examples.Textures;
public class ParticlesBlending
public partial class ParticlesBlending : IExample
{
private const int screenWidth = 800;
private const int screenHeight = 450;
public const int MaxParticles = 200;
public string Name => "Textures / Particles Blending";
public string Title => "raylib [textures] example - particles blending";
// Particle structure with basic data
struct Particle
private struct Particle
{
public Vector2 Position;
public Color Color;
@ -30,20 +38,18 @@ public class ParticlesBlending
public bool Active;
}
public static int Main()
private Particle[] mouseTail;
private float gravity;
private Texture2D smoke;
private BlendMode blending;
public void Init()
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [textures] example - particles blending");
// Particles pool, reuse them!
Particle[] mouseTail = new Particle[MaxParticles];
mouseTail = new Particle[MaxParticles];
// Initialize particles
for (int i = 0; i < mouseTail.Length; i++)
for (var i = 0; i < mouseTail.Length; i++)
{
mouseTail[i].Position = new Vector2(0, 0);
mouseTail[i].Color = new Color(
@ -58,113 +64,133 @@ public class ParticlesBlending
mouseTail[i].Active = false;
}
float gravity = 3.0f;
Texture2D smoke = LoadTexture("resources/spark_flame.png");
BlendMode blending = BlendMode.Alpha;
gravity = 3.0f;
smoke = LoadTexture("resources/spark_flame.png");
blending = BlendMode.Alpha;
}
public void Update()
{
// Update
//----------------------------------------------------------------------------------
// Activate one particle every frame and Update active particles
// NOTE: Particles initial position should be mouse position when activated
// NOTE: Particles fall down with gravity and rotation... and disappear after 2 seconds (alpha = 0)
// NOTE: When a particle disappears, active = false and it can be reused
for (var i = 0; i < mouseTail.Length; i++)
{
if (!mouseTail[i].Active)
{
mouseTail[i].Active = true;
mouseTail[i].Alpha = 1.0f;
mouseTail[i].Position = GetMousePosition();
i = mouseTail.Length;
}
}
for (var i = 0; i < mouseTail.Length; i++)
{
if (mouseTail[i].Active)
{
mouseTail[i].Position.Y += gravity / 2;
mouseTail[i].Alpha -= 0.005f;
if (mouseTail[i].Alpha <= 0.0f)
{
mouseTail[i].Active = false;
}
mouseTail[i].Rotation += 2.0f;
}
}
if (IsKeyPressed(KeyboardKey.Space))
{
if (blending == BlendMode.Alpha)
{
blending = BlendMode.Additive;
}
else
{
blending = BlendMode.Alpha;
}
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.DarkGray);
BeginBlendMode(blending);
// Draw active particles
for (var i = 0; i < mouseTail.Length; i++)
{
if (mouseTail[i].Active)
{
Rectangle source = new(0, 0, smoke.Width, smoke.Height);
Rectangle dest = new(
mouseTail[i].Position.X,
mouseTail[i].Position.Y,
smoke.Width * mouseTail[i].Size,
smoke.Height * mouseTail[i].Size
);
Vector2 position = new(
smoke.Width * mouseTail[i].Size / 2,
smoke.Height * mouseTail[i].Size / 2
);
var color = Fade(mouseTail[i].Color, mouseTail[i].Alpha);
DrawTexturePro(smoke, source, dest, position, mouseTail[i].Rotation, color);
}
}
EndBlendMode();
DrawText("PRESS SPACE to CHANGE BLENDING MODE", 180, 20, 20, Color.Black);
if (blending == BlendMode.Alpha)
{
DrawText("ALPHA BLENDING", 290, screenHeight - 40, 20, Color.Black);
}
else
{
DrawText("ADDITIVE BLENDING", 280, screenHeight - 40, 20, Color.RayWhite);
}
EndDrawing();
//----------------------------------------------------------------------------------
}
public void Unload()
{
UnloadTexture(smoke);
}
public static int Main()
{
// Initialization
//--------------------------------------------------------------------------------------
InitWindow(screenWidth, screenHeight, "raylib [textures] example - particles blending");
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
var game = new ParticlesBlending();
game.Init();
// Main game loop
while (!WindowShouldClose())
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
// Activate one particle every frame and Update active particles
// NOTE: Particles initial position should be mouse position when activated
// NOTE: Particles fall down with gravity and rotation... and disappear after 2 seconds (alpha = 0)
// NOTE: When a particle disappears, active = false and it can be reused.
for (int i = 0; i < mouseTail.Length; i++)
{
if (!mouseTail[i].Active)
{
mouseTail[i].Active = true;
mouseTail[i].Alpha = 1.0f;
mouseTail[i].Position = GetMousePosition();
i = mouseTail.Length;
}
}
for (int i = 0; i < mouseTail.Length; i++)
{
if (mouseTail[i].Active)
{
mouseTail[i].Position.Y += gravity / 2;
mouseTail[i].Alpha -= 0.005f;
if (mouseTail[i].Alpha <= 0.0f)
{
mouseTail[i].Active = false;
}
mouseTail[i].Rotation += 2.0f;
}
}
if (IsKeyPressed(KeyboardKey.Space))
{
if (blending == BlendMode.Alpha)
{
blending = BlendMode.Additive;
}
else
{
blending = BlendMode.Alpha;
}
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.DarkGray);
BeginBlendMode(blending);
// Draw active particles
for (int i = 0; i < mouseTail.Length; i++)
{
if (mouseTail[i].Active)
{
Rectangle source = new(0, 0, smoke.Width, smoke.Height);
Rectangle dest = new(
mouseTail[i].Position.X,
mouseTail[i].Position.Y,
smoke.Width * mouseTail[i].Size,
smoke.Height * mouseTail[i].Size
);
Vector2 position = new(
smoke.Width * mouseTail[i].Size / 2,
smoke.Height * mouseTail[i].Size / 2
);
Color color = ColorAlpha(mouseTail[i].Color, mouseTail[i].Alpha);
DrawTexturePro(smoke, source, dest, position, mouseTail[i].Rotation, color);
}
}
EndBlendMode();
DrawText("PRESS SPACE to CHANGE BLENDING MODE", 180, 20, 20, Color.Black);
if (blending == BlendMode.Alpha)
{
DrawText("ALPHA BLENDING", 290, screenHeight - 40, 20, Color.Black);
}
else
{
DrawText("ADDITIVE BLENDING", 280, screenHeight - 40, 20, Color.RayWhite);
}
EndDrawing();
//----------------------------------------------------------------------------------
game.Update();
}
game.Unload();
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadTexture(smoke);
CloseWindow();
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;

View file

@ -1,51 +1,59 @@
/*******************************************************************************************
*
* raylib [shapes] example - Draw Textured Polygon
* raylib [textures] example - polygon drawing
*
* This example has been created using raylib 99.98 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
* Example complexity rating: [] 1/4
*
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
* Copyright (c) 2021 Chris Camacho (codifies - bedroomcoders.co.uk)
* Example originally created with raylib 3.7, 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) 2021-2025 Chris Camacho (@chriscamacho) and Ramon Santamaria (@raysan5)
*
********************************************************************************************/
using System.Numerics;
using static Raylib_cs.Raylib;
namespace Examples.Textures;
public class Polygon
public partial class Polygon : IExample
{
public static int Main()
private const int screenWidth = 800;
private const int screenHeight = 450;
public string Name => "Textures / Textured Polygon";
public string Title => "raylib [textures] example - polygon drawing";
private Vector2[] texcoords;
private Vector2[] points;
private Vector2[] positions;
private Texture2D texture;
private float angle;
public void Init()
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
texcoords = new[] {
new Vector2(0.75f, 0),
new Vector2(0.25f, 0),
new Vector2(0, 0.5f),
new Vector2(0, 0.75f),
new Vector2(0.25f, 1),
new Vector2(0.375f, 0.875f),
new Vector2(0.625f, 0.875f),
new Vector2(0.75f, 1),
new Vector2(1, 0.75f),
new Vector2(1, 0.5f),
// Close the poly
new Vector2(0.75f, 0)
};
InitWindow(screenWidth, screenHeight, "raylib [textures] example - Textured Polygon");
Vector2[] texcoords = new[] {
new Vector2(0.75f, 0),
new Vector2(0.25f, 0),
new Vector2(0, 0.5f),
new Vector2(0, 0.75f),
new Vector2(0.25f, 1),
new Vector2(0.375f, 0.875f),
new Vector2(0.625f, 0.875f),
new Vector2(0.75f, 1),
new Vector2(1, 0.75f),
new Vector2(1, 0.5f),
// Close the poly
new Vector2(0.75f, 0)
};
Vector2[] points = new Vector2[11];
points = new Vector2[11];
// Define the base poly vertices from the UV's
// NOTE: They can be specified in any other way
for (int i = 0; i < points.Length; i++)
for (var i = 0; i < points.Length; i++)
{
points[i].X = (texcoords[i].X - 0.5f) * 256.0f;
points[i].Y = (texcoords[i].Y - 0.5f) * 256.0f;
@ -53,58 +61,49 @@ public class Polygon
// Define the vertices drawing position
// NOTE: Initially same as points but updated every frame
Vector2[] positions = new Vector2[points.Length];
for (int i = 0; i < positions.Length; i++)
positions = new Vector2[points.Length];
for (var i = 0; i < positions.Length; i++)
{
positions[i] = points[i];
}
Texture2D texture = LoadTexture("resources/cat.png");
float angle = 0;
texture = LoadTexture("resources/cat.png");
angle = 0;
}
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose())
public void Update()
{
// Update
//----------------------------------------------------------------------------------
angle += 1;
for (var i = 0; i < positions.Length; i++)
{
// Update
//----------------------------------------------------------------------------------
// Update your variables here
//----------------------------------------------------------------------------------
angle += 1;
for (int i = 0; i < positions.Length; i++)
{
positions[i] = Raymath.Vector2Rotate(points[i], angle * Raylib.DEG2RAD);
}
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
DrawText("Textured Polygon", 20, 20, 20, Color.DarkGray);
Vector2 center = new(screenWidth / 2, screenHeight / 2);
DrawTexturePoly(texture, center, positions, texcoords, positions.Length, Color.White);
EndDrawing();
//----------------------------------------------------------------------------------
positions[i] = Raymath.Vector2Rotate(points[i], angle * Raylib.DEG2RAD);
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
DrawText("textured polygon", 20, 20, 20, Color.DarkGray);
Vector2 center = new(screenWidth / 2, screenHeight / 2);
DrawTexturePoly(texture, center, positions, texcoords, positions.Length, Color.White);
EndDrawing();
//----------------------------------------------------------------------------------
}
public void Unload()
{
UnloadTexture(texture);
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow();
//--------------------------------------------------------------------------------------
return 0;
}
// Draw textured polygon, defined by vertex and texture coordinates
// NOTE: Polygon center must have straight line path to all points
// without crossing perimeter, points must be in anticlockwise order
static void DrawTexturePoly(
private static void DrawTexturePoly(
Texture2D texture,
Vector2 center,
Vector2[] points,
@ -114,13 +113,11 @@ public class Polygon
)
{
Rlgl.SetTexture(texture.Id);
// Texturing is only supported on RL_QUADS
Rlgl.Begin(DrawMode.Quads);
Rlgl.Begin(DrawMode.Triangles);
Rlgl.Color4ub(tint.R, tint.G, tint.B, tint.A);
for (int i = 0; i < pointCount - 1; i++)
for (var i = 0; i < pointCount - 1; i++)
{
Rlgl.TexCoord2f(0.5f, 0.5f);
Rlgl.Vertex2f(center.X, center.Y);
@ -130,12 +127,37 @@ public class Polygon
Rlgl.TexCoord2f(texcoords[i + 1].X, texcoords[i + 1].Y);
Rlgl.Vertex2f(points[i + 1].X + center.X, points[i + 1].Y + center.Y);
Rlgl.TexCoord2f(texcoords[i + 1].X, texcoords[i + 1].Y);
Rlgl.Vertex2f(points[i + 1].X + center.X, points[i + 1].Y + center.Y);
}
Rlgl.End();
Rlgl.SetTexture(0);
}
public static int Main()
{
// Initialization
//--------------------------------------------------------------------------------------
InitWindow(screenWidth, screenHeight, "raylib [textures] example - polygon drawing");
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
var game = new Polygon();
game.Init();
// Main game loop
while (!WindowShouldClose())
{
game.Update();
}
game.Unload();
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow();
//--------------------------------------------------------------------------------------
return 0;
}
}

View file

@ -1,112 +1,141 @@
/*******************************************************************************************
*
* raylib [textures] example - Load textures from raw data
* raylib [textures] example - raw data
*
* Example complexity rating: [] 3/4
*
* NOTE: Images are loaded in CPU memory (RAM); textures are loaded in GPU memory (VRAM)
*
* This example has been created using raylib 1.3 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
* Example originally created with raylib 1.3, last time updated with raylib 3.5
*
* Copyright (c) 2015 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) 2015-2025 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
using static Raylib_cs.Raylib;
namespace Examples.Textures;
public class RawData
public partial class RawData : IExample
{
public unsafe static int Main()
private const int screenWidth = 800;
private const int screenHeight = 450;
public string Name => "Textures / Raw Data";
public string Title => "raylib [textures] example - raw data";
private Texture2D fudesumi;
private Texture2D checkedTex;
public unsafe void Init()
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [textures] example - texture from raw data");
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
// Load RAW image data (512x512, 32bit RGBA, no file header)
Image fudesumiRaw = LoadImageRaw(
var fudesumiRaw = LoadImageRaw(
"resources/fudesumi.raw",
384,
512,
PixelFormat.UncompressedR8G8B8A8,
0
);
Texture2D fudesumi = LoadTextureFromImage(fudesumiRaw);
UnloadImage(fudesumiRaw);
fudesumi = LoadTextureFromImage(fudesumiRaw); // Upload CPU (RAM) image to GPU (VRAM)
UnloadImage(fudesumiRaw); // Unload CPU (RAM) image data
// Generate a checked texture by code
int width = 960;
int height = 480;
var imWidth = 960;
var imHeight = 480;
// Store pixel data
Color* pixels = (Color*)Raylib.MemAlloc((uint)(width * height * sizeof(Color)));
for (int y = 0; y < height; y++)
// Dynamic memory allocation to store pixels data (Color type)
// WARNING: Using raylib provided MemAlloc() that uses default raylib
// internal memory allocator, so this data can be freed using UnloadImage()
// that also uses raylib internal memory de-allocator
var pixels = (Color*)Raylib.MemAlloc((uint)(imWidth * imHeight * sizeof(Color)));
for (var y = 0; y < imHeight; y++)
{
for (int x = 0; x < width; x++)
for (var x = 0; x < imWidth; x++)
{
if (((x / 32 + y / 32) / 1) % 2 == 0)
{
pixels[y * width + x] = Color.Orange;
pixels[y * imWidth + x] = Color.Orange;
}
else
{
pixels[y * width + x] = Color.Gold;
pixels[y * imWidth + x] = Color.Gold;
}
}
}
// Load pixels data into an image structure and create texture
Image checkedIm = new Image
// NOTE: We can assign pixels directly to data because Color is R8G8B8A8
// data structure defining that pixelformat, format must be set properly
var checkedIm = new Image
{
Data = pixels,
Width = width,
Height = height,
Width = imWidth,
Height = imHeight,
Format = PixelFormat.UncompressedR8G8B8A8,
Mipmaps = 1,
};
Texture2D checkedTex = LoadTextureFromImage(checkedIm);
Raylib.MemFree(pixels);
checkedTex = LoadTextureFromImage(checkedIm);
Raylib.MemFree(pixels); // Unload CPU (RAM) image data (pixels)
}
public void Update()
{
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
var x = screenWidth / 2 - checkedTex.Width / 2;
var y = screenHeight / 2 - checkedTex.Height / 2;
DrawTexture(checkedTex, x, y, Fade(Color.White, 0.5f));
DrawTexture(fudesumi, 430, -30, Color.White);
DrawText("CHECKED TEXTURE ", 84, 85, 30, Color.Brown);
DrawText("GENERATED by CODE", 72, 148, 30, Color.Brown);
DrawText("and RAW IMAGE LOADING", 46, 210, 30, Color.Brown);
DrawText("(c) Fudesumi sprite by Eiden Marsal", 310, screenHeight - 20, 10, Color.Brown);
EndDrawing();
//----------------------------------------------------------------------------------
}
public void Unload()
{
UnloadTexture(fudesumi); // Texture unloading
UnloadTexture(checkedTex); // Texture unloading
}
public static int Main()
{
// Initialization
//--------------------------------------------------------------------------------------
InitWindow(screenWidth, screenHeight, "raylib [textures] example - raw data");
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//---------------------------------------------------------------------------------------
var game = new RawData();
game.Init();
// Main game loop
while (!WindowShouldClose())
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
// TODO: Update your variables here
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
int x = screenWidth / 2 - checkedTex.Width / 2;
int y = screenHeight / 2 - checkedTex.Height / 2;
DrawTexture(checkedTex, x, y, ColorAlpha(Color.White, 0.5f));
DrawTexture(fudesumi, 430, -30, Color.White);
DrawText("CHECKED TEXTURE ", 84, 85, 30, Color.Brown);
DrawText("GENERATED by CODE", 72, 148, 30, Color.Brown);
DrawText("and RAW IMAGE LOADING", 46, 210, 30, Color.Brown);
DrawText("(c) Fudesumi sprite by Eiden Marsal", 310, screenHeight - 20, 10, Color.Brown);
EndDrawing();
//----------------------------------------------------------------------------------
game.Update();
}
game.Unload();
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadTexture(fudesumi);
UnloadTexture(checkedTex);
CloseWindow();
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;

View file

@ -0,0 +1,178 @@
/*******************************************************************************************
*
* raylib [textures] example - screen buffer
*
* Example complexity rating: [] 2/4
*
* Example originally created with raylib 5.5, last time updated with raylib 5.5
*
* Example contributed by Agnis Aldiņš (@nezvers) 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 Agnis Aldiņš (@nezvers)
*
********************************************************************************************/
namespace Examples.Textures;
public partial class ScreenBuffer : IExample
{
private const int screenWidth = 800;
private const int screenHeight = 450;
private const int MaxColors = 256;
private const int ScaleFactor = 2;
private const int imageWidth = screenWidth / ScaleFactor;
private const int imageHeight = screenHeight / ScaleFactor;
private const int flameWidth = screenWidth / ScaleFactor;
public string Name => "Textures / Screen Buffer";
public string Title => "raylib [textures] example - screen buffer";
private Color[] palette;
private byte[] indexBuffer;
private byte[] flameRootBuffer;
private Image screenImage;
private Texture2D screenTexture;
public void Init()
{
palette = new Color[MaxColors];
indexBuffer = new byte[imageWidth * imageWidth];
flameRootBuffer = new byte[flameWidth];
screenImage = GenImageColor(imageWidth, imageHeight, Color.Black);
screenTexture = LoadTextureFromImage(screenImage);
// Generate flame color palette
for (var i = 0; i < MaxColors; i++)
{
var t = (float)i / (float)(MaxColors - 1);
var hue = t * t;
var saturation = t;
var value = t;
palette[i] = ColorFromHSV(250.0f + 150.0f * hue, saturation, value);
}
}
public unsafe void Update()
{
// Update
//----------------------------------------------------------------------------------
// Grow flameRoot
for (var x = 2; x < flameWidth; x++)
{
var flame = (int)flameRootBuffer[x];
flame += GetRandomValue(0, 2);
flameRootBuffer[x] = (flame > 255) ? (byte)255 : (byte)flame;
}
// Transfer flameRoot to indexBuffer
for (var x = 0; x < flameWidth; x++)
{
var i = x + (imageHeight - 1) * imageWidth;
indexBuffer[i] = flameRootBuffer[x];
}
// Clear top row, because it can't move any higher
for (var x = 0; x < imageWidth; x++)
{
if (indexBuffer[x] != 0)
{
indexBuffer[x] = 0;
}
}
// Skip top row, it is already cleared
for (var y = 1; y < imageHeight; y++)
{
for (var x = 0; x < imageWidth; x++)
{
var i = x + y * imageWidth;
int colorIndex = indexBuffer[i];
if (colorIndex != 0)
{
// Move pixel a row above
indexBuffer[i] = 0;
var moveX = GetRandomValue(0, 2) - 1;
var newX = x + moveX;
if ((newX > 0) && (newX < imageWidth))
{
var iabove = i - imageWidth + moveX;
var decay = GetRandomValue(0, 3);
colorIndex -= (decay < colorIndex) ? decay : colorIndex;
indexBuffer[iabove] = (byte)colorIndex;
}
}
}
}
// Update screenImage with palette colors
for (var y = 1; y < imageHeight; y++)
{
for (var x = 0; x < imageWidth; x++)
{
var i = x + y * imageWidth;
int colorIndex = indexBuffer[i];
var col = palette[colorIndex];
ImageDrawPixel(ref screenImage, x, y, col);
}
}
UpdateTexture(screenTexture, screenImage.Data);
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
DrawTextureEx(screenTexture, new Vector2(0, 0), 0.0f, 2.0f, Color.White);
EndDrawing();
//----------------------------------------------------------------------------------
}
public void Unload()
{
UnloadTexture(screenTexture);
UnloadImage(screenImage);
}
public static int Main()
{
// Initialization
//--------------------------------------------------------------------------------------
InitWindow(screenWidth, screenHeight, "raylib [textures] example - screen buffer");
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
var game = new ScreenBuffer();
game.Init();
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
game.Update();
}
game.Unload();
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
}

View file

@ -1,122 +1,147 @@
/*******************************************************************************************
*
* raylib [textures] example - Texture loading and drawing a part defined by a rectangle
* raylib [textures] example - sprite animation
*
* This example has been created using raylib 1.3 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
* Example complexity rating: [] 2/4
*
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
* Example originally created with raylib 1.3, last time updated with raylib 1.3
*
* 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) 2014-2025 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
using System;
using System.Numerics;
using static Raylib_cs.Raylib;
namespace Examples.Textures;
public class SpriteAnim
public partial class SpriteAnim : IExample
{
private const int screenWidth = 800;
private const int screenHeight = 450;
public const int MaxFrameSpeed = 15;
public const int MinFrameSpeed = 1;
public string Name => "Textures / Sprite Anim";
public string Title => "raylib [textures] example - sprite animation";
private Texture2D scarfy;
private Vector2 position;
private Rectangle frameRec;
private int currentFrame;
private int framesCounter;
private int framesSpeed;
public void Init()
{
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
scarfy = LoadTexture("resources/scarfy.png"); // Texture loading
position = new(350.0f, 280.0f);
frameRec = new(0.0f, 0.0f, (float)scarfy.Width / 6, (float)scarfy.Height);
currentFrame = 0;
framesCounter = 0;
framesSpeed = 8; // Number of spritesheet frames shown by second
}
public void Update()
{
// Update
//----------------------------------------------------------------------------------
framesCounter++;
if (framesCounter >= (60 / framesSpeed))
{
framesCounter = 0;
currentFrame++;
if (currentFrame > 5)
{
currentFrame = 0;
}
frameRec.X = (float)currentFrame * (float)scarfy.Width / 6;
}
if (IsKeyPressed(KeyboardKey.Right))
{
framesSpeed++;
}
else if (IsKeyPressed(KeyboardKey.Left))
{
framesSpeed--;
}
framesSpeed = Math.Clamp(framesSpeed, MinFrameSpeed, MaxFrameSpeed);
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
DrawTexture(scarfy, 15, 40, Color.White);
DrawRectangleLines(15, 40, scarfy.Width, scarfy.Height, Color.Lime);
DrawRectangleLines(
15 + (int)frameRec.X,
40 + (int)frameRec.Y,
(int)frameRec.Width,
(int)frameRec.Height,
Color.Red
);
DrawText("FRAME SPEED: ", 165, 210, 10, Color.DarkGray);
DrawText($"{framesSpeed:D2} FPS", 575, 210, 10, Color.DarkGray);
DrawText("PRESS RIGHT/LEFT KEYS to CHANGE SPEED!", 290, 240, 10, Color.DarkGray);
for (var i = 0; i < MaxFrameSpeed; i++)
{
if (i < framesSpeed)
{
DrawRectangle(250 + 21 * i, 205, 20, 20, Color.Red);
}
DrawRectangleLines(250 + 21 * i, 205, 20, 20, Color.Maroon);
}
DrawTextureRec(scarfy, frameRec, position, Color.White); // Draw part of the texture
DrawText("(c) Scarfy sprite by Eiden Marsal", screenWidth - 200, screenHeight - 20, 10, Color.Gray);
EndDrawing();
//----------------------------------------------------------------------------------
}
public void Unload()
{
UnloadTexture(scarfy); // Texture unloading
}
public static int Main()
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [textures] example - sprite animation");
InitWindow(screenWidth, screenHeight, "raylib [texture] example - texture rectangle");
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
Texture2D scarfy = LoadTexture("resources/scarfy.png");
Vector2 position = new(350.0f, 280.0f);
Rectangle frameRec = new(0.0f, 0.0f, (float)scarfy.Width / 6, (float)scarfy.Height);
int currentFrame = 0;
int framesCounter = 0;
// Number of spritesheet frames shown by second
int framesSpeed = 8;
SetTargetFPS(60);
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
var game = new SpriteAnim();
game.Init();
// Main game loop
while (!WindowShouldClose())
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
framesCounter++;
if (framesCounter >= (60 / framesSpeed))
{
framesCounter = 0;
currentFrame++;
if (currentFrame > 5)
{
currentFrame = 0;
}
frameRec.X = (float)currentFrame * (float)scarfy.Width / 6;
}
if (IsKeyPressed(KeyboardKey.Right))
{
framesSpeed++;
}
else if (IsKeyPressed(KeyboardKey.Left))
{
framesSpeed--;
}
framesSpeed = Math.Clamp(framesSpeed, MinFrameSpeed, MaxFrameSpeed);
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
DrawTexture(scarfy, 15, 40, Color.White);
DrawRectangleLines(15, 40, scarfy.Width, scarfy.Height, Color.Lime);
DrawRectangleLines(
15 + (int)frameRec.X,
40 + (int)frameRec.Y,
(int)frameRec.Width,
(int)frameRec.Height,
Color.Red
);
DrawText("FRAME SPEED: ", 165, 210, 10, Color.DarkGray);
DrawText($"{framesSpeed:2F} FPS", 575, 210, 10, Color.DarkGray);
DrawText("PRESS RIGHT/LEFT KEYS to CHANGE SPEED!", 290, 240, 10, Color.DarkGray);
for (int i = 0; i < MaxFrameSpeed; i++)
{
if (i < framesSpeed)
{
DrawRectangle(250 + 21 * i, 205, 20, 20, Color.Red);
}
DrawRectangleLines(250 + 21 * i, 205, 20, 20, Color.Maroon);
}
// Draw part of the texture
DrawTextureRec(scarfy, frameRec, position, Color.White);
DrawText("(c) Scarfy sprite by Eiden Marsal", screenWidth - 200, screenHeight - 20, 10, Color.Gray);
EndDrawing();
//----------------------------------------------------------------------------------
game.Update();
}
game.Unload();
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadTexture(scarfy);
CloseWindow();
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;

View file

@ -2,43 +2,53 @@
*
* raylib [textures] example - sprite button
*
* This example has been created using raylib 2.5 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
* Example complexity rating: [] 2/4
*
* Copyright (c) 2019 Ramon Santamaria (@raysan5)
* Example originally created with raylib 2.5, last time updated with raylib 2.5
*
* 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 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
using System.Numerics;
using static Raylib_cs.Raylib;
namespace Examples.Textures;
public class SpriteButton
public partial class SpriteButton : IExample
{
// Number of frames (rectangles) for the button sprite texture
public const int NumFrames = 3;
public static int Main()
private const int screenWidth = 800;
private const int screenHeight = 450;
public string Name => "Textures / Sprite Button";
public string Title => "raylib [textures] example - sprite button";
private Sound fxButton;
private Texture2D button;
private int frameHeight;
private Rectangle sourceRec;
private Rectangle btnBounds;
private int btnState;
private bool btnAction;
private Vector2 mousePoint;
public void Init()
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitAudioDevice(); // Initialize audio device
InitWindow(screenWidth, screenHeight, "raylib [textures] example - sprite button");
InitAudioDevice();
Sound fxButton = LoadSound("resources/audio/buttonfx.wav");
Texture2D button = LoadTexture("resources/button.png");
fxButton = LoadSound("resources/audio/buttonfx.wav"); // Load button sound
button = LoadTexture("resources/button.png"); // Load button texture
// Define frame rectangle for drawing
int frameHeight = button.Height / NumFrames;
Rectangle sourceRec = new(0, 0, button.Width, frameHeight);
frameHeight = button.Height / NumFrames;
sourceRec = new(0, 0, button.Width, frameHeight);
// Define button bounds on screen
Rectangle btnBounds = new(
btnBounds = new(
screenWidth / 2 - button.Width / 2,
screenHeight / 2 - button.Height / NumFrames / 2,
button.Width,
@ -46,75 +56,95 @@ public class SpriteButton
);
// Button state: 0-NORMAL, 1-MOUSE_HOVER, 2-PRESSED
int btnState = 0;
btnState = 0;
// Button action should be activated
bool btnAction = false;
btnAction = false;
Vector2 mousePoint = new(0.0f, 0.0f);
mousePoint = new(0.0f, 0.0f);
}
public void Update()
{
// Update
//----------------------------------------------------------------------------------
mousePoint = GetMousePosition();
btnAction = false;
// Check button state
if (CheckCollisionPointRec(mousePoint, btnBounds))
{
if (IsMouseButtonDown(MouseButton.Left))
{
btnState = 2;
}
else
{
btnState = 1;
}
if (IsMouseButtonReleased(MouseButton.Left))
{
btnAction = true;
}
}
else
{
btnState = 0;
}
if (btnAction)
{
PlaySound(fxButton);
// TODO: Any desired action
}
// Calculate button frame rectangle to draw depending on button state
sourceRec.Y = btnState * frameHeight;
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
DrawTextureRec(button, sourceRec, new Vector2(btnBounds.X, btnBounds.Y), Color.White); // Draw button frame
EndDrawing();
//----------------------------------------------------------------------------------
}
public void Unload()
{
UnloadTexture(button); // Unload button texture
UnloadSound(fxButton); // Unload sound
CloseAudioDevice(); // Close audio device
}
public static int Main()
{
// Initialization
//--------------------------------------------------------------------------------------
InitWindow(screenWidth, screenHeight, "raylib [textures] example - sprite button");
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
var game = new SpriteButton();
game.Init();
// Main game loop
while (!WindowShouldClose())
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
mousePoint = GetMousePosition();
btnAction = false;
// Check button state
if (CheckCollisionPointRec(mousePoint, btnBounds))
{
if (IsMouseButtonDown(MouseButton.Left))
{
btnState = 2;
}
else
{
btnState = 1;
}
if (IsMouseButtonReleased(MouseButton.Left))
{
btnAction = true;
}
}
else
{
btnState = 0;
}
if (btnAction)
{
PlaySound(fxButton);
// TODO: Any desired action
}
// Calculate button frame rectangle to draw depending on button state
sourceRec.Y = btnState * frameHeight;
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
// Draw button frame
DrawTextureRec(button, sourceRec, new Vector2(btnBounds.X, btnBounds.Y), Color.White);
EndDrawing();
//----------------------------------------------------------------------------------
game.Update();
}
game.Unload();
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadTexture(button);
UnloadSound(fxButton);
CloseAudioDevice();
CloseWindow();
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;

View file

@ -2,129 +2,157 @@
*
* raylib [textures] example - sprite explosion
*
* This example has been created using raylib 2.5 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
* Example complexity rating: [] 2/4
*
* Copyright (c) 2019 Anata and Ramon Santamaria (@raysan5)
* Example originally created with raylib 2.5, last time updated with raylib 3.5
*
* 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 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
using System.Numerics;
using static Raylib_cs.Raylib;
namespace Examples.Textures;
public class SpriteExplosion
public partial class SpriteExplosion : IExample
{
const int NumFramesPerLine = 5;
const int NumLines = 5;
private const int NumFramesPerLine = 5;
private const int NumLines = 5;
private const int screenWidth = 800;
private const int screenHeight = 450;
public string Name => "Textures / Sprite Explosion";
public string Title => "raylib [textures] example - sprite explosion";
private Sound fxBoom;
private Texture2D explosion;
private int frameWidth;
private int frameHeight;
private int currentFrame;
private int currentLine;
private Rectangle frameRec;
private Vector2 position;
private bool active;
private int framesCounter;
public void Init()
{
InitAudioDevice();
// Load explosion sound
fxBoom = LoadSound("resources/audio/boom.wav");
// Load explosion texture
explosion = LoadTexture("resources/explosion.png");
// Init variables for animation
frameWidth = explosion.Width / NumFramesPerLine; // Sprite one frame rectangle width
frameHeight = explosion.Height / NumLines; // Sprite one frame rectangle height
currentFrame = 0;
currentLine = 0;
frameRec = new(0, 0, frameWidth, frameHeight);
position = new(0.0f, 0.0f);
active = false;
framesCounter = 0;
}
public void Update()
{
// Update
//----------------------------------------------------------------------------------
// Check for mouse button pressed and activate explosion (if not active)
if (IsMouseButtonPressed(MouseButton.Left) && !active)
{
position = GetMousePosition();
active = true;
position.X -= frameWidth / 2;
position.Y -= frameHeight / 2;
PlaySound(fxBoom);
}
// Compute explosion animation frames
if (active)
{
framesCounter++;
if (framesCounter > 2)
{
currentFrame++;
if (currentFrame >= NumFramesPerLine)
{
currentFrame = 0;
currentLine++;
if (currentLine >= NumLines)
{
currentLine = 0;
active = false;
}
}
framesCounter = 0;
}
}
frameRec.X = frameWidth * currentFrame;
frameRec.Y = frameHeight * currentLine;
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
// Draw explosion required frame rectangle
if (active)
{
DrawTextureRec(explosion, frameRec, position, Color.White);
}
EndDrawing();
//----------------------------------------------------------------------------------
}
public void Unload()
{
UnloadTexture(explosion); // Unload texture
UnloadSound(fxBoom); // Unload sound
CloseAudioDevice();
}
public static int Main()
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [textures] example - sprite explosion");
InitAudioDevice();
// Load explosion sound
Sound fxBoom = LoadSound("resources/audio/boom.wav");
// Load explosion texture
Texture2D explosion = LoadTexture("resources/explosion.png");
// Init variables for animation
// Sprite one frame rectangle width
int frameWidth = explosion.Width / NumFramesPerLine;
// Sprite one frame rectangle height
int frameHeight = explosion.Height / NumLines;
int currentFrame = 0;
int currentLine = 0;
Rectangle frameRec = new(0, 0, frameWidth, frameHeight);
Vector2 position = new(0.0f, 0.0f);
bool active = false;
int framesCounter = 0;
SetTargetFPS(120);
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
var game = new SpriteExplosion();
game.Init();
// Main game loop
while (!WindowShouldClose())
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
// Check for mouse button pressed and activate explosion (if not active)
if (IsMouseButtonPressed(MouseButton.Left) && !active)
{
position = GetMousePosition();
active = true;
position.X -= frameWidth / 2;
position.Y -= frameHeight / 2;
PlaySound(fxBoom);
}
// Compute explosion animation frames
if (active)
{
framesCounter++;
if (framesCounter > 2)
{
currentFrame++;
if (currentFrame >= NumFramesPerLine)
{
currentFrame = 0;
currentLine++;
if (currentLine >= NumLines)
{
currentLine = 0;
active = false;
}
}
framesCounter = 0;
}
}
frameRec.X = frameWidth * currentFrame;
frameRec.Y = frameHeight * currentLine;
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
// Draw explosion required frame rectangle
if (active)
{
DrawTextureRec(explosion, frameRec, position, Color.White);
}
EndDrawing();
//----------------------------------------------------------------------------------
game.Update();
}
game.Unload();
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadTexture(explosion);
UnloadSound(fxBoom);
CloseAudioDevice();
CloseWindow();
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;

View file

@ -0,0 +1,137 @@
/*******************************************************************************************
*
* raylib [textures] example - sprite stacking
*
* Example complexity rating: [] 2/4
*
* Example originally created with raylib 6.0, last time updated with raylib 6.0
*
* Example contributed by Robin (@RobinsAviary) 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
*
* Redbooth model (c) 2017-2025 @kluchek under https://creativecommons.org/licenses/by/4.0/ https://github.com/kluchek/vox-models/
* Copyright (c) 2025 Robin (@RobinsAviary)
*
********************************************************************************************/
namespace Examples.Textures;
public partial class SpriteStacking : IExample
{
private const int screenWidth = 800;
private const int screenHeight = 450;
private const float speedChange = 0.25f; // Amount speed will change by when the user presses A/D
public string Name => "Textures / Sprite Stacking";
public string Title => "raylib [textures] example - sprite stacking";
private Texture2D booth;
private float stackScale; // Overall scale of the stacked sprite
private float stackSpacing; // Vertical spacing between each layer
private uint stackCount; // Number of layers, used for calculating the size of a single slice
private float rotationSpeed; // Stacked sprites rotation speed
private float rotation; // Current rotation of the stacked sprite
public void Init()
{
booth = LoadTexture("resources/booth.png");
stackScale = 3.0f;
stackSpacing = 2.0f;
stackCount = 122;
rotationSpeed = 30.0f;
rotation = 0.0f;
}
public void Update()
{
// Update
//----------------------------------------------------------------------------------
// Use mouse wheel to affect stack separation
stackSpacing += GetMouseWheelMove() * 0.1f;
stackSpacing = Math.Clamp(stackSpacing, 0.0f, 5.0f);
// Add a positive/negative offset to spin right/left at different speeds
if (IsKeyDown(KeyboardKey.Left) || IsKeyDown(KeyboardKey.A))
{
rotationSpeed -= speedChange;
}
if (IsKeyDown(KeyboardKey.Right) || IsKeyDown(KeyboardKey.D))
{
rotationSpeed += speedChange;
}
rotation += rotationSpeed * GetFrameTime();
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
// Get the size of a single slice
var frameWidth = (float)booth.Width;
var frameHeight = (float)booth.Height / (float)stackCount;
// Get the scaled resolution to draw at
var scaledWidth = frameWidth * stackScale;
var scaledHeight = frameHeight * stackScale;
// Draw the stacked sprite, rotated to the correct angle, with an vertical offset applied based on its y location
for (var i = (int)stackCount - 1; i >= 0; i--)
{
// Center vertically
Rectangle source = new(0.0f, (float)i * frameHeight, frameWidth, frameHeight);
Rectangle dest = new(screenWidth / 2.0f, (screenHeight / 2.0f) + (i * stackSpacing) - (stackSpacing * stackCount / 2.0f), scaledWidth, scaledHeight);
Vector2 origin = new(scaledWidth / 2.0f, scaledHeight / 2.0f);
DrawTexturePro(booth, source, dest, origin, rotation, Color.White);
}
DrawText("A/D to spin\nmouse wheel to change separation (aka 'angle')", 10, 10, 20, Color.DarkGray);
DrawText($"current spacing: {stackSpacing:F1}", 10, 50, 20, Color.DarkGray);
DrawText($"current speed: {rotationSpeed:F2}", 10, 70, 20, Color.DarkGray);
DrawText("redbooth model (c) kluchek under cc 4.0", 10, 420, 20, Color.DarkGray);
EndDrawing();
//----------------------------------------------------------------------------------
}
public void Unload()
{
UnloadTexture(booth);
}
public static int Main()
{
// Initialization
//--------------------------------------------------------------------------------------
InitWindow(screenWidth, screenHeight, "raylib [textures] example - sprite stacking");
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
var game = new SpriteStacking();
game.Init();
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
game.Update();
}
game.Unload();
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
}

View file

@ -1,85 +1,112 @@
/*******************************************************************************************
*
* raylib [textures] example - Texture source and destination rectangles
* raylib [textures] example - srcrec dstrec
*
* This example has been created using raylib 1.3 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
* Example complexity rating: [] 3/4
*
* Copyright (c) 2015 Ramon Santamaria (@raysan5)
* Example originally created with raylib 1.3, last time updated with raylib 1.3
*
* 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) 2015-2025 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
using System.Numerics;
using static Raylib_cs.Raylib;
namespace Examples.Textures;
public class SrcRecDstRec
public partial class SrcRecDstRec : IExample
{
private const int screenWidth = 800;
private const int screenHeight = 450;
public string Name => "Textures / Src and Dst Rectangles";
public string Title => "raylib [textures] example - srcrec dstrec";
private Texture2D scarfy;
private Rectangle sourceRec;
private Rectangle destRec;
private Vector2 origin;
private int rotation;
public void Init()
{
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
scarfy = LoadTexture("resources/scarfy.png"); // Texture loading
var frameWidth = scarfy.Width / 6;
var frameHeight = scarfy.Height;
// Source rectangle (part of the texture to use for drawing)
sourceRec = new(0, 0, frameWidth, frameHeight);
// Destination rectangle (screen rectangle where drawing part of texture)
destRec = new(screenWidth / 2, screenHeight / 2, frameWidth * 2, frameHeight * 2);
// Origin of the texture (rotation/scale point), it's relative to destination rectangle size
origin = new(frameWidth, frameHeight);
rotation = 0;
}
public void Update()
{
// Update
//----------------------------------------------------------------------------------
rotation++;
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
// NOTE: Using DrawTexturePro() we can easily rotate and scale the part of the texture we draw
// sourceRec defines the part of the texture we use for drawing
// destRec defines the rectangle where our texture part will fit (scaling it to fit)
// origin defines the point of the texture used as reference for rotation and scaling
// rotation defines the texture rotation (using origin as rotation point)
DrawTexturePro(scarfy, sourceRec, destRec, origin, rotation, Color.White);
DrawLine((int)destRec.X, 0, (int)destRec.X, screenHeight, Color.Gray);
DrawLine(0, (int)destRec.Y, screenWidth, (int)destRec.Y, Color.Gray);
DrawText("(c) Scarfy sprite by Eiden Marsal", screenWidth - 200, screenHeight - 20, 10, Color.Gray);
EndDrawing();
//----------------------------------------------------------------------------------
}
public void Unload()
{
UnloadTexture(scarfy); // Texture unloading
}
public static int Main()
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
string title = "raylib [textures] examples - texture source and destination rectangles";
InitWindow(screenWidth, screenHeight, title);
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
Texture2D scarfy = LoadTexture("resources/scarfy.png");
int frameWidth = scarfy.Width / 6;
int frameHeight = scarfy.Height;
// NOTE: Source rectangle (part of the texture to use for drawing)
Rectangle sourceRec = new(0, 0, frameWidth, frameHeight);
// NOTE: Destination rectangle (screen rectangle where drawing part of texture)
Rectangle destRec = new(screenWidth / 2, screenHeight / 2, frameWidth * 2, frameHeight * 2);
// NOTE: Origin of the texture (rotation/scale point), it's relative to destination rectangle size
Vector2 origin = new(frameWidth, frameHeight);
int rotation = 0;
InitWindow(screenWidth, screenHeight, "raylib [textures] example - srcrec dstrec");
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
var game = new SrcRecDstRec();
game.Init();
// Main game loop
while (!WindowShouldClose())
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
rotation++;
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
// NOTE: Using DrawTexturePro() we can easily rotate and scale the part of the texture we draw
// sourceRec defines the part of the texture we use for drawing
// destRec defines the rectangle where our texture part will fit (scaling it to fit)
// origin defines the point of the texture used as reference for rotation and scaling
// rotation defines the texture rotation (using origin as rotation point)
DrawTexturePro(scarfy, sourceRec, destRec, origin, rotation, Color.White);
DrawLine((int)destRec.X, 0, (int)destRec.X, screenHeight, Color.Gray);
DrawLine(0, (int)destRec.Y, screenWidth, (int)destRec.Y, Color.Gray);
DrawText("(c) Scarfy sprite by Eiden Marsal", screenWidth - 200, screenHeight - 20, 10, Color.Gray);
EndDrawing();
//----------------------------------------------------------------------------------
game.Update();
}
game.Unload();
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadTexture(scarfy);
CloseWindow();
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;

View file

@ -1,11 +1,33 @@
using System;
using System.Numerics;
using static Raylib_cs.Raylib;
/*******************************************************************************************
*
* raylib [textures] example - textured curve
*
* Example complexity rating: [] 3/4
*
* Example originally created with raylib 4.5, last time updated with raylib 4.5
*
* 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) and Ramon Santamaria (@raysan5)
*
********************************************************************************************/
namespace Examples.Textures;
public unsafe class TexturedCurve
public unsafe partial class TexturedCurve : IExample
{
private const int screenWidth = 800;
private const int screenHeight = 450;
public string Name => "Textures / Textured Curve";
public string Title => "raylib [textures] example - textured curve";
public ConfigFlags ConfigFlags => ConfigFlags.VSyncHint | ConfigFlags.Msaa4xHint;
public class CurvePoint
{
public Vector2 value;
@ -17,26 +39,18 @@ public unsafe class TexturedCurve
public static implicit operator Vector2(CurvePoint v) => v.value;
}
static Texture2D texRoad;
static bool showCurve = false;
static float curveWidth = 50;
static int curveSegments = 24;
static CurvePoint curveStartPosition;
static CurvePoint curveStartPositionTangent;
static CurvePoint curveEndPosition;
static CurvePoint curveEndPositionTangent;
static CurvePoint curveSelectedPoint;
private Texture2D texRoad;
private bool showCurve;
private float curveWidth;
private int curveSegments;
private CurvePoint curveStartPosition;
private CurvePoint curveStartPositionTangent;
private CurvePoint curveEndPosition;
private CurvePoint curveEndPositionTangent;
private CurvePoint curveSelectedPoint;
public static int Main()
public void Init()
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
SetConfigFlags(ConfigFlags.VSyncHint | ConfigFlags.Msaa4xHint);
InitWindow(screenWidth, screenHeight, "raylib [textures] examples - textured curve");
// Load the road texture
texRoad = LoadTexture("resources/road.png");
SetTextureFilter(texRoad, TextureFilter.Bilinear);
@ -48,45 +62,42 @@ public unsafe class TexturedCurve
curveEndPosition = new Vector2(700, 350);
curveEndPositionTangent = new Vector2(600, 100);
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose())
{
// Update
//----------------------------------------------------------------------------------
UpdateCurve();
UpdateOptions();
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
DrawTexturedCurve();
DrawCurve();
DrawText("Drag points to move curve, press SPACE to show/hide base curve", 10, 10, 10, Color.DarkGray);
DrawText($"Curve width: {curveWidth} (Use + and - to adjust)", 10, 30, 10, Color.DarkGray);
DrawText($"Curve segments: {curveSegments} (Use LEFT and RIGHT to adjust)", 10, 50, 10, Color.DarkGray);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadTexture(texRoad);
CloseWindow();
//--------------------------------------------------------------------------------------
return 0;
showCurve = false;
curveWidth = 50;
curveSegments = 24;
curveSelectedPoint = null;
}
static void DrawCurve()
public void Update()
{
// Update
//----------------------------------------------------------------------------------
UpdateCurve();
UpdateOptions();
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
DrawTexturedCurve();
DrawCurve();
DrawText("Drag points to move curve, press SPACE to show/hide base curve", 10, 10, 10, Color.DarkGray);
DrawText($"Curve width: {curveWidth} (Use + and - to adjust)", 10, 30, 10, Color.DarkGray);
DrawText($"Curve segments: {curveSegments} (Use LEFT and RIGHT to adjust)", 10, 50, 10, Color.DarkGray);
EndDrawing();
//----------------------------------------------------------------------------------
}
public void Unload()
{
UnloadTexture(texRoad);
}
private void DrawCurve()
{
if (showCurve)
{
@ -104,7 +115,7 @@ public unsafe class TexturedCurve
DrawLineV(curveStartPosition, curveStartPositionTangent, Color.SkyBlue);
DrawLineV(curveStartPositionTangent, curveEndPositionTangent, Fade(Color.LightGray, 0.4f));
DrawLineV(curveEndPosition, curveEndPositionTangent, Color.Purple);
Vector2 mouse = GetMousePosition();
var mouse = GetMousePosition();
if (CheckCollisionPointCircle(mouse, curveStartPosition, 6))
{
@ -131,11 +142,12 @@ public unsafe class TexturedCurve
DrawCircleV(curveEndPositionTangent, 5, Color.DarkGreen);
}
static void UpdateCurve()
private void UpdateCurve()
{
// If the mouse is not down, we are not editing the curve so clear the selection
if (!IsMouseButtonDown(MouseButton.Left))
{
curveSelectedPoint = null;
return;
}
@ -146,7 +158,7 @@ public unsafe class TexturedCurve
}
// The mouse is down, and nothing was selected, so see if anything was picked
Vector2 mouse = GetMousePosition();
var mouse = GetMousePosition();
if (CheckCollisionPointCircle(mouse, curveStartPosition, 6))
{
@ -166,28 +178,28 @@ public unsafe class TexturedCurve
}
}
static void DrawTexturedCurve()
private void DrawTexturedCurve()
{
float step = 1.0f / curveSegments;
var step = 1.0f / curveSegments;
Vector2 previous = curveStartPosition;
Vector2 previousTangent = Vector2.Zero;
var previousTangent = Vector2.Zero;
float previousV = 0;
// We can't compute a tangent for the first point, so we need to reuse the tangent from the first segment
bool tangentSet = false;
var tangentSet = false;
Vector2 current = Vector2.Zero;
float t = 0.0f;
var current = Vector2.Zero;
var t = 0.0f;
for (int i = 1; i <= curveSegments; i++)
for (var i = 1; i <= curveSegments; i++)
{
// Segment the curve
t = step * i;
float a = MathF.Pow(1 - t, 3);
float b = 3 * MathF.Pow(1 - t, 2) * t;
float c = 3 * (1 - t) * MathF.Pow(t, 2);
float d = MathF.Pow(t, 3);
var a = MathF.Pow(1 - t, 3);
var b = 3 * MathF.Pow(1 - t, 2) * t;
var c = 3 * (1 - t) * MathF.Pow(t, 2);
var d = MathF.Pow(t, 3);
// Compute the endpoint for this segment
current.Y = a * curveStartPosition.Y + b * curveStartPositionTangent.Y;
@ -199,10 +211,10 @@ public unsafe class TexturedCurve
Vector2 delta = new(current.X - previous.X, current.Y - previous.Y);
// The right hand normal to the delta vector
Vector2 normal = Vector2.Normalize(new Vector2(-delta.Y, delta.X));
var normal = Vector2.Normalize(new Vector2(-delta.Y, delta.X));
// The v teXture coordinate of the segment (add up the length of all the segments so far)
float v = previousV + delta.Length();
// The v texture coordinate of the segment (add up the length of all the segments so far)
var v = previousV + delta.Length() / (texRoad.Height * 2);
// Make sure the start point has a normal
if (!tangentSet)
@ -211,12 +223,12 @@ public unsafe class TexturedCurve
tangentSet = true;
}
// EXtend out the normals from the previous and current points to get the quad for this segment
Vector2 prevPosNormal = previous + (previousTangent * curveWidth);
Vector2 prevNegNormal = previous + (previousTangent * -curveWidth);
// Extend out the normals from the previous and current points to get the quad for this segment
var prevPosNormal = previous + (previousTangent * curveWidth);
var prevNegNormal = previous + (previousTangent * -curveWidth);
Vector2 currentPosNormal = current + (normal * curveWidth);
Vector2 currentNegNormal = current + (normal * -curveWidth);
var currentPosNormal = current + (normal * curveWidth);
var currentNegNormal = current + (normal * -curveWidth);
// Draw the segment as a quad
Rlgl.SetTexture(texRoad.Id);
@ -239,21 +251,21 @@ public unsafe class TexturedCurve
Rlgl.End();
// The current step is the start of the neXt step
// The current step is the start of the next step
previous = current;
previousTangent = normal;
previousV = v;
}
}
static void UpdateOptions()
private void UpdateOptions()
{
if (IsKeyPressed(KeyboardKey.Space))
{
showCurve = !showCurve;
}
// Update with
// Update width
if (IsKeyPressed(KeyboardKey.Equal))
{
curveWidth += 2;
@ -282,4 +294,33 @@ public unsafe class TexturedCurve
curveSegments = 2;
}
}
public static int Main()
{
// Initialization
//--------------------------------------------------------------------------------------
SetConfigFlags(ConfigFlags.VSyncHint | ConfigFlags.Msaa4xHint);
InitWindow(screenWidth, screenHeight, "raylib [textures] example - textured curve");
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
var game = new TexturedCurve();
game.Init();
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
game.Update();
}
game.Unload();
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
}

View file

@ -1,72 +1,93 @@
/*******************************************************************************************
*
* raylib [textures] example - Retrieve image data from texture: GetTextureData()
* raylib [textures] example - to image
*
* Example complexity rating: [] 1/4
*
* NOTE: Images are loaded in CPU memory (RAM); textures are loaded in GPU memory (VRAM)
*
* This example has been created using raylib 1.3 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
* Example originally created with raylib 1.3, last time updated with raylib 4.0
*
* Copyright (c) 2015 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) 2015-2025 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
using static Raylib_cs.Raylib;
namespace Examples.Textures;
public class ToImage
public partial class ToImage : IExample
{
private const int screenWidth = 800;
private const int screenHeight = 450;
public string Name => "Textures / Texture to Image";
public string Title => "raylib [textures] example - to image";
private Texture2D texture;
public void Init()
{
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
var image = LoadImage("resources/raylib-cs_logo.png"); // Load image data into CPU memory (RAM)
texture = LoadTextureFromImage(image); // Image converted to texture, GPU memory (RAM -> VRAM)
UnloadImage(image); // Unload image data from CPU memory (RAM)
image = LoadImageFromTexture(texture); // Load image from GPU texture (VRAM -> RAM)
UnloadTexture(texture); // Unload texture from GPU memory (VRAM)
texture = LoadTextureFromImage(image); // Recreate texture from retrieved image data (RAM -> VRAM)
UnloadImage(image); // Unload retrieved image data from CPU memory (RAM)
}
public void Update()
{
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
var x = screenWidth / 2 - texture.Width / 2;
var y = screenHeight / 2 - texture.Height / 2;
DrawTexture(texture, x, y, Color.White);
DrawText("this IS a texture loaded from an image!", 300, 370, 10, Color.Gray);
EndDrawing();
//----------------------------------------------------------------------------------
}
public void Unload()
{
UnloadTexture(texture); // Texture unloading
}
public static int Main()
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [textures] example - to image");
InitWindow(screenWidth, screenHeight, "raylib [textures] example - texture to image");
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
Image image = LoadImage("resources/raylib-cs_logo.png");
Texture2D texture = LoadTextureFromImage(image);
UnloadImage(image);
image = LoadImageFromTexture(texture);
UnloadTexture(texture);
texture = LoadTextureFromImage(image);
UnloadImage(image);
//---------------------------------------------------------------------------------------
var game = new ToImage();
game.Init();
// Main game loop
while (!WindowShouldClose())
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
// TODO: Update your variables here
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
int x = screenWidth / 2 - texture.Width / 2;
int y = screenHeight / 2 - texture.Height / 2;
DrawTexture(texture, x, y, Color.White);
DrawText("this IS a texture loaded from an image!", 300, 370, 10, Color.Gray);
EndDrawing();
//----------------------------------------------------------------------------------
game.Update();
}
game.Unload();
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadTexture(texture);
CloseWindow();
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;