feat: backporting existing raylib-cs examples and new official raylib examples to WASM, adopting raylib's original code style
This commit is contained in:
parent
768fa93c41
commit
732b7aa346
234 changed files with 38999 additions and 10578 deletions
|
|
@ -1,11 +1,15 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
|
@ -14,101 +18,126 @@ 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;
|
||||
|
|
|
|||
|
|
@ -2,14 +2,18 @@
|
|||
*
|
||||
* 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)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
|
@ -17,99 +21,128 @@ 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;
|
||||
|
|
|
|||
|
|
@ -1,12 +1,15 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
|
@ -16,8 +19,11 @@ 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 +34,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 +56,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();
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
|
|
|
|||
248
Examples/Textures/CellularAutomata.cs
Normal file
248
Examples/Textures/CellularAutomata.cs
Normal file
|
|
@ -0,0 +1,248 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
144
Examples/Textures/ClipboardImage.cs
Normal file
144
Examples/Textures/ClipboardImage.cs
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using System.Numerics;
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,17 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
|
@ -14,53 +20,69 @@ 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 +103,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 +311,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 +350,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 +394,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 +440,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 +489,3 @@ public class DrawTiled
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
233
Examples/Textures/FogOfWar.cs
Normal file
233
Examples/Textures/FogOfWar.cs
Normal file
|
|
@ -0,0 +1,233 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using System.Numerics;
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
248
Examples/Textures/FramebufferRendering.cs
Normal file
248
Examples/Textures/FramebufferRendering.cs
Normal file
|
|
@ -0,0 +1,248 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* 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 System.Numerics;
|
||||
using static Raylib_cs.Raylib;
|
||||
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;
|
||||
}
|
||||
}
|
||||
171
Examples/Textures/GifPlayer.cs
Normal file
171
Examples/Textures/GifPlayer.cs
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
149
Examples/Textures/ImageChannel.cs
Normal file
149
Examples/Textures/ImageChannel.cs
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using System.Numerics;
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +1,17 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
|
@ -16,85 +20,99 @@ 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;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,17 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
|
@ -13,104 +19,147 @@ 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();
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
|
|
|
|||
165
Examples/Textures/ImageKernel.cs
Normal file
165
Examples/Textures/ImageKernel.cs
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +1,17 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
|
@ -15,56 +19,74 @@ 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;
|
||||
|
|
|
|||
|
|
@ -1,13 +1,17 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
|
@ -15,11 +19,18 @@ 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 +43,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;
|
||||
|
|
|
|||
121
Examples/Textures/ImageRotate.cs
Normal file
121
Examples/Textures/ImageRotate.cs
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,15 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
|
@ -14,21 +18,26 @@ 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 +47,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;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,15 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
|
@ -13,52 +17,71 @@ 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;
|
||||
|
|
|
|||
160
Examples/Textures/MagnifyingGlass.cs
Normal file
160
Examples/Textures/MagnifyingGlass.cs
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using System.Numerics;
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +1,17 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
|
@ -16,48 +20,66 @@ 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 +87,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;
|
||||
|
|
|
|||
|
|
@ -1,15 +1,19 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
|
@ -19,31 +23,46 @@ 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 +71,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 +81,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 +92,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 +102,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;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,15 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
|
@ -14,12 +18,19 @@ 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 +41,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 +67,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;
|
||||
|
|
|
|||
|
|
@ -1,12 +1,17 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
|
@ -15,37 +20,43 @@ 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 +64,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 +116,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 +130,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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,17 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
|
@ -15,98 +19,125 @@ 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;
|
||||
|
|
|
|||
181
Examples/Textures/ScreenBuffer.cs
Normal file
181
Examples/Textures/ScreenBuffer.cs
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using System.Numerics;
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,15 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
|
@ -15,108 +19,133 @@ 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;
|
||||
|
|
|
|||
|
|
@ -2,10 +2,14 @@
|
|||
*
|
||||
* 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)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
|
@ -14,31 +18,40 @@ 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 +59,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;
|
||||
|
|
|
|||
|
|
@ -2,10 +2,14 @@
|
|||
*
|
||||
* 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)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
|
@ -14,117 +18,144 @@ 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;
|
||||
|
|
|
|||
140
Examples/Textures/SpriteStacking.cs
Normal file
140
Examples/Textures/SpriteStacking.cs
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using System.Numerics;
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,15 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
|
@ -14,72 +18,98 @@ 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;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,37 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Numerics;
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
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 +43,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 +66,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 +119,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 +146,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 +162,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 +182,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 +215,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 +227,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 +255,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 +298,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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,17 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
|
@ -15,58 +19,77 @@ 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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue