WASM examples (+ backports of new official examples) (#344)
* chg: New build system that uses the officially distributed binaries, bumped version to 8.0.0, simplified git workflow, removed deprecated OpenGL 1.1 functionality. * chg: Modernize CI workflow, enable SourceLink - Bump workflow actions to latest majors (Node 24); drop deprecated softprops/action-gh-release@v1 - Trigger push builds on main instead of master - Create local nuget feed dir before pack (fixes NU1301) - Enable Microsoft.SourceLink.GitHub for debugging symbols (ref PR #340) * fix: centralized version data in Directory.build.props, and fixed various interop details that had incorrect function signatures * chore: updated readme * fix: version the native extract marker and chain download via DependsOnTargets The .extracted marker now includes the raylib package name, so bumping TargetRaylibTag re-extracts the new archive instead of silently keeping (and packing/copying) the previous version's files. _PrepareNativeLibrary and _StageWasmNative now depend directly on _DownloadAndExtractInternal instead of CallTarget-ing it; dependency targets run in the same project instance, so the resolved properties (RaylibPackageName etc.) propagate naturally. * fix: let the binding build for browser-wasm on both net8.0 and net10.0 The net8-era wasm workload (Microsoft.NET.Runtime.WebAssembly.Sdk 8.0.x, auto-imported for RID browser-wasm) treats every browser-wasm project as a wasm app: it forces OutputType=Exe after project evaluation (CS5001 for a classlib) and hooks its app-bundle build after Build, which errors because a library has no assemblies to bundle. Opt Raylib-cs out via DisableAutoWasmBuildApp (props time, before the workload defaults its trigger) and pin OutputType back to Library in Directory.Build.targets (evaluated after the workload props, so the assignment wins). net10's wasm SDK needs neither workaround. * chore: readme updated * chg: simplifying build logic - a simple line in the documentation should save us the code here * fix: Wrong signature of FrameBufferComplete * chore: readme update * feat: samples default to local project reference, and can optionally use the nuget package * feat: backporting existing raylib-cs examples and new official raylib examples to WASM, adopting raylib's original code style * chore: readme, gitignore, and targets backport. * fix: Examples.csproj runs the download task when building locally * feat: backporting existing raylib-cs examples and new official raylib examples to WASM, adopting raylib's original code style * chore: readme, gitignore, and targets backport. * chore: clean up linter warnings * feat: html harness focuses the example and allows quick navigation with J/K instead. * chore: readme mentions the property to use nuget vs. the local project reference * feat: replaced the J/K navigation with good old HTML buttons * chore: run dotnet format scoped default (was previously scoped to just 'style')
This commit is contained in:
parent
b207e633ae
commit
8c22e68c2a
236 changed files with 40405 additions and 10896 deletions
|
|
@ -1,114 +1,140 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [textures] example - Background scrolling
|
||||
* raylib [textures] example - background scrolling
|
||||
*
|
||||
* This example has been created using raylib 2.0 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
* Example complexity rating: [★☆☆☆] 1/4
|
||||
*
|
||||
* Copyright (c) 2019 Ramon Santamaria (@raysan5)
|
||||
* Example originally created with raylib 2.0, last time updated with raylib 2.5
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2019-2025 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using System.Numerics;
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
namespace Examples.Textures;
|
||||
|
||||
public class BackgroundScrolling
|
||||
public partial class BackgroundScrolling : IExample
|
||||
{
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
public string Name => "Textures / Background Scrolling";
|
||||
|
||||
public string Title => "raylib [textures] example - background scrolling";
|
||||
|
||||
private Texture2D background;
|
||||
private Texture2D midground;
|
||||
private Texture2D foreground;
|
||||
|
||||
private float scrollingBack;
|
||||
private float scrollingMid;
|
||||
private float scrollingFore;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
// NOTE: Be careful, background width must be equal or bigger than screen width
|
||||
// if not, texture should be draw more than two times for scrolling effect
|
||||
background = LoadTexture("resources/cyberpunk_street_background.png");
|
||||
midground = LoadTexture("resources/cyberpunk_street_midground.png");
|
||||
foreground = LoadTexture("resources/cyberpunk_street_foreground.png");
|
||||
|
||||
scrollingBack = 0.0f;
|
||||
scrollingMid = 0.0f;
|
||||
scrollingFore = 0.0f;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
scrollingBack -= 0.1f;
|
||||
scrollingMid -= 0.5f;
|
||||
scrollingFore -= 1.0f;
|
||||
|
||||
// NOTE: Texture is scaled twice its size, so it sould be considered on scrolling
|
||||
if (scrollingBack <= -background.Width * 2)
|
||||
{
|
||||
scrollingBack = 0;
|
||||
}
|
||||
if (scrollingMid <= -midground.Width * 2)
|
||||
{
|
||||
scrollingMid = 0;
|
||||
}
|
||||
if (scrollingFore <= -foreground.Width * 2)
|
||||
{
|
||||
scrollingFore = 0;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(GetColor(0x052c46ff));
|
||||
|
||||
// Draw background image twice
|
||||
// NOTE: Texture is scaled twice its size
|
||||
DrawTextureEx(background, new Vector2(scrollingBack, 20), 0.0f, 2.0f, Color.White);
|
||||
DrawTextureEx(
|
||||
background,
|
||||
new Vector2(background.Width * 2 + scrollingBack, 20),
|
||||
0.0f,
|
||||
2.0f,
|
||||
Color.White
|
||||
);
|
||||
|
||||
// Draw midground image twice
|
||||
DrawTextureEx(midground, new Vector2(scrollingMid, 20), 0.0f, 2.0f, Color.White);
|
||||
DrawTextureEx(midground, new Vector2(midground.Width * 2 + scrollingMid, 20), 0.0f, 2.0f, Color.White);
|
||||
|
||||
// Draw foreground image twice
|
||||
DrawTextureEx(foreground, new Vector2(scrollingFore, 70), 0.0f, 2.0f, Color.White);
|
||||
DrawTextureEx(
|
||||
foreground,
|
||||
new Vector2(foreground.Width * 2 + scrollingFore, 70),
|
||||
0.0f,
|
||||
2.0f,
|
||||
Color.White
|
||||
);
|
||||
|
||||
DrawText("BACKGROUND SCROLLING & PARALLAX", 10, 10, 20, Color.Red);
|
||||
DrawText("(c) Cyberpunk Street Environment by Luis Zuno (@ansimuz)", screenWidth - 330, screenHeight - 20, 10, Color.RayWhite);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
UnloadTexture(background); // Unload background texture
|
||||
UnloadTexture(midground); // Unload midground texture
|
||||
UnloadTexture(foreground); // Unload foreground texture
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - background scrolling");
|
||||
|
||||
// NOTE: Be careful, background width must be equal or bigger than screen width
|
||||
// if not, texture should be draw more than two times for scrolling effect
|
||||
Texture2D background = LoadTexture("resources/cyberpunk_street_background.png");
|
||||
Texture2D midground = LoadTexture("resources/cyberpunk_street_midground.png");
|
||||
Texture2D foreground = LoadTexture("resources/cyberpunk_street_foreground.png");
|
||||
|
||||
float scrollingBack = 0.0f;
|
||||
float scrollingMid = 0.0f;
|
||||
float scrollingFore = 0.0f;
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
var game = new BackgroundScrolling();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
scrollingBack -= 0.1f;
|
||||
scrollingMid -= 0.5f;
|
||||
scrollingFore -= 1.0f;
|
||||
|
||||
// NOTE: Texture is scaled twice its size, so it sould be considered on scrolling
|
||||
if (scrollingBack <= -background.Width * 2)
|
||||
{
|
||||
scrollingBack = 0;
|
||||
}
|
||||
if (scrollingMid <= -midground.Width * 2)
|
||||
{
|
||||
scrollingMid = 0;
|
||||
}
|
||||
if (scrollingFore <= -foreground.Width * 2)
|
||||
{
|
||||
scrollingFore = 0;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(GetColor(0x052c46ff));
|
||||
|
||||
// Draw background image twice
|
||||
// NOTE: Texture is scaled twice its size
|
||||
DrawTextureEx(background, new Vector2(scrollingBack, 20), 0.0f, 2.0f, Color.White);
|
||||
DrawTextureEx(
|
||||
background,
|
||||
new Vector2(background.Width * 2 + scrollingBack, 20),
|
||||
0.0f,
|
||||
2.0f,
|
||||
Color.White
|
||||
);
|
||||
|
||||
// Draw midground image twice
|
||||
DrawTextureEx(midground, new Vector2(scrollingMid, 20), 0.0f, 2.0f, Color.White);
|
||||
DrawTextureEx(midground, new Vector2(midground.Width * 2 + scrollingMid, 20), 0.0f, 2.0f, Color.White);
|
||||
|
||||
// Draw foreground image twice
|
||||
DrawTextureEx(foreground, new Vector2(scrollingFore, 70), 0.0f, 2.0f, Color.White);
|
||||
DrawTextureEx(
|
||||
foreground,
|
||||
new Vector2(foreground.Width * 2 + scrollingFore, 70),
|
||||
0.0f,
|
||||
2.0f,
|
||||
Color.White
|
||||
);
|
||||
|
||||
DrawText("BACKGROUND SCROLLING & PARALLAX", 10, 10, 20, Color.Red);
|
||||
|
||||
int x = screenWidth - 330;
|
||||
int y = screenHeight - 20;
|
||||
DrawText("(c) Cyberpunk Street Environment by Luis Zuno (@ansimuz)", x, y, 10, Color.RayWhite);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadTexture(background);
|
||||
UnloadTexture(midground);
|
||||
UnloadTexture(foreground);
|
||||
|
||||
CloseWindow();
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -2,114 +2,145 @@
|
|||
*
|
||||
* raylib [textures] example - blend modes
|
||||
*
|
||||
* Example complexity rating: [★☆☆☆] 1/4
|
||||
*
|
||||
* NOTE: Images are loaded in CPU memory (RAM); textures are loaded in GPU memory (VRAM)
|
||||
*
|
||||
* This example has been created using raylib 3.5 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
* Example originally created with raylib 3.5, last time updated with raylib 3.5
|
||||
*
|
||||
* Example contributed by Karlo Licudine (@accidentalrebel) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Copyright (c) 2020 Karlo Licudine (@accidentalrebel)
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2020-2025 Karlo Licudine (@accidentalrebel)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
namespace Examples.Textures;
|
||||
|
||||
public class BlendModes
|
||||
public partial class BlendModes : IExample
|
||||
{
|
||||
public static int Main()
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
private const int blendCountMax = 4;
|
||||
|
||||
public string Name => "Textures / Blend Modes";
|
||||
|
||||
public string Title => "raylib [textures] example - blend modes";
|
||||
|
||||
private Texture2D bgTexture;
|
||||
private Texture2D fgTexture;
|
||||
|
||||
private BlendMode blendMode;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - blend modes");
|
||||
|
||||
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
|
||||
Image bgImage = LoadImage("resources/cyberpunk_street_background.png");
|
||||
Texture2D bgTexture = LoadTextureFromImage(bgImage);
|
||||
var bgImage = LoadImage("resources/cyberpunk_street_background.png");
|
||||
bgTexture = LoadTextureFromImage(bgImage);
|
||||
|
||||
Image fgImage = LoadImage("resources/cyberpunk_street_foreground.png");
|
||||
Texture2D fgTexture = LoadTextureFromImage(fgImage);
|
||||
var fgImage = LoadImage("resources/cyberpunk_street_foreground.png");
|
||||
fgTexture = LoadTextureFromImage(fgImage);
|
||||
|
||||
// Once image has been converted to texture and uploaded to VRAM, it can be unloaded from RAM
|
||||
UnloadImage(bgImage);
|
||||
UnloadImage(fgImage);
|
||||
|
||||
const int blendCountMax = 4;
|
||||
BlendMode blendMode = 0;
|
||||
blendMode = 0;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsKeyPressed(KeyboardKey.Space))
|
||||
{
|
||||
if ((int)blendMode >= (blendCountMax - 1))
|
||||
{
|
||||
blendMode = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
blendMode++;
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
var bgX = screenWidth / 2 - bgTexture.Width / 2;
|
||||
var bgY = screenHeight / 2 - bgTexture.Height / 2;
|
||||
DrawTexture(bgTexture, bgX, bgY, Color.White);
|
||||
|
||||
// Apply the blend mode and then draw the foreground texture
|
||||
BeginBlendMode(blendMode);
|
||||
var fgX = screenWidth / 2 - fgTexture.Width / 2;
|
||||
var fgY = screenHeight / 2 - fgTexture.Height / 2;
|
||||
DrawTexture(fgTexture, fgX, fgY, Color.White);
|
||||
EndBlendMode();
|
||||
|
||||
// Draw the texts
|
||||
DrawText("Press SPACE to change blend modes.", 310, 350, 10, Color.Gray);
|
||||
|
||||
switch (blendMode)
|
||||
{
|
||||
case BlendMode.Alpha:
|
||||
DrawText("Current: BLEND_ALPHA", (screenWidth / 2) - 60, 370, 10, Color.Gray);
|
||||
break;
|
||||
case BlendMode.Additive:
|
||||
DrawText("Current: BLEND_ADDITIVE", (screenWidth / 2) - 60, 370, 10, Color.Gray);
|
||||
break;
|
||||
case BlendMode.Multiplied:
|
||||
DrawText("Current: BLEND_MULTIPLIED", (screenWidth / 2) - 60, 370, 10, Color.Gray);
|
||||
break;
|
||||
case BlendMode.AddColors:
|
||||
DrawText("Current: BLEND_ADD_COLORS", (screenWidth / 2) - 60, 370, 10, Color.Gray);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
var text = "(c) Cyberpunk Street Environment by Luis Zuno (@ansimuz)";
|
||||
DrawText(text, screenWidth - 330, screenHeight - 20, 10, Color.Gray);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
UnloadTexture(fgTexture); // Unload foreground texture
|
||||
UnloadTexture(bgTexture); // Unload background texture
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - blend modes");
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//---------------------------------------------------------------------------------------
|
||||
|
||||
var game = new BlendModes();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsKeyPressed(KeyboardKey.Space))
|
||||
{
|
||||
if ((int)blendMode >= (blendCountMax - 1))
|
||||
{
|
||||
blendMode = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
blendMode++;
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
int bgX = screenWidth / 2 - bgTexture.Width / 2;
|
||||
int bgY = screenHeight / 2 - bgTexture.Height / 2;
|
||||
DrawTexture(bgTexture, bgX, bgY, Color.White);
|
||||
|
||||
// Apply the blend mode and then draw the foreground texture
|
||||
BeginBlendMode(blendMode);
|
||||
int fgX = screenWidth / 2 - fgTexture.Width / 2;
|
||||
int fgY = screenHeight / 2 - fgTexture.Height / 2;
|
||||
DrawTexture(fgTexture, fgX, fgY, Color.White);
|
||||
EndBlendMode();
|
||||
|
||||
// Draw the texts
|
||||
DrawText("Press SPACE to change blend modes.", 310, 350, 10, Color.Gray);
|
||||
|
||||
switch (blendMode)
|
||||
{
|
||||
case BlendMode.Alpha:
|
||||
DrawText("Current: BLEND_ALPHA", (screenWidth / 2) - 60, 370, 10, Color.Gray);
|
||||
break;
|
||||
case BlendMode.Additive:
|
||||
DrawText("Current: BLEND_ADDITIVE", (screenWidth / 2) - 60, 370, 10, Color.Gray);
|
||||
break;
|
||||
case BlendMode.Multiplied:
|
||||
DrawText("Current: BLEND_MULTIPLIED", (screenWidth / 2) - 60, 370, 10, Color.Gray);
|
||||
break;
|
||||
case BlendMode.AddColors:
|
||||
DrawText("Current: BLEND_ADD_COLORS", (screenWidth / 2) - 60, 370, 10, Color.Gray);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
string text = "(c) Cyberpunk Street Environment by Luis Zuno (@ansimuz)";
|
||||
DrawText(text, screenWidth - 330, screenHeight - 20, 10, Color.Gray);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadTexture(fgTexture);
|
||||
UnloadTexture(bgTexture);
|
||||
|
||||
CloseWindow();
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -1,23 +1,27 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [textures] example - Bunnymark
|
||||
* raylib [textures] example - bunnymark
|
||||
*
|
||||
* This example has been created using raylib 1.6 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
* Example complexity rating: [★★★☆] 3/4
|
||||
*
|
||||
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5), 2024 Moritz Voss (@thygrrr)
|
||||
* Example originally created with raylib 1.6, last time updated with raylib 2.5
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2014-2025 Ramon Santamaria (@raysan5), 2024 Moritz Voss (@thygrrr)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Numerics;
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
namespace Examples.Textures;
|
||||
|
||||
public static class Bunnymark
|
||||
public partial class Bunnymark : IExample
|
||||
{
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
// limits
|
||||
private const int MaxBunnies = 500_000;
|
||||
private const int BunnyIncrement = 500;
|
||||
|
|
@ -28,6 +32,10 @@ public static class Bunnymark
|
|||
// This is the maximum amount of elements (quads) per batch
|
||||
private const int MAX_BATCH_ELEMENTS = Rlgl.DEFAULT_BATCH_BUFFER_ELEMENTS;
|
||||
|
||||
public string Name => "Textures / Bunnymark";
|
||||
|
||||
public string Title => "raylib [textures] example - bunnymark";
|
||||
|
||||
private record struct Bunny()
|
||||
{
|
||||
public Vector2 Position { get; set; } = GetMousePosition();
|
||||
|
|
@ -46,99 +54,123 @@ public static class Bunnymark
|
|||
GetRandomValue(100, 240), 255);
|
||||
}
|
||||
|
||||
private Texture2D texBunny;
|
||||
private Vector2 halfSize;
|
||||
private Bunny[] bunnies;
|
||||
private int bunniesCount;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
// Load bunny texture
|
||||
texBunny = LoadTexture("resources/wabbit_alpha.png");
|
||||
halfSize = new Vector2(texBunny.Width, texBunny.Height) / 2;
|
||||
|
||||
// Initialize bunnies storage
|
||||
bunnies = new Bunny[MaxBunnies];
|
||||
bunniesCount = 0;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
Span<Bunny> bunnies = this.bunnies;
|
||||
|
||||
if (IsMouseButtonDown(MouseButton.Left) && bunniesCount < MaxBunnies)
|
||||
{
|
||||
// Add a range of new bunnies
|
||||
foreach (ref var bunny in bunnies[bunniesCount..(bunniesCount + BunnyIncrement)])
|
||||
{
|
||||
bunny = new();
|
||||
}
|
||||
bunniesCount += BunnyIncrement;
|
||||
}
|
||||
else if (IsMouseButtonDown(MouseButton.Right))
|
||||
{
|
||||
// Remove the oldest bunnies, shifting them back in the span
|
||||
if (bunniesCount > BunnyDecrement)
|
||||
{
|
||||
bunnies[BunnyDecrement..bunniesCount].CopyTo(bunnies);
|
||||
}
|
||||
bunniesCount = Math.Max(0, bunniesCount - BunnyDecrement);
|
||||
}
|
||||
|
||||
// Update bunnies
|
||||
foreach (ref var bunny in bunnies[..bunniesCount])
|
||||
{
|
||||
// Integrate position
|
||||
bunny.Position += bunny.Speed;
|
||||
|
||||
// Bounce bunnies off the screen borders
|
||||
bunny.Speed *= (bunny.Position + halfSize) switch
|
||||
{
|
||||
{ X: < 0 or > screenWidth, Y: < 40 or > screenHeight } => new(-1, -1),
|
||||
{ X: < 0 or > screenWidth } => new(-1, 1),
|
||||
{ Y: < 40 or > screenHeight } => new(1, -1),
|
||||
_ => Vector2.One,
|
||||
};
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
foreach (var bunny in bunnies[..bunniesCount])
|
||||
{
|
||||
// NOTE: When internal batch buffer limit is reached (MAX_BATCH_ELEMENTS),
|
||||
// a draw call is launched and buffer starts being filled again;
|
||||
// before issuing a draw call, updated vertex data from internal CPU buffer is send to GPU...
|
||||
// Process of sending data is costly and it could happen that GPU data has not been completely
|
||||
// processed for drawing while new data is tried to be sent (updating current in-use buffers)
|
||||
// it could generates a stall and consequently a frame drop, limiting the number of drawn bunnies
|
||||
DrawTexture(texBunny, (int)bunny.Position.X, (int)bunny.Position.Y, bunny.Color);
|
||||
}
|
||||
|
||||
DrawRectangle(0, 0, screenWidth, 40, Color.Black);
|
||||
DrawText($"bunnies: {bunniesCount}", 120, 10, 20, Color.Green);
|
||||
DrawText($"batched draw calls: {1 + bunniesCount / MAX_BATCH_ELEMENTS}", 320, 10, 20, Color.Maroon);
|
||||
DrawText("Left Mouse: Add Bunnies!!! :D", 10, 400, 20, Color.LightGray);
|
||||
DrawText("Right Mouse: Remove Bunnies", 10, 420, 20, Color.LightGray);
|
||||
|
||||
DrawFPS(10, 10);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
UnloadTexture(texBunny);
|
||||
#if BROWSER
|
||||
bunnies = null;
|
||||
bunniesCount = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - bunnymark");
|
||||
|
||||
// Load bunny texture
|
||||
Texture2D texBunny = LoadTexture("resources/wabbit_alpha.png");
|
||||
Vector2 halfSize = new Vector2(texBunny.Width, texBunny.Height) / 2;
|
||||
|
||||
// Initialize bunnies storage
|
||||
Span<Bunny> bunnies = new Bunny[MaxBunnies];
|
||||
int bunniesCount = 0;
|
||||
|
||||
SetTargetFPS(TARGET_FPS);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
var game = new Bunnymark();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsMouseButtonDown(MouseButton.Left) && bunniesCount < MaxBunnies)
|
||||
{
|
||||
// Add a range of new bunnies
|
||||
foreach (ref var bunny in bunnies[bunniesCount..(bunniesCount + BunnyIncrement)])
|
||||
{
|
||||
bunny = new();
|
||||
}
|
||||
bunniesCount += BunnyIncrement;
|
||||
}
|
||||
else if (IsMouseButtonDown(MouseButton.Right))
|
||||
{
|
||||
// Remove the oldest bunnies, shifting them back in the span
|
||||
if (bunniesCount > BunnyDecrement)
|
||||
{
|
||||
bunnies[BunnyDecrement..bunniesCount].CopyTo(bunnies);
|
||||
}
|
||||
bunniesCount = Math.Max(0, bunniesCount - BunnyDecrement);
|
||||
}
|
||||
|
||||
// Update bunnies
|
||||
foreach (ref var bunny in bunnies[..bunniesCount])
|
||||
{
|
||||
// Integrate position
|
||||
bunny.Position += bunny.Speed;
|
||||
|
||||
// Bounce bunnies off the screen borders
|
||||
bunny.Speed *= (bunny.Position + halfSize) switch
|
||||
{
|
||||
{ X: < 0 or > screenWidth, Y: < 40 or > screenHeight } => new(-1, -1),
|
||||
{ X: < 0 or > screenWidth } => new(-1, 1),
|
||||
{ Y: < 40 or > screenHeight } => new(1, -1),
|
||||
_ => Vector2.One,
|
||||
};
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
foreach (var bunny in bunnies[..bunniesCount])
|
||||
{
|
||||
// NOTE: When internal batch buffer limit is reached (MAX_BATCH_ELEMENTS),
|
||||
// a draw call is launched and buffer starts being filled again;
|
||||
// before issuing a draw call, updated vertex data from internal CPU buffer is send to GPU...
|
||||
// Process of sending data is costly, and it could happen that GPU data has not been completely
|
||||
// processed for drawing while new data is tried to be sent (updating current in-use buffers)
|
||||
// it could generate a stall and consequently a frame drop, limiting the number of drawn bunnies
|
||||
DrawTexture(texBunny, (int)bunny.Position.X, (int)bunny.Position.Y, bunny.Color);
|
||||
}
|
||||
|
||||
DrawRectangle(0, 0, screenWidth, 40, Color.Black);
|
||||
DrawText($"bunnies: {bunniesCount}", 120, 10, 20, Color.Green);
|
||||
DrawText($"batched draw calls: {1 + bunniesCount / MAX_BATCH_ELEMENTS}", 320, 10, 20, Color.Maroon);
|
||||
DrawText("Left Mouse: Add Bunnies!!! :D", 10, 400, 20, Color.LightGray);
|
||||
DrawText("Right Mouse: Remove Bunnies", 10, 420, 20, Color.LightGray);
|
||||
|
||||
DrawFPS(10, 10);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadTexture(texBunny);
|
||||
|
||||
CloseWindow();
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
|
|
|
|||
246
Examples/Textures/CellularAutomata.cs
Normal file
246
Examples/Textures/CellularAutomata.cs
Normal file
|
|
@ -0,0 +1,246 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [textures] example - cellular automata
|
||||
*
|
||||
* Example complexity rating: [★★☆☆] 2/4
|
||||
*
|
||||
* Example originally created with raylib 5.6, last time updated with raylib 5.6
|
||||
*
|
||||
* Example contributed by Jordi Santonja (@JordSant) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2025 Jordi Santonja (@JordSant)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
namespace Examples.Textures;
|
||||
|
||||
public partial class CellularAutomata : IExample
|
||||
{
|
||||
// Initialization constants
|
||||
//--------------------------------------------------------------------------------------
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
private const int imageWidth = 800;
|
||||
private const int imageHeight = 800 / 2;
|
||||
|
||||
// Rule button sizes and positions
|
||||
private const int drawRuleStartX = 585;
|
||||
private const int drawRuleStartY = 10;
|
||||
private const int drawRuleSpacing = 15;
|
||||
private const int drawRuleGroupSpacing = 50;
|
||||
private const int drawRuleSize = 14;
|
||||
private const int drawRuleInnerSize = 10;
|
||||
|
||||
// Preset button sizes
|
||||
private const int presetsSizeX = 42;
|
||||
private const int presetsSizeY = 22;
|
||||
|
||||
private const int linesUpdatedPerFrame = 4;
|
||||
|
||||
public string Name => "Textures / Cellular Automata";
|
||||
|
||||
public string Title => "raylib [textures] example - cellular automata";
|
||||
|
||||
// Some interesting rules
|
||||
private static readonly int[] presetValues = { 18, 30, 60, 86, 102, 124, 126, 150, 182, 225 };
|
||||
private const int presetsCount = 10;
|
||||
|
||||
private Image image;
|
||||
private Texture2D texture;
|
||||
private int rule;
|
||||
private int line;
|
||||
|
||||
private static void ComputeLine(ref Image image, int line, int rule)
|
||||
{
|
||||
// Compute next line pixels. Boundaries are not computed, always 0
|
||||
for (var i = 1; i < imageWidth - 1; i++)
|
||||
{
|
||||
// Get, from the previous line, the 3 pixels states as a binary value
|
||||
var prevValue = ((GetImageColor(image, i - 1, line - 1).R < 5) ? 4 : 0) + // Left pixel
|
||||
((GetImageColor(image, i, line - 1).R < 5) ? 2 : 0) + // Center pixel
|
||||
((GetImageColor(image, i + 1, line - 1).R < 5) ? 1 : 0); // Right pixel
|
||||
// Get next value from rule bitmask
|
||||
var currValue = (rule & (1 << prevValue)) != 0;
|
||||
// Update pixel color
|
||||
ImageDrawPixel(ref image, i, line, currValue ? Color.Black : Color.RayWhite);
|
||||
}
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
// Image that contains the cellular automaton
|
||||
image = GenImageColor(imageWidth, imageHeight, Color.RayWhite);
|
||||
// The top central pixel set as black
|
||||
ImageDrawPixel(ref image, imageWidth / 2, 0, Color.Black);
|
||||
|
||||
texture = LoadTextureFromImage(image);
|
||||
|
||||
// Variables
|
||||
rule = 30; // Starting rule
|
||||
line = 1; // Line to compute, starting from line 1. One point in line 0 is already set
|
||||
}
|
||||
|
||||
public unsafe void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// Handle mouse
|
||||
var mouse = GetMousePosition();
|
||||
var mouseInCell = -1; // -1: outside any button; 0-7: rule cells; 8+: preset cells
|
||||
|
||||
// Check mouse on rule cells
|
||||
for (var i = 0; i < 8; i++)
|
||||
{
|
||||
var cellX = drawRuleStartX - drawRuleGroupSpacing * i + drawRuleSpacing;
|
||||
var cellY = drawRuleStartY + drawRuleSpacing;
|
||||
if ((mouse.X >= cellX) && (mouse.X <= cellX + drawRuleSize) &&
|
||||
(mouse.Y >= cellY) && (mouse.Y <= cellY + drawRuleSize))
|
||||
{
|
||||
mouseInCell = i; // 0-7: rule cells
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check mouse on preset cells
|
||||
if (mouseInCell < 0)
|
||||
{
|
||||
for (var i = 0; i < presetsCount; i++)
|
||||
{
|
||||
var cellX = 4 + (presetsSizeX + 2) * (i / 2);
|
||||
var cellY = 2 + (presetsSizeY + 2) * (i % 2);
|
||||
if ((mouse.X >= cellX) && (mouse.X <= cellX + presetsSizeX) &&
|
||||
(mouse.Y >= cellY) && (mouse.Y <= cellY + presetsSizeY))
|
||||
{
|
||||
mouseInCell = i + 8; // 8+: preset cells
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (IsMouseButtonPressed(MouseButton.Left) && (mouseInCell >= 0))
|
||||
{
|
||||
// Rule changed both by selecting a preset or toggling a bit
|
||||
if (mouseInCell < 8)
|
||||
{
|
||||
rule ^= (1 << mouseInCell);
|
||||
}
|
||||
else
|
||||
{
|
||||
rule = presetValues[mouseInCell - 8];
|
||||
}
|
||||
|
||||
// Reset image
|
||||
ImageClearBackground(ref image, Color.RayWhite);
|
||||
ImageDrawPixel(ref image, imageWidth / 2, 0, Color.Black);
|
||||
line = 1;
|
||||
}
|
||||
|
||||
// Compute next lines
|
||||
//----------------------------------------------------------------------------------
|
||||
if (line < imageHeight)
|
||||
{
|
||||
for (var i = 0; (i < linesUpdatedPerFrame) && (line + i < imageHeight); i++)
|
||||
{
|
||||
ComputeLine(ref image, line + i, rule);
|
||||
}
|
||||
line += linesUpdatedPerFrame;
|
||||
|
||||
UpdateTexture(texture, image.Data);
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
// Draw cellular automaton texture
|
||||
DrawTexture(texture, 0, screenHeight - imageHeight, Color.White);
|
||||
|
||||
// Draw preset values
|
||||
for (var i = 0; i < presetsCount; i++)
|
||||
{
|
||||
DrawText($"{presetValues[i]}", 8 + (presetsSizeX + 2) * (i / 2), 4 + (presetsSizeY + 2) * (i % 2), 20, Color.Gray);
|
||||
DrawRectangleLines(4 + (presetsSizeX + 2) * (i / 2), 2 + (presetsSizeY + 2) * (i % 2), presetsSizeX, presetsSizeY, Color.Blue);
|
||||
|
||||
// If the mouse is on this preset, highlight it
|
||||
if (mouseInCell == i + 8)
|
||||
{
|
||||
DrawRectangleLinesEx(new Rectangle(2 + (presetsSizeX + 2.0f) * (i / 2),
|
||||
(presetsSizeY + 2.0f) * (i % 2),
|
||||
presetsSizeX + 4.0f, presetsSizeY + 4.0f), 3, Color.Red);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw rule bits
|
||||
for (var i = 0; i < 8; i++)
|
||||
{
|
||||
// The three input bits
|
||||
for (var j = 0; j < 3; j++)
|
||||
{
|
||||
DrawRectangleLines(drawRuleStartX - drawRuleGroupSpacing * i + drawRuleSpacing * j, drawRuleStartY, drawRuleSize, drawRuleSize, Color.Gray);
|
||||
if ((i & (4 >> j)) != 0)
|
||||
{
|
||||
DrawRectangle(drawRuleStartX + 2 - drawRuleGroupSpacing * i + drawRuleSpacing * j, drawRuleStartY + 2, drawRuleInnerSize, drawRuleInnerSize, Color.Black);
|
||||
}
|
||||
}
|
||||
|
||||
// The output bit
|
||||
DrawRectangleLines(drawRuleStartX - drawRuleGroupSpacing * i + drawRuleSpacing, drawRuleStartY + drawRuleSpacing, drawRuleSize, drawRuleSize, Color.Blue);
|
||||
if ((rule & (1 << i)) != 0)
|
||||
{
|
||||
DrawRectangle(drawRuleStartX + 2 - drawRuleGroupSpacing * i + drawRuleSpacing, drawRuleStartY + 2 + drawRuleSpacing, drawRuleInnerSize, drawRuleInnerSize, Color.Black);
|
||||
}
|
||||
|
||||
// If the mouse is on this rule bit, highlight it
|
||||
if (mouseInCell == i)
|
||||
{
|
||||
DrawRectangleLinesEx(new Rectangle(drawRuleStartX - drawRuleGroupSpacing * i + drawRuleSpacing - 2.0f,
|
||||
drawRuleStartY + drawRuleSpacing - 2.0f,
|
||||
drawRuleSize + 4.0f, drawRuleSize + 4.0f), 3, Color.Red);
|
||||
}
|
||||
}
|
||||
|
||||
DrawText($"RULE: {rule}", drawRuleStartX + drawRuleSpacing * 4, drawRuleStartY + 1, 30, Color.Gray);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
UnloadImage(image);
|
||||
UnloadTexture(texture);
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - cellular automata");
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
var game = new CellularAutomata();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
141
Examples/Textures/ClipboardImage.cs
Normal file
141
Examples/Textures/ClipboardImage.cs
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [textures] example - clipboard image
|
||||
*
|
||||
* Example complexity rating: [★☆☆☆] 1/4
|
||||
*
|
||||
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||
*
|
||||
* Example contributed by Maicon Santana (@maiconpintoabreu) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2026 Maicon Santana (@maiconpintoabreu)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
namespace Examples.Textures;
|
||||
|
||||
[ExcludeFromBrowser("GetClipboardImage() is a desktop-only OS clipboard feature")]
|
||||
public partial class ClipboardImage : IExample
|
||||
{
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
private const int MaxTextureCollection = 20;
|
||||
|
||||
public string Name => "Textures / Clipboard Image";
|
||||
|
||||
public string Title => "raylib [textures] example - clipboard image";
|
||||
|
||||
private struct TextureCollection
|
||||
{
|
||||
public Texture2D Texture;
|
||||
public Vector2 Position;
|
||||
}
|
||||
|
||||
private TextureCollection[] collection;
|
||||
private int currentCollectionIndex;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
collection = new TextureCollection[MaxTextureCollection];
|
||||
currentCollectionIndex = 0;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsKeyPressed(KeyboardKey.R)) // Reset image collection
|
||||
{
|
||||
// Unload textures to avoid memory leaks
|
||||
for (var i = 0; i < MaxTextureCollection; i++)
|
||||
{
|
||||
UnloadTexture(collection[i].Texture);
|
||||
}
|
||||
|
||||
currentCollectionIndex = 0;
|
||||
}
|
||||
|
||||
if (IsKeyDown(KeyboardKey.LeftControl) && IsKeyPressed(KeyboardKey.V) &&
|
||||
(currentCollectionIndex < MaxTextureCollection))
|
||||
{
|
||||
var image = GetClipboardImage();
|
||||
|
||||
if (IsImageValid(image))
|
||||
{
|
||||
collection[currentCollectionIndex].Texture = LoadTextureFromImage(image);
|
||||
collection[currentCollectionIndex].Position = GetMousePosition();
|
||||
currentCollectionIndex++;
|
||||
UnloadImage(image);
|
||||
}
|
||||
else
|
||||
{
|
||||
TraceLog(TraceLogLevel.Info, "IMAGE: Could not retrieve image from clipboard");
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
for (var i = 0; i < currentCollectionIndex; i++)
|
||||
{
|
||||
if (IsTextureValid(collection[i].Texture))
|
||||
{
|
||||
DrawTexturePro(collection[i].Texture,
|
||||
new Rectangle(0, 0, collection[i].Texture.Width, collection[i].Texture.Height),
|
||||
new Rectangle(collection[i].Position.X, collection[i].Position.Y, collection[i].Texture.Width, collection[i].Texture.Height),
|
||||
new Vector2(collection[i].Texture.Width * 0.5f, collection[i].Texture.Height * 0.5f),
|
||||
0.0f, Color.White);
|
||||
}
|
||||
}
|
||||
|
||||
DrawRectangle(0, 0, screenWidth, 40, Color.Black);
|
||||
DrawText("Clipboard Image - Ctrl+V to Paste and R to Reset ", 120, 10, 20, Color.LightGray);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
for (var i = 0; i < MaxTextureCollection; i++)
|
||||
{
|
||||
UnloadTexture(collection[i].Texture);
|
||||
}
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - clipboard image");
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
var game = new ClipboardImage();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,66 +1,85 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [textures] example - Draw part of the texture tiled
|
||||
* raylib [textures] example - tiled drawing
|
||||
*
|
||||
* This example has been created using raylib 3.0 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
* Example complexity rating: [★★★☆] 3/4
|
||||
*
|
||||
* Copyright (c) 2020 Vlad Adrian (@demizdor) and Ramon Santamaria (@raysan5)
|
||||
* Example originally created with raylib 3.0, last time updated with raylib 4.2
|
||||
*
|
||||
* Example contributed by Vlad Adrian (@demizdor) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2020-2025 Vlad Adrian (@demizdor) and Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using System.Numerics;
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
namespace Examples.Textures;
|
||||
|
||||
public class DrawTiled
|
||||
public partial class DrawTiled : IExample
|
||||
{
|
||||
const int OptWidth = 220;
|
||||
const int MarginSize = 8;
|
||||
const int ColorSize = 16;
|
||||
private const int OptWidth = 220;
|
||||
private const int MarginSize = 8;
|
||||
private const int ColorSize = 16;
|
||||
|
||||
public static int Main()
|
||||
public string Name => "Textures / Draw Tiled";
|
||||
|
||||
public string Title => "raylib [textures] example - tiled drawing";
|
||||
|
||||
public ConfigFlags ConfigFlags => ConfigFlags.ResizableWindow;
|
||||
|
||||
private int screenWidth;
|
||||
private int screenHeight;
|
||||
|
||||
private Texture2D texPattern;
|
||||
|
||||
// Coordinates for all patterns inside the texture
|
||||
private Rectangle[] recPattern;
|
||||
|
||||
// Setup colors
|
||||
private Color[] colors;
|
||||
private Rectangle[] colorRec;
|
||||
|
||||
private int activePattern;
|
||||
private int activeCol;
|
||||
private float scale;
|
||||
private float rotation;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
int screenWidth = 800;
|
||||
int screenHeight = 450;
|
||||
|
||||
SetConfigFlags(ConfigFlags.ResizableWindow);
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - Draw part of a texture tiled");
|
||||
screenWidth = 800;
|
||||
screenHeight = 450;
|
||||
|
||||
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
|
||||
Texture2D texPattern = LoadTexture("resources/patterns.png");
|
||||
|
||||
// Makes the texture smoother when upscaled
|
||||
SetTextureFilter(texPattern, TextureFilter.Trilinear);
|
||||
texPattern = LoadTexture("resources/patterns.png");
|
||||
SetTextureFilter(texPattern, TextureFilter.Bilinear); // Makes the texture smoother when upscaled
|
||||
|
||||
// Coordinates for all patterns inside the texture
|
||||
Rectangle[] recPattern = new[] {
|
||||
new Rectangle(3, 3, 66, 66),
|
||||
new Rectangle(75, 3, 100, 100),
|
||||
new Rectangle(3, 75, 66, 66),
|
||||
new Rectangle(7, 156, 50, 50),
|
||||
new Rectangle(85, 106, 90, 45),
|
||||
new Rectangle(75, 154, 100, 60)
|
||||
};
|
||||
recPattern = new[] {
|
||||
new Rectangle(3, 3, 66, 66),
|
||||
new Rectangle(75, 3, 100, 100),
|
||||
new Rectangle(3, 75, 66, 66),
|
||||
new Rectangle(7, 156, 50, 50),
|
||||
new Rectangle(85, 106, 90, 45),
|
||||
new Rectangle(75, 154, 100, 60)
|
||||
};
|
||||
|
||||
// Setup colors
|
||||
Color[] colors = new[]
|
||||
colors = new[]
|
||||
{
|
||||
Color.Black,
|
||||
Color.Maroon,
|
||||
Color.Orange,
|
||||
Color.Blue,
|
||||
Color.Purple,
|
||||
Color.Beige,
|
||||
Color.Lime,
|
||||
Color.Red,
|
||||
Color.DarkGray,
|
||||
Color.SkyBlue
|
||||
};
|
||||
Rectangle[] colorRec = new Rectangle[colors.Length];
|
||||
Color.Black,
|
||||
Color.Maroon,
|
||||
Color.Orange,
|
||||
Color.Blue,
|
||||
Color.Purple,
|
||||
Color.Beige,
|
||||
Color.Lime,
|
||||
Color.Red,
|
||||
Color.DarkGray,
|
||||
Color.SkyBlue
|
||||
};
|
||||
colorRec = new Rectangle[colors.Length];
|
||||
|
||||
// Calculate rectangle for each color
|
||||
for (int i = 0, x = 0, y = 0; i < colors.Length; i++)
|
||||
|
|
@ -81,155 +100,176 @@ public class DrawTiled
|
|||
}
|
||||
}
|
||||
|
||||
int activePattern = 0, activeCol = 0;
|
||||
float scale = 1.0f, rotation = 0.0f;
|
||||
activePattern = 0;
|
||||
activeCol = 0;
|
||||
scale = 1.0f;
|
||||
rotation = 0.0f;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
screenWidth = GetScreenWidth();
|
||||
screenHeight = GetScreenHeight();
|
||||
|
||||
// Handle mouse
|
||||
if (IsMouseButtonPressed(MouseButton.Left))
|
||||
{
|
||||
var mouse = GetMousePosition();
|
||||
|
||||
// Check which pattern was clicked and set it as the active pattern
|
||||
for (var i = 0; i < recPattern.Length; i++)
|
||||
{
|
||||
Rectangle rec = new(
|
||||
2 + MarginSize + recPattern[i].X,
|
||||
40 + MarginSize + recPattern[i].Y,
|
||||
recPattern[i].Width,
|
||||
recPattern[i].Height
|
||||
);
|
||||
if (CheckCollisionPointRec(mouse, rec))
|
||||
{
|
||||
activePattern = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check to see which color was clicked and set it as the active color
|
||||
for (var i = 0; i < colors.Length; ++i)
|
||||
{
|
||||
if (CheckCollisionPointRec(mouse, colorRec[i]))
|
||||
{
|
||||
activeCol = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle keys: change scale
|
||||
if (IsKeyPressed(KeyboardKey.Up))
|
||||
{
|
||||
scale += 0.25f;
|
||||
}
|
||||
if (IsKeyPressed(KeyboardKey.Down))
|
||||
{
|
||||
scale -= 0.25f;
|
||||
}
|
||||
if (scale > 10.0f)
|
||||
{
|
||||
scale = 10.0f;
|
||||
}
|
||||
else if (scale <= 0.0f)
|
||||
{
|
||||
scale = 0.25f;
|
||||
}
|
||||
|
||||
// Handle keys: change rotation
|
||||
if (IsKeyPressed(KeyboardKey.Left))
|
||||
{
|
||||
rotation -= 25.0f;
|
||||
}
|
||||
if (IsKeyPressed(KeyboardKey.Right))
|
||||
{
|
||||
rotation += 25.0f;
|
||||
}
|
||||
|
||||
// Handle keys: reset
|
||||
if (IsKeyPressed(KeyboardKey.Space))
|
||||
{
|
||||
rotation = 0.0f;
|
||||
scale = 1.0f;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
// Draw the tiled area
|
||||
var source = recPattern[activePattern];
|
||||
Rectangle dest = new(
|
||||
OptWidth + MarginSize,
|
||||
MarginSize,
|
||||
screenWidth - OptWidth - 2 * MarginSize,
|
||||
screenHeight - 2 * MarginSize
|
||||
);
|
||||
DrawTextureTiled(texPattern, source, dest, Vector2.Zero, rotation, scale, colors[activeCol]);
|
||||
|
||||
// Draw options
|
||||
var color = ColorAlpha(Color.LightGray, 0.5f);
|
||||
DrawRectangle(MarginSize, MarginSize, OptWidth - MarginSize, screenHeight - 2 * MarginSize, color);
|
||||
|
||||
DrawText("Select Pattern", 2 + MarginSize, 30 + MarginSize, 10, Color.Black);
|
||||
DrawTexture(texPattern, 2 + MarginSize, 40 + MarginSize, Color.Black);
|
||||
DrawRectangle(
|
||||
2 + MarginSize + (int)recPattern[activePattern].X,
|
||||
40 + MarginSize + (int)recPattern[activePattern].Y,
|
||||
(int)recPattern[activePattern].Width,
|
||||
(int)recPattern[activePattern].Height,
|
||||
ColorAlpha(Color.DarkBlue, 0.3f)
|
||||
);
|
||||
|
||||
DrawText("Select Color", 2 + MarginSize, 10 + 256 + MarginSize, 10, Color.Black);
|
||||
for (var i = 0; i < colors.Length; i++)
|
||||
{
|
||||
DrawRectangleRec(colorRec[i], colors[i]);
|
||||
if (activeCol == i)
|
||||
{
|
||||
DrawRectangleLinesEx(colorRec[i], 3, ColorAlpha(Color.White, 0.5f));
|
||||
}
|
||||
}
|
||||
|
||||
DrawText("Scale (UP/DOWN to change)", 2 + MarginSize, 80 + 256 + MarginSize, 10, Color.Black);
|
||||
DrawText($"{scale:F2}x", 2 + MarginSize, 92 + 256 + MarginSize, 20, Color.Black);
|
||||
|
||||
DrawText("Rotation (LEFT/RIGHT to change)", 2 + MarginSize, 122 + 256 + MarginSize, 10, Color.Black);
|
||||
DrawText($"{rotation:F0} degrees", 2 + MarginSize, 134 + 256 + MarginSize, 20, Color.Black);
|
||||
|
||||
DrawText("Press [SPACE] to reset", 2 + MarginSize, 164 + 256 + MarginSize, 10, Color.DarkBlue);
|
||||
|
||||
// Draw FPS
|
||||
DrawText($"{GetFPS()} FPS", 2 + MarginSize, 2 + MarginSize, 20, Color.Black);
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
UnloadTexture(texPattern); // Unload texture
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
SetConfigFlags(ConfigFlags.ResizableWindow); // Make the window resizable
|
||||
InitWindow(800, 450, "raylib [textures] example - tiled drawing");
|
||||
|
||||
SetTargetFPS(60);
|
||||
//---------------------------------------------------------------------------------------
|
||||
|
||||
var game = new DrawTiled();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
screenWidth = GetScreenWidth();
|
||||
screenHeight = GetScreenHeight();
|
||||
|
||||
// Handle mouse
|
||||
if (IsMouseButtonPressed(MouseButton.Left))
|
||||
{
|
||||
Vector2 mouse = GetMousePosition();
|
||||
|
||||
// Check which pattern was clicked and set it as the active pattern
|
||||
for (int i = 0; i < recPattern.Length; i++)
|
||||
{
|
||||
Rectangle rec = new(
|
||||
2 + MarginSize + recPattern[i].X,
|
||||
40 + MarginSize + recPattern[i].Y,
|
||||
recPattern[i].Width,
|
||||
recPattern[i].Height
|
||||
);
|
||||
if (CheckCollisionPointRec(mouse, rec))
|
||||
{
|
||||
activePattern = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check to see which color was clicked and set it as the active color
|
||||
for (int i = 0; i < colors.Length; ++i)
|
||||
{
|
||||
if (CheckCollisionPointRec(mouse, colorRec[i]))
|
||||
{
|
||||
activeCol = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle keys
|
||||
|
||||
// Change scale
|
||||
if (IsKeyPressed(KeyboardKey.Up))
|
||||
{
|
||||
scale += 0.25f;
|
||||
}
|
||||
if (IsKeyPressed(KeyboardKey.Down))
|
||||
{
|
||||
scale -= 0.25f;
|
||||
}
|
||||
if (scale > 10.0f)
|
||||
{
|
||||
scale = 10.0f;
|
||||
}
|
||||
else if (scale <= 0.0f)
|
||||
{
|
||||
scale = 0.25f;
|
||||
}
|
||||
|
||||
// Change rotation
|
||||
if (IsKeyPressed(KeyboardKey.Left))
|
||||
{
|
||||
rotation -= 25.0f;
|
||||
}
|
||||
if (IsKeyPressed(KeyboardKey.Right))
|
||||
{
|
||||
rotation += 25.0f;
|
||||
}
|
||||
|
||||
// Reset
|
||||
if (IsKeyPressed(KeyboardKey.Space))
|
||||
{
|
||||
rotation = 0.0f;
|
||||
scale = 1.0f;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
// Draw the tiled area
|
||||
Rectangle source = recPattern[activePattern];
|
||||
Rectangle dest = new(
|
||||
OptWidth + MarginSize,
|
||||
MarginSize,
|
||||
screenWidth - OptWidth - 2 * MarginSize,
|
||||
screenHeight - 2 * MarginSize
|
||||
);
|
||||
DrawTextureTiled(texPattern, source, dest, Vector2.Zero, rotation, scale, colors[activeCol]);
|
||||
|
||||
// Draw options
|
||||
Color color = ColorAlpha(Color.LightGray, 0.5f);
|
||||
DrawRectangle(MarginSize, MarginSize, OptWidth - MarginSize, screenHeight - 2 * MarginSize, color);
|
||||
|
||||
DrawText("Select Pattern", 2 + MarginSize, 30 + MarginSize, 10, Color.Black);
|
||||
DrawTexture(texPattern, 2 + MarginSize, 40 + MarginSize, Color.Black);
|
||||
DrawRectangle(
|
||||
2 + MarginSize + (int)recPattern[activePattern].X,
|
||||
40 + MarginSize + (int)recPattern[activePattern].Y,
|
||||
(int)recPattern[activePattern].Width,
|
||||
(int)recPattern[activePattern].Height,
|
||||
ColorAlpha(Color.DarkBlue, 0.3f)
|
||||
);
|
||||
|
||||
DrawText("Select Color", 2 + MarginSize, 10 + 256 + MarginSize, 10, Color.Black);
|
||||
for (int i = 0; i < colors.Length; i++)
|
||||
{
|
||||
DrawRectangleRec(colorRec[i], colors[i]);
|
||||
if (activeCol == i)
|
||||
{
|
||||
DrawRectangleLinesEx(colorRec[i], 3, ColorAlpha(Color.White, 0.5f));
|
||||
}
|
||||
}
|
||||
|
||||
DrawText("Scale (UP/DOWN to change)", 2 + MarginSize, 80 + 256 + MarginSize, 10, Color.Black);
|
||||
DrawText($"{scale}x", 2 + MarginSize, 92 + 256 + MarginSize, 20, Color.Black);
|
||||
|
||||
DrawText("Rotation (LEFT/RIGHT to change)", 2 + MarginSize, 122 + 256 + MarginSize, 10, Color.Black);
|
||||
DrawText($"{rotation} degrees", 2 + MarginSize, 134 + 256 + MarginSize, 20, Color.Black);
|
||||
|
||||
DrawText("Press [SPACE] to reset", 2 + MarginSize, 164 + 256 + MarginSize, 10, Color.DarkBlue);
|
||||
|
||||
// Draw FPS
|
||||
DrawText($"{GetFPS()}", 2 + MarginSize, 2 + MarginSize, 20, Color.Black);
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadTexture(texPattern);
|
||||
|
||||
CloseWindow();
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Draw part of a texture (defined by a rectangle) with rotation and scale tiled into dest.
|
||||
static void DrawTextureTiled(
|
||||
private static void DrawTextureTiled(
|
||||
Texture2D texture,
|
||||
Rectangle source,
|
||||
Rectangle dest,
|
||||
|
|
@ -268,7 +308,7 @@ public class DrawTiled
|
|||
else if (dest.Width <= tileWidth)
|
||||
{
|
||||
// Tiled vertically (one column)
|
||||
int dy = 0;
|
||||
var dy = 0;
|
||||
for (; dy + tileHeight < dest.Height; dy += tileHeight)
|
||||
{
|
||||
DrawTexturePro(
|
||||
|
|
@ -307,7 +347,7 @@ public class DrawTiled
|
|||
else if (dest.Height <= tileHeight)
|
||||
{
|
||||
// Tiled horizontally (one row)
|
||||
int dx = 0;
|
||||
var dx = 0;
|
||||
for (; dx + tileWidth < dest.Width; dx += tileWidth)
|
||||
{
|
||||
DrawTexturePro(
|
||||
|
|
@ -351,10 +391,10 @@ public class DrawTiled
|
|||
else
|
||||
{
|
||||
// Tiled both horizontally and vertically (rows and columns)
|
||||
int dx = 0;
|
||||
var dx = 0;
|
||||
for (; dx + tileWidth < dest.Width; dx += tileWidth)
|
||||
{
|
||||
int dy = 0;
|
||||
var dy = 0;
|
||||
for (; dy + tileHeight < dest.Height; dy += tileHeight)
|
||||
{
|
||||
DrawTexturePro(
|
||||
|
|
@ -397,7 +437,7 @@ public class DrawTiled
|
|||
// Fit last column of tiles
|
||||
if (dx < dest.Width)
|
||||
{
|
||||
int dy = 0;
|
||||
var dy = 0;
|
||||
for (; dy + tileHeight < dest.Height; dy += tileHeight)
|
||||
{
|
||||
DrawTexturePro(
|
||||
|
|
@ -446,4 +486,3 @@ public class DrawTiled
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
230
Examples/Textures/FogOfWar.cs
Normal file
230
Examples/Textures/FogOfWar.cs
Normal file
|
|
@ -0,0 +1,230 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [textures] example - fog of war
|
||||
*
|
||||
* Example complexity rating: [★★★☆] 3/4
|
||||
*
|
||||
* Example originally created with raylib 4.2, last time updated with raylib 4.2
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2018-2025 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
namespace Examples.Textures;
|
||||
|
||||
public partial class FogOfWar : IExample
|
||||
{
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
private const int MapTileSize = 32; // Tiles size 32x32 pixels
|
||||
private const int PlayerSize = 16; // Player size
|
||||
private const int PlayerTileVisibility = 2; // Player can see 2 tiles around its position
|
||||
|
||||
public string Name => "Textures / Fog of War";
|
||||
|
||||
public string Title => "raylib [textures] example - fog of war";
|
||||
|
||||
// Map data type
|
||||
private struct Map
|
||||
{
|
||||
public uint TilesX; // Number of tiles in X axis
|
||||
public uint TilesY; // Number of tiles in Y axis
|
||||
public byte[] TileIds; // Tile ids (tilesX*tilesY), defines type of tile to draw
|
||||
public byte[] TileFog; // Tile fog state (tilesX*tilesY), defines if a tile has fog or half-fog
|
||||
}
|
||||
|
||||
private Map map;
|
||||
private Vector2 playerPosition;
|
||||
private int playerTileX;
|
||||
private int playerTileY;
|
||||
private RenderTexture2D fogOfWar;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
map = new Map();
|
||||
map.TilesX = 25;
|
||||
map.TilesY = 15;
|
||||
|
||||
// NOTE: We can have up to 256 values for tile ids and for tile fog state,
|
||||
// probably we don't need that many values for fog state, it can be optimized
|
||||
// to use only 2 bits per fog state (reducing size by 4) but logic will be a bit more complex
|
||||
map.TileIds = new byte[map.TilesX * map.TilesY];
|
||||
map.TileFog = new byte[map.TilesX * map.TilesY];
|
||||
|
||||
// Load map tiles (generating 2 random tile ids for testing)
|
||||
// NOTE: Map tile ids should be probably loaded from an external map file
|
||||
for (uint i = 0; i < map.TilesY * map.TilesX; i++)
|
||||
{
|
||||
map.TileIds[i] = (byte)GetRandomValue(0, 1);
|
||||
}
|
||||
|
||||
// Player position on the screen (pixel coordinates, not tile coordinates)
|
||||
playerPosition = new Vector2(180, 130);
|
||||
playerTileX = 0;
|
||||
playerTileY = 0;
|
||||
|
||||
// Render texture to render fog of war
|
||||
// NOTE: To get an automatic smooth-fog effect we use a render texture to render fog
|
||||
// at a smaller size (one pixel per tile) and scale it on drawing with bilinear filtering
|
||||
fogOfWar = LoadRenderTexture((int)map.TilesX, (int)map.TilesY);
|
||||
SetTextureFilter(fogOfWar.Texture, TextureFilter.Bilinear);
|
||||
SetTextureWrap(fogOfWar.Texture, TextureWrap.Clamp);
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// Move player around
|
||||
if (IsKeyDown(KeyboardKey.Right))
|
||||
{
|
||||
playerPosition.X += 5;
|
||||
}
|
||||
if (IsKeyDown(KeyboardKey.Left))
|
||||
{
|
||||
playerPosition.X -= 5;
|
||||
}
|
||||
if (IsKeyDown(KeyboardKey.Down))
|
||||
{
|
||||
playerPosition.Y += 5;
|
||||
}
|
||||
if (IsKeyDown(KeyboardKey.Up))
|
||||
{
|
||||
playerPosition.Y -= 5;
|
||||
}
|
||||
|
||||
// Check player position to avoid moving outside tilemap limits
|
||||
if (playerPosition.X < 0)
|
||||
{
|
||||
playerPosition.X = 0;
|
||||
}
|
||||
else if ((playerPosition.X + PlayerSize) > (map.TilesX * MapTileSize))
|
||||
{
|
||||
playerPosition.X = (float)map.TilesX * MapTileSize - PlayerSize;
|
||||
}
|
||||
if (playerPosition.Y < 0)
|
||||
{
|
||||
playerPosition.Y = 0;
|
||||
}
|
||||
else if ((playerPosition.Y + PlayerSize) > (map.TilesY * MapTileSize))
|
||||
{
|
||||
playerPosition.Y = (float)map.TilesY * MapTileSize - PlayerSize;
|
||||
}
|
||||
|
||||
// Previous visited tiles are set to partial fog
|
||||
for (uint i = 0; i < map.TilesX * map.TilesY; i++)
|
||||
{
|
||||
if (map.TileFog[i] == 1)
|
||||
{
|
||||
map.TileFog[i] = 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Get current tile position from player pixel position
|
||||
playerTileX = (int)((playerPosition.X + (float)MapTileSize / 2) / MapTileSize);
|
||||
playerTileY = (int)((playerPosition.Y + (float)MapTileSize / 2) / MapTileSize);
|
||||
|
||||
// Check visibility and update fog
|
||||
// NOTE: We check tilemap limits to avoid processing tiles out-of-array-bounds (it could crash program)
|
||||
for (var y = (playerTileY - PlayerTileVisibility); y < (playerTileY + PlayerTileVisibility); y++)
|
||||
{
|
||||
for (var x = (playerTileX - PlayerTileVisibility); x < (playerTileX + PlayerTileVisibility); x++)
|
||||
{
|
||||
if ((x >= 0) && (x < (int)map.TilesX) && (y >= 0) && (y < (int)map.TilesY))
|
||||
{
|
||||
map.TileFog[y * map.TilesX + x] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
// Draw fog of war to a small render texture for automatic smoothing on scaling
|
||||
BeginTextureMode(fogOfWar);
|
||||
ClearBackground(Color.Blank);
|
||||
for (uint y = 0; y < map.TilesY; y++)
|
||||
{
|
||||
for (uint x = 0; x < map.TilesX; x++)
|
||||
{
|
||||
if (map.TileFog[y * map.TilesX + x] == 0)
|
||||
{
|
||||
DrawRectangle((int)x, (int)y, 1, 1, Color.Black);
|
||||
}
|
||||
else if (map.TileFog[y * map.TilesX + x] == 2)
|
||||
{
|
||||
DrawRectangle((int)x, (int)y, 1, 1, Fade(Color.Black, 0.8f));
|
||||
}
|
||||
}
|
||||
}
|
||||
EndTextureMode();
|
||||
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
for (uint y = 0; y < map.TilesY; y++)
|
||||
{
|
||||
for (uint x = 0; x < map.TilesX; x++)
|
||||
{
|
||||
// Draw tiles from id (and tile borders)
|
||||
DrawRectangle((int)x * MapTileSize, (int)y * MapTileSize, MapTileSize, MapTileSize,
|
||||
(map.TileIds[y * map.TilesX + x] == 0) ? Color.Blue : Fade(Color.Blue, 0.9f));
|
||||
DrawRectangleLines((int)x * MapTileSize, (int)y * MapTileSize, MapTileSize, MapTileSize, Fade(Color.DarkBlue, 0.5f));
|
||||
}
|
||||
}
|
||||
|
||||
// Draw player
|
||||
DrawRectangleV(playerPosition, new Vector2(PlayerSize, PlayerSize), Color.Red);
|
||||
|
||||
// Draw fog of war (scaled to full map, bilinear filtering)
|
||||
DrawTexturePro(fogOfWar.Texture,
|
||||
new Rectangle(0, 0, (float)fogOfWar.Texture.Width, (float)-fogOfWar.Texture.Height),
|
||||
new Rectangle(0, 0, (float)map.TilesX * MapTileSize, (float)map.TilesY * MapTileSize),
|
||||
new Vector2(0, 0), 0.0f, Color.White);
|
||||
|
||||
// Draw player current tile
|
||||
DrawText($"Current tile: [{playerTileX},{playerTileY}]", 10, 10, 20, Color.RayWhite);
|
||||
DrawText("ARROW KEYS to move", 10, screenHeight - 25, 20, Color.RayWhite);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
UnloadRenderTexture(fogOfWar); // Unload render texture
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - fog of war");
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
var game = new FogOfWar();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
246
Examples/Textures/FramebufferRendering.cs
Normal file
246
Examples/Textures/FramebufferRendering.cs
Normal file
|
|
@ -0,0 +1,246 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [textures] example - framebuffer rendering
|
||||
*
|
||||
* Example complexity rating: [★★☆☆] 2/4
|
||||
*
|
||||
* Example originally created with raylib 5.6, last time updated with raylib 5.6
|
||||
*
|
||||
* Example contributed by Jack Boakes (@jackboakes) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2026 Jack Boakes (@jackboakes)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using static Raylib_cs.Raymath;
|
||||
|
||||
namespace Examples.Textures;
|
||||
|
||||
public partial class FramebufferRendering : IExample
|
||||
{
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
private const int splitWidth = screenWidth / 2;
|
||||
|
||||
public string Name => "Textures / Framebuffer Rendering";
|
||||
|
||||
public string Title => "raylib [textures] example - framebuffer rendering";
|
||||
|
||||
public bool CursorDisabled => true;
|
||||
|
||||
private Camera3D subjectCamera;
|
||||
private Camera3D observerCamera;
|
||||
|
||||
private RenderTexture2D observerTarget;
|
||||
private Rectangle observerSource;
|
||||
private Rectangle observerDest;
|
||||
|
||||
private RenderTexture2D subjectTarget;
|
||||
private Rectangle subjectSource;
|
||||
private Rectangle subjectDest;
|
||||
private float textureAspectRatio;
|
||||
|
||||
private const float captureSize = 128.0f;
|
||||
private Rectangle cropSource;
|
||||
private Rectangle cropDest;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
// Camera to look at the 3D world
|
||||
subjectCamera = new Camera3D();
|
||||
subjectCamera.Position = new Vector3(5.0f, 5.0f, 5.0f);
|
||||
subjectCamera.Target = new Vector3(0.0f, 0.0f, 0.0f);
|
||||
subjectCamera.Up = new Vector3(0.0f, 1.0f, 0.0f);
|
||||
subjectCamera.FovY = 45.0f;
|
||||
subjectCamera.Projection = CameraProjection.Perspective;
|
||||
|
||||
// Camera to observe the subject camera and 3D world
|
||||
observerCamera = new Camera3D();
|
||||
observerCamera.Position = new Vector3(10.0f, 10.0f, 10.0f);
|
||||
observerCamera.Target = new Vector3(0.0f, 0.0f, 0.0f);
|
||||
observerCamera.Up = new Vector3(0.0f, 1.0f, 0.0f);
|
||||
observerCamera.FovY = 45.0f;
|
||||
observerCamera.Projection = CameraProjection.Perspective;
|
||||
|
||||
// Set up render textures
|
||||
observerTarget = LoadRenderTexture(splitWidth, screenHeight);
|
||||
observerSource = new Rectangle(0.0f, 0.0f, observerTarget.Texture.Width, -observerTarget.Texture.Height);
|
||||
observerDest = new Rectangle(0.0f, 0.0f, splitWidth, screenHeight);
|
||||
|
||||
subjectTarget = LoadRenderTexture(splitWidth, screenHeight);
|
||||
subjectSource = new Rectangle(0.0f, 0.0f, subjectTarget.Texture.Width, -subjectTarget.Texture.Height);
|
||||
subjectDest = new Rectangle(splitWidth, 0.0f, splitWidth, screenHeight);
|
||||
textureAspectRatio = (float)subjectTarget.Texture.Width / subjectTarget.Texture.Height;
|
||||
|
||||
// Rectangles for cropping render texture
|
||||
cropSource = new Rectangle((subjectTarget.Texture.Width - captureSize) / 2.0f, (subjectTarget.Texture.Height - captureSize) / 2.0f, captureSize, -captureSize);
|
||||
cropDest = new Rectangle(splitWidth + 20.0f, 20.0f, captureSize, captureSize);
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
UpdateCamera(ref observerCamera, CameraMode.Free);
|
||||
UpdateCamera(ref subjectCamera, CameraMode.Orbital);
|
||||
|
||||
if (IsKeyPressed(KeyboardKey.R))
|
||||
{
|
||||
observerCamera.Target = new Vector3(0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
// Build LHS observer view texture
|
||||
BeginTextureMode(observerTarget);
|
||||
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
BeginMode3D(observerCamera);
|
||||
|
||||
DrawGrid(10, 1.0f);
|
||||
DrawCube(new Vector3(0.0f, 0.0f, 0.0f), 2.0f, 2.0f, 2.0f, Color.Gold);
|
||||
DrawCubeWires(new Vector3(0.0f, 0.0f, 0.0f), 2.0f, 2.0f, 2.0f, Color.Pink);
|
||||
DrawCameraPrism(subjectCamera, textureAspectRatio, Color.Green);
|
||||
|
||||
EndMode3D();
|
||||
|
||||
DrawText("Observer View", 10, observerTarget.Texture.Height - 30, 20, Color.Black);
|
||||
DrawText("WASD + Mouse to Move", 10, 10, 20, Color.DarkGray);
|
||||
DrawText("Scroll to Zoom", 10, 30, 20, Color.DarkGray);
|
||||
DrawText("R to Reset Observer Target", 10, 50, 20, Color.DarkGray);
|
||||
|
||||
EndTextureMode();
|
||||
|
||||
// Build RHS subject view texture
|
||||
BeginTextureMode(subjectTarget);
|
||||
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
BeginMode3D(subjectCamera);
|
||||
|
||||
DrawCube(new Vector3(0.0f, 0.0f, 0.0f), 2.0f, 2.0f, 2.0f, Color.Gold);
|
||||
DrawCubeWires(new Vector3(0.0f, 0.0f, 0.0f), 2.0f, 2.0f, 2.0f, Color.Pink);
|
||||
DrawGrid(10, 1.0f);
|
||||
|
||||
EndMode3D();
|
||||
|
||||
DrawRectangleLines((int)((subjectTarget.Texture.Width - captureSize) / 2.0f), (int)((subjectTarget.Texture.Height - captureSize) / 2.0f), (int)captureSize, (int)captureSize, Color.Green);
|
||||
DrawText("Subject View", 10, subjectTarget.Texture.Height - 30, 20, Color.Black);
|
||||
|
||||
EndTextureMode();
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(Color.Black);
|
||||
|
||||
// Draw observer texture LHS
|
||||
DrawTexturePro(observerTarget.Texture, observerSource, observerDest, new Vector2(0.0f, 0.0f), 0.0f, Color.White);
|
||||
|
||||
// Draw subject texture RHS
|
||||
DrawTexturePro(subjectTarget.Texture, subjectSource, subjectDest, new Vector2(0.0f, 0.0f), 0.0f, Color.White);
|
||||
|
||||
// Draw the small crop overlay on top
|
||||
DrawTexturePro(subjectTarget.Texture, cropSource, cropDest, new Vector2(0.0f, 0.0f), 0.0f, Color.White);
|
||||
DrawRectangleLinesEx(cropDest, 2, Color.Black);
|
||||
|
||||
// Draw split screen divider line
|
||||
DrawLine(splitWidth, 0, splitWidth, screenHeight, Color.Black);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
UnloadRenderTexture(observerTarget);
|
||||
UnloadRenderTexture(subjectTarget);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
private static void DrawCameraPrism(Camera3D camera, float aspect, Color color)
|
||||
{
|
||||
float length = Vector3Distance(camera.Position, camera.Target);
|
||||
// Define the 4 corners of the camera's prism plane sliced at the target in Normalized Device Coordinates
|
||||
Vector3[] planeNDC =
|
||||
{
|
||||
new(-1.0f, -1.0f, 1.0f), // Bottom Left
|
||||
new( 1.0f, -1.0f, 1.0f), // Bottom Right
|
||||
new( 1.0f, 1.0f, 1.0f), // Top Right
|
||||
new(-1.0f, 1.0f, 1.0f) // Top Left
|
||||
};
|
||||
|
||||
// Build the matrices
|
||||
Matrix4x4 view = GetCameraMatrix(camera);
|
||||
Matrix4x4 proj = MatrixPerspective(camera.FovY * DEG2RAD, aspect, 0.05f, length);
|
||||
// Combine view and projection so we can reverse the full camera transform
|
||||
Matrix4x4 viewProj = MatrixMultiply(view, proj);
|
||||
// Invert the view-projection matrix to unproject points from NDC space back into world space
|
||||
Matrix4x4 inverseViewProj = MatrixInvert(viewProj);
|
||||
|
||||
// Transform the 4 plane corners from NDC into world space
|
||||
Vector3[] corners = new Vector3[4];
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
float x = planeNDC[i].X;
|
||||
float y = planeNDC[i].Y;
|
||||
float z = planeNDC[i].Z;
|
||||
|
||||
// Multiply NDC position by the inverse view-projection matrix
|
||||
// This produces a homogeneous (x, y, z, w) position in world space
|
||||
float vx = inverseViewProj.M11 * x + inverseViewProj.M12 * y + inverseViewProj.M13 * z + inverseViewProj.M14;
|
||||
float vy = inverseViewProj.M21 * x + inverseViewProj.M22 * y + inverseViewProj.M23 * z + inverseViewProj.M24;
|
||||
float vz = inverseViewProj.M31 * x + inverseViewProj.M32 * y + inverseViewProj.M33 * z + inverseViewProj.M34;
|
||||
float vw = inverseViewProj.M41 * x + inverseViewProj.M42 * y + inverseViewProj.M43 * z + inverseViewProj.M44;
|
||||
|
||||
corners[i] = new Vector3(vx / vw, vy / vw, vz / vw);
|
||||
}
|
||||
|
||||
// Draw the far plane sliced at the target
|
||||
DrawLine3D(corners[0], corners[1], color);
|
||||
DrawLine3D(corners[1], corners[2], color);
|
||||
DrawLine3D(corners[2], corners[3], color);
|
||||
DrawLine3D(corners[3], corners[0], color);
|
||||
|
||||
// Draw the prism lines from the far plane to the camera position
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
DrawLine3D(camera.Position, corners[i], color);
|
||||
}
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - framebuffer rendering");
|
||||
|
||||
SetTargetFPS(60);
|
||||
DisableCursor();
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
var game = new FramebufferRendering();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
169
Examples/Textures/GifPlayer.cs
Normal file
169
Examples/Textures/GifPlayer.cs
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [textures] example - gif player
|
||||
*
|
||||
* Example complexity rating: [★★★☆] 3/4
|
||||
*
|
||||
* Example originally created with raylib 4.2, last time updated with raylib 4.2
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2021-2025 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
namespace Examples.Textures;
|
||||
|
||||
public partial class GifPlayer : IExample
|
||||
{
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
private const int MaxFrameDelay = 20;
|
||||
private const int MinFrameDelay = 1;
|
||||
|
||||
public string Name => "Textures / Gif Player";
|
||||
|
||||
public string Title => "raylib [textures] example - gif player";
|
||||
|
||||
private int animFrames;
|
||||
private Image imScarfyAnim;
|
||||
private Texture2D texScarfyAnim;
|
||||
private uint nextFrameDataOffset; // Current byte offset to next frame in image.data
|
||||
private int currentAnimFrame; // Current animation frame to load and draw
|
||||
private int frameDelay; // Frame delay to switch between animation frames
|
||||
private int frameCounter; // General frames counter
|
||||
|
||||
public void Init()
|
||||
{
|
||||
animFrames = 0;
|
||||
|
||||
// Load all GIF animation frames into a single Image
|
||||
// NOTE: GIF data is always loaded as RGBA (32bit) by default
|
||||
// NOTE: Frames are just appended one after another in image.data memory
|
||||
imScarfyAnim = LoadImageAnim("resources/scarfy_run.gif", out animFrames);
|
||||
|
||||
// Load texture from image
|
||||
// NOTE: We will update this texture when required with next frame data
|
||||
// WARNING: It's not recommended to use this technique for sprites animation,
|
||||
// use spritesheets instead, like illustrated in textures_sprite_anim example
|
||||
texScarfyAnim = LoadTextureFromImage(imScarfyAnim);
|
||||
|
||||
nextFrameDataOffset = 0;
|
||||
|
||||
currentAnimFrame = 0;
|
||||
frameDelay = 8;
|
||||
frameCounter = 0;
|
||||
}
|
||||
|
||||
public unsafe void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
frameCounter++;
|
||||
if (frameCounter >= frameDelay)
|
||||
{
|
||||
// Move to next frame
|
||||
// NOTE: If final frame is reached we return to first frame
|
||||
currentAnimFrame++;
|
||||
if (currentAnimFrame >= animFrames)
|
||||
{
|
||||
currentAnimFrame = 0;
|
||||
}
|
||||
|
||||
// Get memory offset position for next frame data in image.data
|
||||
nextFrameDataOffset = (uint)(imScarfyAnim.Width * imScarfyAnim.Height * 4 * currentAnimFrame);
|
||||
|
||||
// Update GPU texture data with next frame image data
|
||||
// WARNING: Data size (frame size) and pixel format must match already created texture
|
||||
UpdateTexture(texScarfyAnim, (byte*)imScarfyAnim.Data + nextFrameDataOffset);
|
||||
|
||||
frameCounter = 0;
|
||||
}
|
||||
|
||||
// Control frames delay
|
||||
if (IsKeyPressed(KeyboardKey.Right))
|
||||
{
|
||||
frameDelay++;
|
||||
}
|
||||
else if (IsKeyPressed(KeyboardKey.Left))
|
||||
{
|
||||
frameDelay--;
|
||||
}
|
||||
|
||||
if (frameDelay > MaxFrameDelay)
|
||||
{
|
||||
frameDelay = MaxFrameDelay;
|
||||
}
|
||||
else if (frameDelay < MinFrameDelay)
|
||||
{
|
||||
frameDelay = MinFrameDelay;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
DrawText($"TOTAL GIF FRAMES: {animFrames:D2}", 50, 30, 20, Color.LightGray);
|
||||
DrawText($"CURRENT FRAME: {currentAnimFrame:D2}", 50, 60, 20, Color.Gray);
|
||||
DrawText($"CURRENT FRAME IMAGE.DATA OFFSET: {nextFrameDataOffset:D2}", 50, 90, 20, Color.Gray);
|
||||
|
||||
DrawText("FRAMES DELAY: ", 100, 305, 10, Color.DarkGray);
|
||||
DrawText($"{frameDelay:D2} frames", 620, 305, 10, Color.DarkGray);
|
||||
DrawText("PRESS RIGHT/LEFT KEYS to CHANGE SPEED!", 290, 350, 10, Color.DarkGray);
|
||||
|
||||
for (var i = 0; i < MaxFrameDelay; i++)
|
||||
{
|
||||
if (i < frameDelay)
|
||||
{
|
||||
DrawRectangle(190 + 21 * i, 300, 20, 20, Color.Red);
|
||||
}
|
||||
DrawRectangleLines(190 + 21 * i, 300, 20, 20, Color.Maroon);
|
||||
}
|
||||
|
||||
DrawTexture(texScarfyAnim, GetScreenWidth() / 2 - texScarfyAnim.Width / 2, 140, Color.White);
|
||||
|
||||
DrawText("(c) Scarfy sprite by Eiden Marsal", screenWidth - 200, screenHeight - 20, 10, Color.Gray);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
UnloadTexture(texScarfyAnim); // Unload texture
|
||||
UnloadImage(imScarfyAnim); // Unload image (contains all frames)
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - gif player");
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
var game = new GifPlayer();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
146
Examples/Textures/ImageChannel.cs
Normal file
146
Examples/Textures/ImageChannel.cs
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [textures] example - image channel
|
||||
*
|
||||
* NOTE: Images are loaded in CPU memory (RAM); textures are loaded in GPU memory (VRAM)
|
||||
*
|
||||
* Example complexity rating: [★★☆☆] 2/4
|
||||
*
|
||||
* Example originally created with raylib 5.5, last time updated with raylib 5.5
|
||||
*
|
||||
* Example contributed by Bruno Cabral (@brccabral) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2024-2025 Bruno Cabral (@brccabral) and Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
namespace Examples.Textures;
|
||||
|
||||
public partial class ImageChannel : IExample
|
||||
{
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
public string Name => "Textures / Image Channel";
|
||||
|
||||
public string Title => "raylib [textures] example - image channel";
|
||||
|
||||
private Texture2D fudesumiTexture;
|
||||
private Texture2D textureAlpha;
|
||||
private Texture2D textureRed;
|
||||
private Texture2D textureGreen;
|
||||
private Texture2D textureBlue;
|
||||
private Texture2D backgroundTexture;
|
||||
|
||||
private Rectangle fudesumiRec;
|
||||
private Rectangle fudesumiPos;
|
||||
private Rectangle redPos;
|
||||
private Rectangle greenPos;
|
||||
private Rectangle bluePos;
|
||||
private Rectangle alphaPos;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
var fudesumiImage = LoadImage("resources/fudesumi.png");
|
||||
|
||||
var imageAlpha = ImageFromChannel(fudesumiImage, 3);
|
||||
ImageAlphaMask(ref imageAlpha, imageAlpha);
|
||||
|
||||
var imageRed = ImageFromChannel(fudesumiImage, 0);
|
||||
ImageAlphaMask(ref imageRed, imageAlpha);
|
||||
|
||||
var imageGreen = ImageFromChannel(fudesumiImage, 1);
|
||||
ImageAlphaMask(ref imageGreen, imageAlpha);
|
||||
|
||||
var imageBlue = ImageFromChannel(fudesumiImage, 2);
|
||||
ImageAlphaMask(ref imageBlue, imageAlpha);
|
||||
|
||||
var backgroundImage = GenImageChecked(screenWidth, screenHeight, screenWidth / 20, screenHeight / 20, Color.Orange, Color.Yellow);
|
||||
|
||||
fudesumiTexture = LoadTextureFromImage(fudesumiImage);
|
||||
textureAlpha = LoadTextureFromImage(imageAlpha);
|
||||
textureRed = LoadTextureFromImage(imageRed);
|
||||
textureGreen = LoadTextureFromImage(imageGreen);
|
||||
textureBlue = LoadTextureFromImage(imageBlue);
|
||||
backgroundTexture = LoadTextureFromImage(backgroundImage);
|
||||
|
||||
fudesumiRec = new Rectangle(0, 0, fudesumiImage.Width, fudesumiImage.Height);
|
||||
|
||||
fudesumiPos = new Rectangle(50, 10, fudesumiImage.Width * 0.8f, fudesumiImage.Height * 0.8f);
|
||||
redPos = new Rectangle(410, 10, fudesumiPos.Width / 2.0f, fudesumiPos.Height / 2.0f);
|
||||
greenPos = new Rectangle(600, 10, fudesumiPos.Width / 2.0f, fudesumiPos.Height / 2.0f);
|
||||
bluePos = new Rectangle(410, 230, fudesumiPos.Width / 2.0f, fudesumiPos.Height / 2.0f);
|
||||
alphaPos = new Rectangle(600, 230, fudesumiPos.Width / 2.0f, fudesumiPos.Height / 2.0f);
|
||||
|
||||
UnloadImage(fudesumiImage);
|
||||
UnloadImage(imageAlpha);
|
||||
UnloadImage(imageRed);
|
||||
UnloadImage(imageGreen);
|
||||
UnloadImage(imageBlue);
|
||||
UnloadImage(backgroundImage);
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// Nothing to update...
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
DrawTexture(backgroundTexture, 0, 0, Color.White);
|
||||
DrawTexturePro(fudesumiTexture, fudesumiRec, fudesumiPos, new Vector2(0, 0), 0, Color.White);
|
||||
|
||||
DrawTexturePro(textureRed, fudesumiRec, redPos, new Vector2(0, 0), 0, Color.Red);
|
||||
DrawTexturePro(textureGreen, fudesumiRec, greenPos, new Vector2(0, 0), 0, Color.Green);
|
||||
DrawTexturePro(textureBlue, fudesumiRec, bluePos, new Vector2(0, 0), 0, Color.Blue);
|
||||
DrawTexturePro(textureAlpha, fudesumiRec, alphaPos, new Vector2(0, 0), 0, Color.White);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
UnloadTexture(backgroundTexture);
|
||||
UnloadTexture(fudesumiTexture);
|
||||
UnloadTexture(textureRed);
|
||||
UnloadTexture(textureGreen);
|
||||
UnloadTexture(textureBlue);
|
||||
UnloadTexture(textureAlpha);
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - image channel");
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
var game = new ImageChannel();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,100 +1,115 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [textures] example - Image loading and drawing on it
|
||||
* raylib [textures] example - image drawing
|
||||
*
|
||||
* Example complexity rating: [★★☆☆] 2/4
|
||||
*
|
||||
* NOTE: Images are loaded in CPU memory (RAM); textures are loaded in GPU memory (VRAM)
|
||||
*
|
||||
* This example has been created using raylib 1.4 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
* Example originally created with raylib 1.4, last time updated with raylib 1.4
|
||||
*
|
||||
* Copyright (c) 2016 Ramon Santamaria (@raysan5)
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2016-2025 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using System.Numerics;
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
namespace Examples.Textures;
|
||||
|
||||
public class ImageDrawing
|
||||
public partial class ImageDrawing : IExample
|
||||
{
|
||||
public static int Main()
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
public string Name => "Textures / Image Drawing";
|
||||
|
||||
public string Title => "raylib [textures] example - image drawing";
|
||||
|
||||
private Texture2D texture;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - image drawing");
|
||||
|
||||
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
|
||||
|
||||
Image cat = LoadImage("resources/cat.png");
|
||||
ImageCrop(ref cat, new Rectangle(100, 10, 280, 380));
|
||||
ImageFlipHorizontal(ref cat);
|
||||
ImageResize(ref cat, 150, 200);
|
||||
var cat = LoadImage("resources/cat.png"); // Load image in CPU memory (RAM)
|
||||
ImageCrop(ref cat, new Rectangle(100, 10, 280, 380)); // Crop an image piece
|
||||
ImageFlipHorizontal(ref cat); // Flip cropped image horizontally
|
||||
ImageResize(ref cat, 150, 200); // Resize flipped-cropped image
|
||||
|
||||
Image parrots = LoadImage("resources/parrots.png");
|
||||
var parrots = LoadImage("resources/parrots.png"); // Load image in CPU memory (RAM)
|
||||
|
||||
// Draw one image over the other with a scaling of 1.5f
|
||||
Rectangle src = new(0, 0, cat.Width, cat.Height);
|
||||
ImageDraw(ref parrots, cat, src, new Rectangle(30, 40, cat.Width * 1.5f, cat.Height * 1.5f), Color.White);
|
||||
ImageCrop(ref parrots, new Rectangle(0, 50, parrots.Width, parrots.Height - 100));
|
||||
ImageCrop(ref parrots, new Rectangle(0, 50, parrots.Width, parrots.Height - 100)); // Crop resulting image
|
||||
|
||||
// Draw on the image with a few image draw methods
|
||||
ImageDrawPixel(ref parrots, 10, 10, Color.RayWhite);
|
||||
ImageDrawCircle(ref parrots, 10, 10, 5, Color.RayWhite);
|
||||
ImageDrawCircleLines(ref parrots, 10, 10, 5, Color.RayWhite);
|
||||
ImageDrawRectangle(ref parrots, 5, 20, 10, 10, Color.RayWhite);
|
||||
|
||||
UnloadImage(cat);
|
||||
UnloadImage(cat); // Unload image from RAM
|
||||
|
||||
// Load custom font for frawing on image
|
||||
Font font = LoadFont("resources/fonts/custom_jupiter_crash.png");
|
||||
// Load custom font for drawing on image
|
||||
var font = LoadFont("resources/custom_jupiter_crash.png");
|
||||
|
||||
// Draw over image using custom font
|
||||
ImageDrawTextEx(ref parrots, font, "PARROTS & CAT", new Vector2(300, 230), font.BaseSize, -2, Color.White);
|
||||
|
||||
// Unload custom spritefont (already drawn used on image)
|
||||
UnloadFont(font);
|
||||
UnloadFont(font); // Unload custom font (already drawn used on image)
|
||||
|
||||
Texture2D texture = LoadTextureFromImage(parrots);
|
||||
UnloadImage(parrots);
|
||||
texture = LoadTextureFromImage(parrots); // Image converted to texture, uploaded to GPU memory (VRAM)
|
||||
UnloadImage(parrots); // Once image has been converted to texture and uploaded to VRAM, it can be unloaded from RAM
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
var x = screenWidth / 2 - texture.Width / 2;
|
||||
var y = screenHeight / 2 - texture.Height / 2;
|
||||
DrawTexture(texture, x, y - 40, Color.White);
|
||||
DrawRectangleLines(x, y - 40, texture.Width, texture.Height, Color.DarkGray);
|
||||
|
||||
DrawText("We are drawing only one texture from various images composed!", 240, 350, 10, Color.DarkGray);
|
||||
DrawText("Source images have been cropped, scaled, flipped and copied one over the other.", 190, 370, 10, Color.DarkGray);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
UnloadTexture(texture); // Texture unloading
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - image drawing");
|
||||
|
||||
SetTargetFPS(60);
|
||||
//---------------------------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
var game = new ImageDrawing();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// TODO: Update your variables here
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
int x = screenWidth / 2 - texture.Width / 2;
|
||||
int y = screenHeight / 2 - texture.Height / 2;
|
||||
DrawTexture(texture, x, y - 40, Color.White);
|
||||
DrawRectangleLines(x, y - 40, texture.Width, texture.Height, Color.DarkGray);
|
||||
|
||||
DrawText("We are drawing only one texture from various images composed!", 240, 350, 10, Color.DarkGray);
|
||||
|
||||
string text = "Source images have been cropped, scaled, flipped and copied one over the other.";
|
||||
DrawText(text, 90, 370, 10, Color.DarkGray);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadTexture(texture);
|
||||
|
||||
CloseWindow();
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -1,116 +1,163 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [textures] example - Procedural images generation
|
||||
* raylib [textures] example - image generation
|
||||
*
|
||||
* This example has been created using raylib 1.8 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
* Example complexity rating: [★★☆☆] 2/4
|
||||
*
|
||||
* Copyright (c) 2O17 Wilhem Barbier (@nounoursheureux)
|
||||
* Example originally created with raylib 1.8, last time updated with raylib 1.8
|
||||
*
|
||||
* Example contributed by Wilhem Barbier (@nounoursheureux) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2017-2025 Wilhem Barbier (@nounoursheureux) and Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
namespace Examples.Textures;
|
||||
|
||||
public class ImageGeneration
|
||||
public partial class ImageGeneration : IExample
|
||||
{
|
||||
public const int NumTextures = 6;
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
// Currently we have 8 generation algorithms but some have multiple purposes (Linear and Square Gradients)
|
||||
public const int NumTextures = 9;
|
||||
|
||||
public string Name => "Textures / Image Generation";
|
||||
|
||||
public string Title => "raylib [textures] example - image generation";
|
||||
|
||||
private Texture2D[] textures;
|
||||
private int currentTexture;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
var verticalGradient = GenImageGradientLinear(screenWidth, screenHeight, 0, Color.Red, Color.Blue);
|
||||
var horizontalGradient = GenImageGradientLinear(screenWidth, screenHeight, 90, Color.Red, Color.Blue);
|
||||
var diagonalGradient = GenImageGradientLinear(screenWidth, screenHeight, 45, Color.Red, Color.Blue);
|
||||
var radialGradient = GenImageGradientRadial(screenWidth, screenHeight, 0.0f, Color.White, Color.Black);
|
||||
var squareGradient = GenImageGradientSquare(screenWidth, screenHeight, 0.0f, Color.White, Color.Black);
|
||||
var isChecked = GenImageChecked(screenWidth, screenHeight, 32, 32, Color.Red, Color.Blue);
|
||||
var whiteNoise = GenImageWhiteNoise(screenWidth, screenHeight, 0.5f);
|
||||
var perlinNoise = GenImagePerlinNoise(screenWidth, screenHeight, 50, 50, 4.0f);
|
||||
var cellular = GenImageCellular(screenWidth, screenHeight, 32);
|
||||
|
||||
textures = new Texture2D[NumTextures];
|
||||
textures[0] = LoadTextureFromImage(verticalGradient);
|
||||
textures[1] = LoadTextureFromImage(horizontalGradient);
|
||||
textures[2] = LoadTextureFromImage(diagonalGradient);
|
||||
textures[3] = LoadTextureFromImage(radialGradient);
|
||||
textures[4] = LoadTextureFromImage(squareGradient);
|
||||
textures[5] = LoadTextureFromImage(isChecked);
|
||||
textures[6] = LoadTextureFromImage(whiteNoise);
|
||||
textures[7] = LoadTextureFromImage(perlinNoise);
|
||||
textures[8] = LoadTextureFromImage(cellular);
|
||||
|
||||
// Unload image data (CPU RAM)
|
||||
UnloadImage(verticalGradient);
|
||||
UnloadImage(horizontalGradient);
|
||||
UnloadImage(diagonalGradient);
|
||||
UnloadImage(radialGradient);
|
||||
UnloadImage(squareGradient);
|
||||
UnloadImage(isChecked);
|
||||
UnloadImage(whiteNoise);
|
||||
UnloadImage(perlinNoise);
|
||||
UnloadImage(cellular);
|
||||
|
||||
currentTexture = 0;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsMouseButtonPressed(MouseButton.Left) || IsKeyPressed(KeyboardKey.Right))
|
||||
{
|
||||
// Cycle between the textures
|
||||
currentTexture = (currentTexture + 1) % NumTextures;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
DrawTexture(textures[currentTexture], 0, 0, Color.White);
|
||||
|
||||
DrawRectangle(30, 400, 325, 30, Fade(Color.SkyBlue, 0.5f));
|
||||
DrawRectangleLines(30, 400, 325, 30, Fade(Color.White, 0.5f));
|
||||
DrawText("MOUSE LEFT BUTTON to CYCLE PROCEDURAL TEXTURES", 40, 410, 10, Color.White);
|
||||
|
||||
switch (currentTexture)
|
||||
{
|
||||
case 0:
|
||||
DrawText("VERTICAL GRADIENT", 560, 10, 20, Color.RayWhite);
|
||||
break;
|
||||
case 1:
|
||||
DrawText("HORIZONTAL GRADIENT", 540, 10, 20, Color.RayWhite);
|
||||
break;
|
||||
case 2:
|
||||
DrawText("DIAGONAL GRADIENT", 540, 10, 20, Color.RayWhite);
|
||||
break;
|
||||
case 3:
|
||||
DrawText("RADIAL GRADIENT", 580, 10, 20, Color.LightGray);
|
||||
break;
|
||||
case 4:
|
||||
DrawText("SQUARE GRADIENT", 580, 10, 20, Color.LightGray);
|
||||
break;
|
||||
case 5:
|
||||
DrawText("CHECKED", 680, 10, 20, Color.RayWhite);
|
||||
break;
|
||||
case 6:
|
||||
DrawText("WHITE NOISE", 640, 10, 20, Color.Red);
|
||||
break;
|
||||
case 7:
|
||||
DrawText("PERLIN NOISE", 640, 10, 20, Color.Red);
|
||||
break;
|
||||
case 8:
|
||||
DrawText("CELLULAR", 670, 10, 20, Color.RayWhite);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
for (var i = 0; i < textures.Length; i++)
|
||||
{
|
||||
UnloadTexture(textures[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - procedural images generation");
|
||||
|
||||
Image verticalGradient = GenImageGradientLinear(screenWidth, screenHeight, 0, Color.Red, Color.Blue);
|
||||
Image horizontalGradient = GenImageGradientLinear(screenWidth, screenHeight, 90, Color.Red, Color.Blue);
|
||||
Image radialGradient = GenImageGradientRadial(screenWidth, screenHeight, 0.0f, Color.White, Color.Black);
|
||||
Image isChecked = GenImageChecked(screenWidth, screenHeight, 32, 32, Color.Red, Color.Blue);
|
||||
Image whiteNoise = GenImageWhiteNoise(screenWidth, screenHeight, 0.5f);
|
||||
Image cellular = GenImageCellular(screenWidth, screenHeight, 32);
|
||||
|
||||
Texture2D[] textures = new Texture2D[NumTextures];
|
||||
textures[0] = LoadTextureFromImage(verticalGradient);
|
||||
textures[1] = LoadTextureFromImage(horizontalGradient);
|
||||
textures[2] = LoadTextureFromImage(radialGradient);
|
||||
textures[3] = LoadTextureFromImage(isChecked);
|
||||
textures[4] = LoadTextureFromImage(whiteNoise);
|
||||
textures[5] = LoadTextureFromImage(cellular);
|
||||
|
||||
UnloadImage(verticalGradient);
|
||||
UnloadImage(horizontalGradient);
|
||||
UnloadImage(radialGradient);
|
||||
UnloadImage(isChecked);
|
||||
UnloadImage(whiteNoise);
|
||||
UnloadImage(cellular);
|
||||
|
||||
int currentTexture = 0;
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - image generation");
|
||||
|
||||
SetTargetFPS(60);
|
||||
//---------------------------------------------------------------------------------------
|
||||
|
||||
var game = new ImageGeneration();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsMouseButtonPressed(MouseButton.Left) || IsKeyPressed(KeyboardKey.Right))
|
||||
{
|
||||
// Cycle between the textures
|
||||
currentTexture = (currentTexture + 1) % NumTextures;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
DrawTexture(textures[currentTexture], 0, 0, Color.White);
|
||||
|
||||
DrawRectangle(30, 400, 325, 30, ColorAlpha(Color.SkyBlue, 0.5f));
|
||||
DrawRectangleLines(30, 400, 325, 30, ColorAlpha(Color.White, 0.5f));
|
||||
DrawText("MOUSE LEFT BUTTON to CYCLE PROCEDURAL TEXTURES", 40, 410, 10, Color.White);
|
||||
|
||||
switch (currentTexture)
|
||||
{
|
||||
case 0:
|
||||
DrawText("VERTICAL GRADIENT", 560, 10, 20, Color.RayWhite);
|
||||
break;
|
||||
case 1:
|
||||
DrawText("HORIZONTAL GRADIENT", 540, 10, 20, Color.RayWhite);
|
||||
break;
|
||||
case 2:
|
||||
DrawText("RADIAL GRADIENT", 580, 10, 20, Color.LightGray);
|
||||
break;
|
||||
case 3:
|
||||
DrawText("CHECKED", 680, 10, 20, Color.RayWhite);
|
||||
break;
|
||||
case 4:
|
||||
DrawText("Color.WHITE NOISE", 640, 10, 20, Color.Red);
|
||||
break;
|
||||
case 5:
|
||||
DrawText("CELLULAR", 670, 10, 20, Color.RayWhite);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
for (int i = 0; i < textures.Length; i++)
|
||||
{
|
||||
UnloadTexture(textures[i]);
|
||||
}
|
||||
|
||||
CloseWindow();
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
|
|
|
|||
163
Examples/Textures/ImageKernel.cs
Normal file
163
Examples/Textures/ImageKernel.cs
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [textures] example - image kernel
|
||||
*
|
||||
* Example complexity rating: [★★★★] 4/4
|
||||
*
|
||||
* NOTE: Images are loaded in CPU memory (RAM); textures are loaded in GPU memory (VRAM)
|
||||
*
|
||||
* Example contributed by Karim Salem (@kimo-s) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Example originally created with raylib 1.3, last time updated with raylib 1.3
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2015-2025 Karim Salem (@kimo-s)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
namespace Examples.Textures;
|
||||
|
||||
public partial class ImageKernel : IExample
|
||||
{
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
public string Name => "Textures / Image Kernel";
|
||||
|
||||
public string Title => "raylib [textures] example - image kernel";
|
||||
|
||||
private Texture2D texture;
|
||||
private Texture2D catSharpendTexture;
|
||||
private Texture2D catSobelTexture;
|
||||
private Texture2D catGaussianTexture;
|
||||
|
||||
private static void NormalizeKernel(float[] kernel, int size)
|
||||
{
|
||||
var sum = 0.0f;
|
||||
for (var i = 0; i < size; i++)
|
||||
{
|
||||
sum += kernel[i];
|
||||
}
|
||||
|
||||
if (sum != 0.0f)
|
||||
{
|
||||
for (var i = 0; i < size; i++)
|
||||
{
|
||||
kernel[i] /= sum;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
var image = LoadImage("resources/cat.png"); // Loaded in CPU memory (RAM)
|
||||
|
||||
float[] gaussiankernel = {
|
||||
1.0f, 2.0f, 1.0f,
|
||||
2.0f, 4.0f, 2.0f,
|
||||
1.0f, 2.0f, 1.0f
|
||||
};
|
||||
|
||||
float[] sobelkernel = {
|
||||
1.0f, 0.0f, -1.0f,
|
||||
2.0f, 0.0f, -2.0f,
|
||||
1.0f, 0.0f, -1.0f
|
||||
};
|
||||
|
||||
float[] sharpenkernel = {
|
||||
0.0f, -1.0f, 0.0f,
|
||||
-1.0f, 5.0f, -1.0f,
|
||||
0.0f, -1.0f, 0.0f
|
||||
};
|
||||
|
||||
NormalizeKernel(gaussiankernel, 9);
|
||||
NormalizeKernel(sharpenkernel, 9);
|
||||
NormalizeKernel(sobelkernel, 9);
|
||||
|
||||
var catSharpend = ImageCopy(image);
|
||||
ImageKernelConvolution(ref catSharpend, sharpenkernel);
|
||||
|
||||
var catSobel = ImageCopy(image);
|
||||
ImageKernelConvolution(ref catSobel, sobelkernel);
|
||||
|
||||
var catGaussian = ImageCopy(image);
|
||||
|
||||
for (var i = 0; i < 6; i++)
|
||||
{
|
||||
ImageKernelConvolution(ref catGaussian, gaussiankernel);
|
||||
}
|
||||
|
||||
ImageCrop(ref image, new Rectangle(0, 0, 200, 450));
|
||||
ImageCrop(ref catGaussian, new Rectangle(0, 0, 200, 450));
|
||||
ImageCrop(ref catSobel, new Rectangle(0, 0, 200, 450));
|
||||
ImageCrop(ref catSharpend, new Rectangle(0, 0, 200, 450));
|
||||
|
||||
// Images converted to texture, GPU memory (VRAM)
|
||||
texture = LoadTextureFromImage(image);
|
||||
catSharpendTexture = LoadTextureFromImage(catSharpend);
|
||||
catSobelTexture = LoadTextureFromImage(catSobel);
|
||||
catGaussianTexture = LoadTextureFromImage(catGaussian);
|
||||
|
||||
// Once images have been converted to texture and uploaded to VRAM,
|
||||
// they can be unloaded from RAM
|
||||
UnloadImage(image);
|
||||
UnloadImage(catGaussian);
|
||||
UnloadImage(catSobel);
|
||||
UnloadImage(catSharpend);
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
DrawTexture(catSharpendTexture, 0, 0, Color.White);
|
||||
DrawTexture(catSobelTexture, 200, 0, Color.White);
|
||||
DrawTexture(catGaussianTexture, 400, 0, Color.White);
|
||||
DrawTexture(texture, 600, 0, Color.White);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
UnloadTexture(texture);
|
||||
UnloadTexture(catGaussianTexture);
|
||||
UnloadTexture(catSobelTexture);
|
||||
UnloadTexture(catSharpendTexture);
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - image kernel");
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
var game = new ImageKernel();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,70 +1,90 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [textures] example - Image loading and texture creation
|
||||
* raylib [textures] example - image loading
|
||||
*
|
||||
* Example complexity rating: [★☆☆☆] 1/4
|
||||
*
|
||||
* NOTE: Images are loaded in CPU memory (RAM); textures are loaded in GPU memory (VRAM)
|
||||
*
|
||||
* This example has been created using raylib 1.3 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
* Example originally created with raylib 1.3, last time updated with raylib 1.3
|
||||
*
|
||||
* Copyright (c) 2015 Ramon Santamaria (@raysan5)
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2015-2025 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
namespace Examples.Textures;
|
||||
|
||||
public class ImageLoading
|
||||
public partial class ImageLoading : IExample
|
||||
{
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
public string Name => "Textures / Image Loading";
|
||||
|
||||
public string Title => "raylib [textures] example - image loading";
|
||||
|
||||
private Texture2D texture;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
|
||||
|
||||
var image = LoadImage("resources/raylib-cs_logo.png"); // Loaded in CPU memory (RAM)
|
||||
texture = LoadTextureFromImage(image); // Image converted to texture, GPU memory (VRAM)
|
||||
UnloadImage(image); // Once image has been converted to texture and uploaded to VRAM, it can be unloaded from RAM
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
DrawTexture(
|
||||
texture,
|
||||
screenWidth / 2 - texture.Width / 2,
|
||||
screenHeight / 2 - texture.Height / 2,
|
||||
Color.White
|
||||
);
|
||||
|
||||
DrawText("this IS a texture loaded from an image!", 300, 370, 10, Color.Gray);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
UnloadTexture(texture); // Texture unloading
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - image loading");
|
||||
|
||||
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
|
||||
|
||||
Image image = LoadImage("resources/raylib-cs_logo.png");
|
||||
Texture2D texture = LoadTextureFromImage(image);
|
||||
|
||||
UnloadImage(image);
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//---------------------------------------------------------------------------------------
|
||||
|
||||
var game = new ImageLoading();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// TODO: Update your variables here
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
DrawTexture(
|
||||
texture,
|
||||
screenWidth / 2 - texture.Width / 2,
|
||||
screenHeight / 2 - texture.Height / 2,
|
||||
Color.White
|
||||
);
|
||||
|
||||
DrawText("this IS a texture loaded from an image!", 300, 370, 10, Color.Gray);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadTexture(texture);
|
||||
|
||||
CloseWindow();
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -1,25 +1,34 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [textures] example - Image processing
|
||||
* raylib [textures] example - image processing
|
||||
*
|
||||
* Example complexity rating: [★★★☆] 3/4
|
||||
*
|
||||
* NOTE: Images are loaded in CPU memory (RAM); textures are loaded in GPU memory (VRAM)
|
||||
*
|
||||
* This example has been created using raylib 1.4 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
* Example originally created with raylib 1.4, last time updated with raylib 3.5
|
||||
*
|
||||
* Copyright (c) 2016 Ramon Santamaria (@raysan5)
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2016-2025 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
namespace Examples.Textures;
|
||||
|
||||
public class ImageProcessing
|
||||
public partial class ImageProcessing : IExample
|
||||
{
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
public const int NumProcesses = 9;
|
||||
|
||||
enum ImageProcess
|
||||
public string Name => "Textures / Image Processing";
|
||||
|
||||
public string Title => "raylib [textures] example - image processing";
|
||||
|
||||
private enum ImageProcess
|
||||
{
|
||||
None = 0,
|
||||
ColorGrayScale,
|
||||
|
|
@ -32,188 +41,210 @@ public class ImageProcessing
|
|||
FlipHorizontal
|
||||
}
|
||||
|
||||
static string[] processText = {
|
||||
"NO PROCESSING",
|
||||
"COLOR GRAYSCALE",
|
||||
"COLOR TINT",
|
||||
"COLOR INVERT",
|
||||
"COLOR CONTRAST",
|
||||
"COLOR BRIGHTNESS",
|
||||
"GAUSSIAN BLUR",
|
||||
"FLIP VERTICAL",
|
||||
"FLIP HORIZONTAL"
|
||||
};
|
||||
private string[] processText = {
|
||||
"NO PROCESSING",
|
||||
"COLOR GRAYSCALE",
|
||||
"COLOR TINT",
|
||||
"COLOR INVERT",
|
||||
"COLOR CONTRAST",
|
||||
"COLOR BRIGHTNESS",
|
||||
"GAUSSIAN BLUR",
|
||||
"FLIP VERTICAL",
|
||||
"FLIP HORIZONTAL"
|
||||
};
|
||||
|
||||
public unsafe static int Main()
|
||||
private Image imageOrigin;
|
||||
private Image imageCopy;
|
||||
private Texture2D texture;
|
||||
private ImageProcess currentProcess;
|
||||
private bool textureReload;
|
||||
private Rectangle[] toggleRecs;
|
||||
private int mouseHoverRec;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
|
||||
|
||||
imageOrigin = LoadImage("resources/parrots.png"); // Loaded in CPU memory (RAM)
|
||||
ImageFormat(ref imageOrigin, PixelFormat.UncompressedR8G8B8A8); // Format image to RGBA 32bit (required for texture update) <-- ISSUE
|
||||
texture = LoadTextureFromImage(imageOrigin); // Image converted to texture, GPU memory (VRAM)
|
||||
|
||||
imageCopy = ImageCopy(imageOrigin);
|
||||
|
||||
currentProcess = ImageProcess.None;
|
||||
textureReload = false;
|
||||
|
||||
toggleRecs = new Rectangle[NumProcesses];
|
||||
mouseHoverRec = -1;
|
||||
|
||||
for (var i = 0; i < NumProcesses; i++)
|
||||
{
|
||||
toggleRecs[i] = new Rectangle(40.0f, (float)(50 + 32 * i), 150.0f, 30.0f);
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Mouse toggle group logic
|
||||
for (var i = 0; i < NumProcesses; i++)
|
||||
{
|
||||
if (CheckCollisionPointRec(GetMousePosition(), toggleRecs[i]))
|
||||
{
|
||||
mouseHoverRec = i;
|
||||
|
||||
if (IsMouseButtonReleased(MouseButton.Left))
|
||||
{
|
||||
currentProcess = (ImageProcess)i;
|
||||
textureReload = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
mouseHoverRec = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Keyboard toggle group logic
|
||||
if (IsKeyPressed(KeyboardKey.Down))
|
||||
{
|
||||
currentProcess++;
|
||||
if ((int)currentProcess > (NumProcesses - 1))
|
||||
{
|
||||
currentProcess = 0;
|
||||
}
|
||||
|
||||
textureReload = true;
|
||||
}
|
||||
else if (IsKeyPressed(KeyboardKey.Up))
|
||||
{
|
||||
currentProcess--;
|
||||
if (currentProcess < 0)
|
||||
{
|
||||
currentProcess = ImageProcess.FlipHorizontal;
|
||||
}
|
||||
|
||||
textureReload = true;
|
||||
}
|
||||
|
||||
// Reload texture when required
|
||||
if (textureReload)
|
||||
{
|
||||
UnloadImage(imageCopy); // Unload image-copy data
|
||||
imageCopy = ImageCopy(imageOrigin); // Restore image-copy from image-origin
|
||||
|
||||
// NOTE: Image processing is a costly CPU process to be done every frame,
|
||||
// If image processing is required in a frame-basis, it should be done
|
||||
// with a texture and by shaders
|
||||
switch (currentProcess)
|
||||
{
|
||||
case ImageProcess.ColorGrayScale:
|
||||
ImageColorGrayscale(ref imageCopy);
|
||||
break;
|
||||
case ImageProcess.ColorTint:
|
||||
ImageColorTint(ref imageCopy, Color.Green);
|
||||
break;
|
||||
case ImageProcess.ColorInvert:
|
||||
ImageColorInvert(ref imageCopy);
|
||||
break;
|
||||
case ImageProcess.ColorContrast:
|
||||
ImageColorContrast(ref imageCopy, -40);
|
||||
break;
|
||||
case ImageProcess.ColorBrightness:
|
||||
ImageColorBrightness(ref imageCopy, -80);
|
||||
break;
|
||||
case ImageProcess.GaussianBlur:
|
||||
ImageBlurGaussian(ref imageCopy, 10);
|
||||
break;
|
||||
case ImageProcess.FlipVertical:
|
||||
ImageFlipVertical(ref imageCopy);
|
||||
break;
|
||||
case ImageProcess.FlipHorizontal:
|
||||
ImageFlipHorizontal(ref imageCopy);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
var pixels = LoadImageColors(imageCopy); // Load pixel data from image (RGBA 32bit)
|
||||
UpdateTexture(texture, pixels); // Update texture with new image data
|
||||
UnloadImageColors(pixels); // Unload pixels data from RAM
|
||||
|
||||
textureReload = false;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
DrawText("IMAGE PROCESSING:", 40, 30, 10, Color.DarkGray);
|
||||
|
||||
// Draw rectangles
|
||||
for (var i = 0; i < NumProcesses; i++)
|
||||
{
|
||||
DrawRectangleRec(toggleRecs[i], ((i == (int)currentProcess) || (i == mouseHoverRec)) ? Color.SkyBlue : Color.LightGray);
|
||||
DrawRectangleLines(
|
||||
(int)toggleRecs[i].X,
|
||||
(int)toggleRecs[i].Y,
|
||||
(int)toggleRecs[i].Width,
|
||||
(int)toggleRecs[i].Height,
|
||||
((i == (int)currentProcess) || (i == mouseHoverRec)) ? Color.Blue : Color.Gray
|
||||
);
|
||||
|
||||
var labelX = (int)(toggleRecs[i].X + toggleRecs[i].Width / 2);
|
||||
DrawText(
|
||||
processText[i],
|
||||
(int)(labelX - MeasureText(processText[i], 10) / 2),
|
||||
(int)toggleRecs[i].Y + 11,
|
||||
10,
|
||||
((i == (int)currentProcess) || (i == mouseHoverRec)) ? Color.DarkBlue : Color.DarkGray
|
||||
);
|
||||
}
|
||||
|
||||
var x = screenWidth - texture.Width - 60;
|
||||
var y = screenHeight / 2 - texture.Height / 2;
|
||||
DrawTexture(texture, x, y, Color.White);
|
||||
DrawRectangleLines(x, y, texture.Width, texture.Height, Color.Black);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
UnloadTexture(texture); // Unload texture from VRAM
|
||||
UnloadImage(imageOrigin); // Unload image-origin from RAM
|
||||
UnloadImage(imageCopy); // Unload image-copy from RAM
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - image processing");
|
||||
|
||||
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
|
||||
Image imageOrigin = LoadImage("resources/parrots.png");
|
||||
ImageFormat(ref imageOrigin, PixelFormat.UncompressedR8G8B8A8);
|
||||
Texture2D texture = LoadTextureFromImage(imageOrigin);
|
||||
|
||||
Image imageCopy = ImageCopy(imageOrigin);
|
||||
|
||||
ImageProcess currentProcess = ImageProcess.None;
|
||||
bool textureReload = false;
|
||||
|
||||
Rectangle[] toggleRecs = new Rectangle[NumProcesses];
|
||||
int mouseHoverRec = -1;
|
||||
|
||||
for (int i = 0; i < NumProcesses; i++)
|
||||
{
|
||||
toggleRecs[i] = new Rectangle(40, 50 + 32 * i, 150, 30);
|
||||
}
|
||||
|
||||
SetTargetFPS(60);
|
||||
//---------------------------------------------------------------------------------------
|
||||
|
||||
var game = new ImageProcessing();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Mouse toggle group logic
|
||||
for (int i = 0; i < NumProcesses; i++)
|
||||
{
|
||||
if (CheckCollisionPointRec(GetMousePosition(), toggleRecs[i]))
|
||||
{
|
||||
mouseHoverRec = i;
|
||||
|
||||
if (IsMouseButtonReleased(MouseButton.Left))
|
||||
{
|
||||
currentProcess = (ImageProcess)i;
|
||||
textureReload = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
mouseHoverRec = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Keyboard toggle group logic
|
||||
if (IsKeyPressed(KeyboardKey.Down))
|
||||
{
|
||||
currentProcess++;
|
||||
if ((int)currentProcess > (NumProcesses - 1))
|
||||
{
|
||||
currentProcess = 0;
|
||||
}
|
||||
|
||||
textureReload = true;
|
||||
}
|
||||
else if (IsKeyPressed(KeyboardKey.Up))
|
||||
{
|
||||
currentProcess--;
|
||||
if (currentProcess < 0)
|
||||
{
|
||||
currentProcess = ImageProcess.FlipHorizontal;
|
||||
}
|
||||
|
||||
textureReload = true;
|
||||
}
|
||||
|
||||
if (textureReload)
|
||||
{
|
||||
UnloadImage(imageCopy);
|
||||
imageCopy = ImageCopy(imageOrigin);
|
||||
|
||||
// NOTE: Image processing is a costly CPU process to be done every frame,
|
||||
// If image processing is required in a frame-basis, it should be done
|
||||
// with a texture and by shaders
|
||||
switch (currentProcess)
|
||||
{
|
||||
case ImageProcess.ColorGrayScale:
|
||||
ImageColorGrayscale(ref imageCopy);
|
||||
break;
|
||||
case ImageProcess.ColorTint:
|
||||
ImageColorTint(ref imageCopy, Color.Green);
|
||||
break;
|
||||
case ImageProcess.ColorInvert:
|
||||
ImageColorInvert(ref imageCopy);
|
||||
break;
|
||||
case ImageProcess.ColorContrast:
|
||||
ImageColorContrast(ref imageCopy, -40);
|
||||
break;
|
||||
case ImageProcess.ColorBrightness:
|
||||
ImageColorBrightness(ref imageCopy, -80);
|
||||
break;
|
||||
case ImageProcess.GaussianBlur:
|
||||
ImageBlurGaussian(ref imageCopy, 10);
|
||||
break;
|
||||
case ImageProcess.FlipVertical:
|
||||
ImageFlipVertical(ref imageCopy);
|
||||
break;
|
||||
case ImageProcess.FlipHorizontal:
|
||||
ImageFlipHorizontal(ref imageCopy);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Get pixel data from image (RGBA 32bit)
|
||||
Color* pixels = LoadImageColors(imageCopy);
|
||||
UpdateTexture(texture, pixels);
|
||||
UnloadImageColors(pixels);
|
||||
|
||||
textureReload = false;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
DrawText("IMAGE PROCESSING:", 40, 30, 10, Color.DarkGray);
|
||||
|
||||
// Draw rectangles
|
||||
for (int i = 0; i < NumProcesses; i++)
|
||||
{
|
||||
DrawRectangleRec(toggleRecs[i], (i == (int)currentProcess) ? Color.SkyBlue : Color.LightGray);
|
||||
DrawRectangleLines(
|
||||
(int)toggleRecs[i].X,
|
||||
(int)toggleRecs[i].Y,
|
||||
(int)toggleRecs[i].Width,
|
||||
(int)toggleRecs[i].Height,
|
||||
(i == (int)currentProcess) ? Color.Blue : Color.Gray
|
||||
);
|
||||
|
||||
int labelX = (int)(toggleRecs[i].X + toggleRecs[i].Width / 2);
|
||||
DrawText(
|
||||
processText[i],
|
||||
(int)(labelX - MeasureText(processText[i], 10) / 2),
|
||||
(int)toggleRecs[i].Y + 11,
|
||||
10,
|
||||
(i == (int)currentProcess) ? Color.DarkBlue : Color.DarkGray
|
||||
);
|
||||
}
|
||||
|
||||
int x = screenWidth - texture.Width - 60;
|
||||
int y = screenHeight / 2 - texture.Height / 2;
|
||||
DrawTexture(texture, x, y, Color.White);
|
||||
DrawRectangleLines(x, y, texture.Width, texture.Height, Color.Black);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadTexture(texture);
|
||||
UnloadImage(imageOrigin);
|
||||
UnloadImage(imageCopy);
|
||||
|
||||
CloseWindow();
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
119
Examples/Textures/ImageRotate.cs
Normal file
119
Examples/Textures/ImageRotate.cs
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [textures] example - image rotate
|
||||
*
|
||||
* Example complexity rating: [★★☆☆] 2/4
|
||||
*
|
||||
* Example originally created with raylib 1.0, last time updated with raylib 1.0
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2014-2025 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
namespace Examples.Textures;
|
||||
|
||||
public partial class ImageRotate : IExample
|
||||
{
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
private const int NumTextures = 3;
|
||||
|
||||
public string Name => "Textures / Image Rotate";
|
||||
|
||||
public string Title => "raylib [textures] example - image rotate";
|
||||
|
||||
private Texture2D[] textures;
|
||||
private int currentTexture;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
|
||||
var image45 = LoadImage("resources/raylib_logo.png");
|
||||
var image90 = LoadImage("resources/raylib_logo.png");
|
||||
var imageNeg90 = LoadImage("resources/raylib_logo.png");
|
||||
|
||||
ImageRotate(ref image45, 45);
|
||||
ImageRotate(ref image90, 90);
|
||||
ImageRotate(ref imageNeg90, -90);
|
||||
|
||||
textures = new Texture2D[NumTextures];
|
||||
|
||||
textures[0] = LoadTextureFromImage(image45);
|
||||
textures[1] = LoadTextureFromImage(image90);
|
||||
textures[2] = LoadTextureFromImage(imageNeg90);
|
||||
|
||||
UnloadImage(image45);
|
||||
UnloadImage(image90);
|
||||
UnloadImage(imageNeg90);
|
||||
|
||||
currentTexture = 0;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsMouseButtonPressed(MouseButton.Left) || IsKeyPressed(KeyboardKey.Right))
|
||||
{
|
||||
currentTexture = (currentTexture + 1) % NumTextures; // Cycle between the textures
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
DrawTexture(
|
||||
textures[currentTexture],
|
||||
screenWidth / 2 - textures[currentTexture].Width / 2,
|
||||
screenHeight / 2 - textures[currentTexture].Height / 2,
|
||||
Color.White);
|
||||
|
||||
DrawText("Press LEFT MOUSE BUTTON to rotate the image clockwise", 250, 420, 10, Color.DarkGray);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
for (var i = 0; i < NumTextures; i++)
|
||||
{
|
||||
UnloadTexture(textures[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - image rotate");
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
var game = new ImageRotate();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,34 +1,40 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [texture] example - Image text drawing using TTF generated spritefont
|
||||
* raylib [textures] example - image text
|
||||
*
|
||||
* This example has been created using raylib 1.8 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
* Example complexity rating: [★★☆☆] 2/4
|
||||
*
|
||||
* Copyright (c) 2017 Ramon Santamaria (@raysan5)
|
||||
* Example originally created with raylib 1.8, last time updated with raylib 4.0
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2017-2025 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using System.Numerics;
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
namespace Examples.Textures;
|
||||
|
||||
public class ImageText
|
||||
public partial class ImageText : IExample
|
||||
{
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [texture] example - image text drawing");
|
||||
public string Name => "Textures / Image Text";
|
||||
|
||||
public string Title => "raylib [textures] example - image text";
|
||||
|
||||
private Font font;
|
||||
private Texture2D texture;
|
||||
private Vector2 position;
|
||||
private bool showFont;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
var parrots = LoadImage("resources/parrots.png"); // Load image in CPU memory (RAM)
|
||||
|
||||
// TTF Font loading with custom generation parameters
|
||||
Font font = LoadFontEx("resources/fonts/KAISG.ttf", 64, null, 95);
|
||||
|
||||
Image parrots = LoadImage("resources/parrots.png");
|
||||
font = LoadFontEx("resources/fonts/KAISG.ttf", 64, null, 0);
|
||||
|
||||
// Draw over image using custom font
|
||||
ImageDrawTextEx(
|
||||
|
|
@ -38,69 +44,89 @@ public class ImageText
|
|||
new Vector2(20, 20),
|
||||
font.BaseSize,
|
||||
0,
|
||||
Color.White
|
||||
Color.Red
|
||||
);
|
||||
|
||||
// Image converted to texture, uploaded to GPU memory (VRAM)
|
||||
Texture2D texture = LoadTextureFromImage(parrots);
|
||||
UnloadImage(parrots);
|
||||
texture = LoadTextureFromImage(parrots); // Image converted to texture, uploaded to GPU memory (VRAM)
|
||||
UnloadImage(parrots); // Once image has been converted to texture and uploaded to VRAM, it can be unloaded from RAM
|
||||
|
||||
Vector2 position = new(
|
||||
position = new(
|
||||
screenWidth / 2 - texture.Width / 2,
|
||||
screenHeight / 2 - texture.Height / 2 - 20
|
||||
);
|
||||
|
||||
bool showFont = false;
|
||||
showFont = false;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsKeyDown(KeyboardKey.Space))
|
||||
{
|
||||
showFont = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
showFont = false;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
if (!showFont)
|
||||
{
|
||||
// Draw texture with text already drawn inside
|
||||
DrawTextureV(texture, position, Color.White);
|
||||
|
||||
// Draw text directly using sprite font
|
||||
Vector2 textPosition = new(position.X + 20, position.Y + 20 + 280);
|
||||
DrawTextEx(font, "[Parrots font drawing]", textPosition, font.BaseSize, 0, Color.White);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawTexture(font.Texture, screenWidth / 2 - font.Texture.Width / 2, 50, Color.Black);
|
||||
}
|
||||
|
||||
DrawText("PRESS SPACE to SHOW FONT ATLAS USED", 290, 420, 10, Color.DarkGray);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
UnloadTexture(texture); // Texture unloading
|
||||
|
||||
UnloadFont(font); // Unload custom font
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - image text");
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
var game = new ImageText();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsKeyDown(KeyboardKey.Space))
|
||||
{
|
||||
showFont = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
showFont = false;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
if (!showFont)
|
||||
{
|
||||
// Draw texture with text already drawn inside
|
||||
DrawTextureV(texture, position, Color.White);
|
||||
|
||||
// Draw text directly using sprite font
|
||||
Vector2 textPosition = new(position.X + 20, position.Y + 20 + 280);
|
||||
DrawTextEx(font, "[Parrots font drawing]", textPosition, font.BaseSize, 0, Color.White);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawTexture(font.Texture, screenWidth / 2 - font.Texture.Width / 2, 50, Color.Black);
|
||||
}
|
||||
|
||||
DrawText("PRESS SPACE to SEE USED SPRITEFONT ", 290, 420, 10, Color.DarkGray);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadTexture(texture);
|
||||
UnloadFont(font);
|
||||
|
||||
CloseWindow();
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -1,64 +1,85 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [textures] example - Texture loading and drawing
|
||||
* raylib [textures] example - logo raylib
|
||||
*
|
||||
* This example has been created using raylib 1.0 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
* Example complexity rating: [★☆☆☆] 1/4
|
||||
*
|
||||
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
|
||||
* Example originally created with raylib 1.0, last time updated with raylib 1.0
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2014-2025 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
namespace Examples.Textures;
|
||||
|
||||
public class LogoRaylibTexture
|
||||
public partial class LogoRaylibTexture : IExample
|
||||
{
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
public string Name => "Textures / Logo Raylib Texture";
|
||||
|
||||
public string Title => "raylib [textures] example - logo raylib";
|
||||
|
||||
private Texture2D texture;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
|
||||
texture = LoadTexture("resources/raylib-cs_logo.png"); // Texture loading
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
DrawTexture(
|
||||
texture,
|
||||
screenWidth / 2 - texture.Width / 2,
|
||||
screenHeight / 2 - texture.Height / 2,
|
||||
Color.White
|
||||
);
|
||||
|
||||
DrawText("this IS a texture!", 360, 370, 10, Color.Gray);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
UnloadTexture(texture); // Texture unloading
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - logo raylib");
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - texture loading and drawing");
|
||||
|
||||
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
|
||||
Texture2D texture = LoadTexture("resources/raylib-cs_logo.png");
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//---------------------------------------------------------------------------------------
|
||||
|
||||
var game = new LogoRaylibTexture();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// TODO: Update your variables here
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
DrawTexture(
|
||||
texture,
|
||||
screenWidth / 2 - texture.Width / 2,
|
||||
screenHeight / 2 - texture.Height / 2,
|
||||
Color.White
|
||||
);
|
||||
|
||||
DrawText("this IS a texture!", 360, 370, 10, Color.Gray);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadTexture(texture);
|
||||
|
||||
CloseWindow();
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
157
Examples/Textures/MagnifyingGlass.cs
Normal file
157
Examples/Textures/MagnifyingGlass.cs
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib textures example - magnifying glass
|
||||
*
|
||||
* Example complexity rating: [★★★☆] 3/4
|
||||
*
|
||||
* Example originally created with raylib 5.6, last time updated with raylib 5.6
|
||||
*
|
||||
* Example contributed by Luke Vaughan (@badram) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2026 Luke Vaughan (@badram)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
namespace Examples.Textures;
|
||||
|
||||
public partial class MagnifyingGlass : IExample
|
||||
{
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
public string Name => "Textures / Magnifying Glass";
|
||||
|
||||
public string Title => "raylib [textures] example - magnifying glass";
|
||||
|
||||
private Texture2D bunny;
|
||||
private Texture2D parrots;
|
||||
private Texture2D mask;
|
||||
private RenderTexture2D magnifiedWorld;
|
||||
private Camera2D camera;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
bunny = LoadTexture("resources/raybunny.png");
|
||||
parrots = LoadTexture("resources/parrots.png");
|
||||
|
||||
// Use image draw to generate a mask texture instead of loading it from a file.
|
||||
var circle = GenImageColor(256, 256, Color.Blank);
|
||||
ImageDrawCircle(ref circle, 128, 128, 128, Color.White);
|
||||
mask = LoadTextureFromImage(circle); // Copy the mask image from RAM to VRAM
|
||||
UnloadImage(circle); // Unload the image from RAM
|
||||
|
||||
magnifiedWorld = LoadRenderTexture(256, 256);
|
||||
|
||||
camera = new Camera2D();
|
||||
// Set magnifying glass zoom
|
||||
camera.Zoom = 2;
|
||||
// Offset by half the size of the magnifying glass to counteract drawing the texture centered on the mouse position
|
||||
camera.Offset = new Vector2(128, 128);
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
var mPos = GetMousePosition();
|
||||
camera.Target = mPos;
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
// Draw the normal version of the world
|
||||
DrawTexture(parrots, 144, 33, Color.White);
|
||||
DrawText("Use the magnifying glass to find hidden bunnies!", 154, 6, 20, Color.Black);
|
||||
|
||||
// Render to a the magnifying glass
|
||||
BeginTextureMode(magnifiedWorld);
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
BeginMode2D(camera);
|
||||
// Draw the same things in the magnified world as were in the normal version
|
||||
DrawTexture(parrots, 144, 33, Color.White);
|
||||
DrawText("Use the magnifying glass to find hidden bunnies!", 154, 6, 20, Color.Black);
|
||||
|
||||
// Draw bunnies only in the magnified world.
|
||||
// BLEND_MULTIPLIED lets them take on the color of the image below them.
|
||||
BeginBlendMode(BlendMode.Multiplied);
|
||||
DrawTexture(bunny, 250, 350, Color.White);
|
||||
DrawTexture(bunny, 500, 100, Color.White);
|
||||
DrawTexture(bunny, 420, 300, Color.White);
|
||||
DrawTexture(bunny, 650, 10, Color.White);
|
||||
EndBlendMode();
|
||||
EndMode2D();
|
||||
|
||||
// Mask the magnifying glass view texture to a circle
|
||||
// To make the mask affect only alpha, a CUSTOM blend mode is used with SEPARATE color/alpha functions
|
||||
BeginBlendMode(BlendMode.CustomSeparate);
|
||||
// C: Color, A: Alpha, s: source (texture to draw), d: destination (texture drawn to)
|
||||
// glSrcRGB: RL_ZERO - Cs * 0 = 0 - discard source rgb because we don't want to draw our texture's colors at all
|
||||
// glDstRGB: RL_ONE - Cd * 1 = Cd - use destination colors unmodified
|
||||
// glSrcAlpha: RL_ONE - As * 1 = As - use source alpha unmodified
|
||||
// glDstAlpha: RL_ZERO - Ad * 0 = 0 - discard destination alpha
|
||||
// glEqRGB: RL_FUNC_ADD - Cs(0) + Cd = Cd - destination color is unmodified
|
||||
// glEqAlpha: RL_FUNC_ADD - As + Ad(0) = As - destination alpha is set to source alpha
|
||||
Rlgl.SetBlendFactorsSeparate(Rlgl.ZERO, Rlgl.ONE, Rlgl.ONE, Rlgl.ZERO, Rlgl.FUNC_ADD, Rlgl.FUNC_ADD);
|
||||
DrawTexture(mask, 0, 0, Color.White);
|
||||
EndBlendMode();
|
||||
EndTextureMode();
|
||||
|
||||
// Draw magnifiedWorld to screen, centered on cursor
|
||||
DrawTextureRec(magnifiedWorld.Texture, new Rectangle(0, 0, 256, -256), new Vector2(mPos.X - 128, mPos.Y - 128), Color.White);
|
||||
|
||||
// Draw the outer ring of the magnifying glass
|
||||
DrawRing(mPos, 126, 130, 0, 360, 64, Color.Black);
|
||||
|
||||
// Draw floating specular highlight on the glass
|
||||
var rx = mPos.X / 800;
|
||||
var ry = mPos.Y / 800;
|
||||
DrawCircle((int)(mPos.X - 64 * rx) - 32, (int)(mPos.Y - 64 * ry) - 32, 4, ColorAlpha(Color.White, 0.5f));
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
UnloadTexture(parrots);
|
||||
UnloadTexture(bunny);
|
||||
UnloadTexture(mask);
|
||||
UnloadRenderTexture(magnifiedWorld);
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - magnifying glass");
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
var game = new MagnifyingGlass();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,63 +1,82 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [textures] example - Mouse painting
|
||||
* raylib [textures] example - mouse painting
|
||||
*
|
||||
* This example has been created using raylib 2.5 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
* Example complexity rating: [★★★☆] 3/4
|
||||
*
|
||||
* Example originally created with raylib 3.0, last time updated with raylib 3.0
|
||||
*
|
||||
* Example contributed by Chris Dill (@MysteriousSpace) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Copyright (c) 2019 Chris Dill (@MysteriousSpace) and Ramon Santamaria (@raysan5)
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2019-2025 Chris Dill (@MysteriousSpace) and Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using System.Numerics;
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
namespace Examples.Textures;
|
||||
|
||||
public class MousePainting
|
||||
public partial class MousePainting : IExample
|
||||
{
|
||||
public static int Main()
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
public string Name => "Textures / Mouse Painting";
|
||||
|
||||
public string Title => "raylib [textures] example - mouse painting";
|
||||
|
||||
public int TargetFps => 120;
|
||||
|
||||
private Color[] colors;
|
||||
private Rectangle[] colorsRecs;
|
||||
|
||||
private int colorSelected;
|
||||
private int colorSelectedPrev;
|
||||
private int colorMouseHover;
|
||||
private float brushSize;
|
||||
private bool mouseWasPressed;
|
||||
|
||||
private Rectangle btnSaveRec;
|
||||
private bool btnSaveMouseHover;
|
||||
private bool showSaveMessage;
|
||||
private int saveMessageCounter;
|
||||
|
||||
private RenderTexture2D target;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - mouse painting");
|
||||
|
||||
// Colours to choose from
|
||||
Color[] colors = new Color[] {
|
||||
Color.RayWhite,
|
||||
Color.Yellow,
|
||||
Color.Gold,
|
||||
Color.Orange,
|
||||
Color.Pink,
|
||||
Color.Red,
|
||||
Color.Maroon,
|
||||
Color.Green,
|
||||
Color.Lime,
|
||||
Color.DarkGreen,
|
||||
Color.SkyBlue,
|
||||
Color.Blue,
|
||||
Color.DarkBlue,
|
||||
Color.Purple,
|
||||
Color.Violet,
|
||||
Color.DarkPurple,
|
||||
Color.Beige,
|
||||
Color.Brown,
|
||||
Color.DarkBrown,
|
||||
Color.LightGray,
|
||||
Color.Gray,
|
||||
Color.DarkGray,
|
||||
Color.Black
|
||||
};
|
||||
// Colors to choose from
|
||||
colors = new Color[] {
|
||||
Color.RayWhite,
|
||||
Color.Yellow,
|
||||
Color.Gold,
|
||||
Color.Orange,
|
||||
Color.Pink,
|
||||
Color.Red,
|
||||
Color.Maroon,
|
||||
Color.Green,
|
||||
Color.Lime,
|
||||
Color.DarkGreen,
|
||||
Color.SkyBlue,
|
||||
Color.Blue,
|
||||
Color.DarkBlue,
|
||||
Color.Purple,
|
||||
Color.Violet,
|
||||
Color.DarkPurple,
|
||||
Color.Beige,
|
||||
Color.Brown,
|
||||
Color.DarkBrown,
|
||||
Color.LightGray,
|
||||
Color.Gray,
|
||||
Color.DarkGray,
|
||||
Color.Black
|
||||
};
|
||||
|
||||
// Define colorsRecs data (for every rectangle)
|
||||
Rectangle[] colorsRecs = new Rectangle[colors.Length];
|
||||
colorsRecs = new Rectangle[colors.Length];
|
||||
|
||||
for (int i = 0; i < colorsRecs.Length; i++)
|
||||
for (var i = 0; i < colorsRecs.Length; i++)
|
||||
{
|
||||
colorsRecs[i].X = 10 + 30 * i + 2 * i;
|
||||
colorsRecs[i].Y = 10;
|
||||
|
|
@ -65,226 +84,255 @@ public class MousePainting
|
|||
colorsRecs[i].Height = 30;
|
||||
}
|
||||
|
||||
int colorSelected = 0;
|
||||
int colorSelectedPrev = colorSelected;
|
||||
int colorMouseHover = 0;
|
||||
int brushSize = 20;
|
||||
colorSelected = 0;
|
||||
colorSelectedPrev = colorSelected;
|
||||
colorMouseHover = 0;
|
||||
brushSize = 20.0f;
|
||||
mouseWasPressed = false;
|
||||
|
||||
Rectangle btnSaveRec = new(750, 10, 40, 30);
|
||||
bool btnSaveMouseHover = false;
|
||||
bool showSaveMessage = false;
|
||||
int saveMessageCounter = 0;
|
||||
btnSaveRec = new(750, 10, 40, 30);
|
||||
btnSaveMouseHover = false;
|
||||
showSaveMessage = false;
|
||||
saveMessageCounter = 0;
|
||||
|
||||
// Create a RenderTexture2D to use as a canvas
|
||||
RenderTexture2D target = LoadRenderTexture(screenWidth, screenHeight);
|
||||
target = LoadRenderTexture(screenWidth, screenHeight);
|
||||
|
||||
// Clear render texture before entering the game loop
|
||||
BeginTextureMode(target);
|
||||
ClearBackground(colors[0]);
|
||||
EndTextureMode();
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
var mousePos = GetMousePosition();
|
||||
|
||||
// Move between colors with keys
|
||||
if (IsKeyPressed(KeyboardKey.Right))
|
||||
{
|
||||
colorSelected++;
|
||||
}
|
||||
else if (IsKeyPressed(KeyboardKey.Left))
|
||||
{
|
||||
colorSelected--;
|
||||
}
|
||||
|
||||
if (colorSelected >= colors.Length)
|
||||
{
|
||||
colorSelected = colors.Length - 1;
|
||||
}
|
||||
else if (colorSelected < 0)
|
||||
{
|
||||
colorSelected = 0;
|
||||
}
|
||||
|
||||
// Choose color with mouse
|
||||
for (var i = 0; i < colors.Length; i++)
|
||||
{
|
||||
if (CheckCollisionPointRec(mousePos, colorsRecs[i]))
|
||||
{
|
||||
colorMouseHover = i;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
colorMouseHover = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if ((colorMouseHover >= 0) && IsMouseButtonPressed(MouseButton.Left))
|
||||
{
|
||||
colorSelected = colorMouseHover;
|
||||
colorSelectedPrev = colorSelected;
|
||||
}
|
||||
|
||||
// Change brush size
|
||||
brushSize += GetMouseWheelMove() * 5;
|
||||
if (brushSize < 2)
|
||||
{
|
||||
brushSize = 2;
|
||||
}
|
||||
|
||||
if (brushSize > 50)
|
||||
{
|
||||
brushSize = 50;
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KeyboardKey.C))
|
||||
{
|
||||
// Clear render texture to clear color
|
||||
BeginTextureMode(target);
|
||||
ClearBackground(colors[0]);
|
||||
EndTextureMode();
|
||||
}
|
||||
|
||||
if (IsMouseButtonDown(MouseButton.Left) || (GetGestureDetected() == Gesture.Drag))
|
||||
{
|
||||
// Paint circle into render texture
|
||||
// NOTE: To avoid discontinuous circles, we could store
|
||||
// previous-next mouse points and just draw a line using brush size
|
||||
BeginTextureMode(target);
|
||||
if (mousePos.Y > 50)
|
||||
{
|
||||
DrawCircle((int)mousePos.X, (int)mousePos.Y, brushSize, colors[colorSelected]);
|
||||
}
|
||||
|
||||
EndTextureMode();
|
||||
}
|
||||
|
||||
if (IsMouseButtonDown(MouseButton.Right))
|
||||
{
|
||||
if (!mouseWasPressed)
|
||||
{
|
||||
colorSelectedPrev = colorSelected;
|
||||
colorSelected = 0;
|
||||
}
|
||||
|
||||
mouseWasPressed = true;
|
||||
|
||||
// Erase circle from render texture
|
||||
BeginTextureMode(target);
|
||||
if (mousePos.Y > 50)
|
||||
{
|
||||
DrawCircle((int)mousePos.X, (int)mousePos.Y, brushSize, colors[0]);
|
||||
}
|
||||
|
||||
EndTextureMode();
|
||||
}
|
||||
else if (IsMouseButtonReleased(MouseButton.Right) && mouseWasPressed)
|
||||
{
|
||||
colorSelected = colorSelectedPrev;
|
||||
mouseWasPressed = false;
|
||||
}
|
||||
|
||||
// Check mouse hover save button
|
||||
if (CheckCollisionPointRec(mousePos, btnSaveRec))
|
||||
{
|
||||
btnSaveMouseHover = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
btnSaveMouseHover = false;
|
||||
}
|
||||
|
||||
// Image saving logic
|
||||
// NOTE: Saving painted texture to a default named image
|
||||
if ((btnSaveMouseHover && IsMouseButtonReleased(MouseButton.Left)) ||
|
||||
IsKeyPressed(KeyboardKey.S))
|
||||
{
|
||||
var image = LoadImageFromTexture(target.Texture);
|
||||
ImageFlipVertical(ref image);
|
||||
ExportImage(image, "my_amazing_texture_painting.png");
|
||||
UnloadImage(image);
|
||||
showSaveMessage = true;
|
||||
}
|
||||
|
||||
if (showSaveMessage)
|
||||
{
|
||||
// On saving, show a full screen message for 2 seconds
|
||||
saveMessageCounter++;
|
||||
if (saveMessageCounter > 240)
|
||||
{
|
||||
showSaveMessage = false;
|
||||
saveMessageCounter = 0;
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
// NOTE: Render texture must be y-flipped due to default OpenGL coordinates (left-bottom)
|
||||
Rectangle source = new(0, 0, target.Texture.Width, -target.Texture.Height);
|
||||
DrawTextureRec(target.Texture, source, new Vector2(0, 0), Color.White);
|
||||
|
||||
// Draw drawing circle for reference
|
||||
if (mousePos.Y > 50)
|
||||
{
|
||||
if (IsMouseButtonDown(MouseButton.Right))
|
||||
{
|
||||
DrawCircleLines((int)mousePos.X, (int)mousePos.Y, brushSize, Color.Gray);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawCircle(GetMouseX(), GetMouseY(), brushSize, colors[colorSelected]);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw top panel
|
||||
DrawRectangle(0, 0, GetScreenWidth(), 50, Color.RayWhite);
|
||||
DrawLine(0, 50, GetScreenWidth(), 50, Color.LightGray);
|
||||
|
||||
// Draw color selection rectangles
|
||||
for (var i = 0; i < colors.Length; i++)
|
||||
{
|
||||
DrawRectangleRec(colorsRecs[i], colors[i]);
|
||||
}
|
||||
|
||||
DrawRectangleLines(10, 10, 30, 30, Color.LightGray);
|
||||
|
||||
if (colorMouseHover >= 0)
|
||||
{
|
||||
DrawRectangleRec(colorsRecs[colorMouseHover], Fade(Color.White, 0.6f));
|
||||
}
|
||||
|
||||
Rectangle rec = new(
|
||||
colorsRecs[colorSelected].X - 2,
|
||||
colorsRecs[colorSelected].Y - 2,
|
||||
colorsRecs[colorSelected].Width + 4,
|
||||
colorsRecs[colorSelected].Height + 4
|
||||
);
|
||||
DrawRectangleLinesEx(rec, 2, Color.Black);
|
||||
|
||||
// Draw save image button
|
||||
DrawRectangleLinesEx(btnSaveRec, 2, btnSaveMouseHover ? Color.Red : Color.Black);
|
||||
DrawText("SAVE!", 755, 20, 10, btnSaveMouseHover ? Color.Red : Color.Black);
|
||||
|
||||
// Draw save image message
|
||||
if (showSaveMessage)
|
||||
{
|
||||
DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), Fade(Color.RayWhite, 0.8f));
|
||||
DrawRectangle(0, 150, GetScreenWidth(), 80, Color.Black);
|
||||
DrawText("IMAGE SAVED!", 150, 180, 20, Color.RayWhite);
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
UnloadRenderTexture(target); // Unload render texture
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - mouse painting");
|
||||
|
||||
SetTargetFPS(120); // Set our game to run at 120 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
var game = new MousePainting();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
Vector2 mousePos = GetMousePosition();
|
||||
|
||||
// Move between colors with keys
|
||||
if (IsKeyPressed(KeyboardKey.Right))
|
||||
{
|
||||
colorSelected++;
|
||||
}
|
||||
else if (IsKeyPressed(KeyboardKey.Left))
|
||||
{
|
||||
colorSelected--;
|
||||
}
|
||||
|
||||
if (colorSelected >= colors.Length)
|
||||
{
|
||||
colorSelected = colors.Length - 1;
|
||||
}
|
||||
else if (colorSelected < 0)
|
||||
{
|
||||
colorSelected = 0;
|
||||
}
|
||||
|
||||
// Choose color with mouse
|
||||
for (int i = 0; i < colors.Length; i++)
|
||||
{
|
||||
if (CheckCollisionPointRec(mousePos, colorsRecs[i]))
|
||||
{
|
||||
colorMouseHover = i;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
colorMouseHover = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if ((colorMouseHover >= 0) && IsMouseButtonPressed(MouseButton.Left))
|
||||
{
|
||||
colorSelected = colorMouseHover;
|
||||
colorSelectedPrev = colorSelected;
|
||||
}
|
||||
|
||||
// Change brush size
|
||||
brushSize += (int)(GetMouseWheelMove() * 5);
|
||||
if (brushSize < 2)
|
||||
{
|
||||
brushSize = 2;
|
||||
}
|
||||
|
||||
if (brushSize > 50)
|
||||
{
|
||||
brushSize = 50;
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KeyboardKey.C))
|
||||
{
|
||||
// Clear render texture to clear color
|
||||
BeginTextureMode(target);
|
||||
ClearBackground(colors[0]);
|
||||
EndTextureMode();
|
||||
}
|
||||
|
||||
if (IsMouseButtonDown(MouseButton.Left))
|
||||
{
|
||||
// Paint circle into render texture
|
||||
// NOTE: To avoid discontinuous circles, we could store
|
||||
// previous-next mouse points and just draw a line using brush size
|
||||
BeginTextureMode(target);
|
||||
if (mousePos.Y > 50)
|
||||
{
|
||||
DrawCircle((int)mousePos.X, (int)mousePos.Y, brushSize, colors[colorSelected]);
|
||||
}
|
||||
|
||||
EndTextureMode();
|
||||
}
|
||||
else if (IsMouseButtonDown(MouseButton.Right))
|
||||
{
|
||||
colorSelected = 0;
|
||||
|
||||
// Erase circle from render texture
|
||||
BeginTextureMode(target);
|
||||
if (mousePos.Y > 50)
|
||||
{
|
||||
DrawCircle((int)mousePos.X, (int)mousePos.Y, brushSize, colors[0]);
|
||||
}
|
||||
|
||||
EndTextureMode();
|
||||
}
|
||||
else
|
||||
{
|
||||
colorSelected = colorSelectedPrev;
|
||||
}
|
||||
|
||||
// Check mouse hover save button
|
||||
if (CheckCollisionPointRec(mousePos, btnSaveRec))
|
||||
{
|
||||
btnSaveMouseHover = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
btnSaveMouseHover = false;
|
||||
}
|
||||
|
||||
// Image saving logic
|
||||
// NOTE: Saving painted texture to a default named image
|
||||
if ((btnSaveMouseHover && IsMouseButtonReleased(MouseButton.Left)) ||
|
||||
IsKeyPressed(KeyboardKey.S))
|
||||
{
|
||||
Image image = LoadImageFromTexture(target.Texture);
|
||||
ImageFlipVertical(ref image);
|
||||
ExportImage(image, "my_amazing_texture_painting.png");
|
||||
UnloadImage(image);
|
||||
showSaveMessage = true;
|
||||
}
|
||||
|
||||
if (showSaveMessage)
|
||||
{
|
||||
// On saving, show a full screen message for 2 seconds
|
||||
saveMessageCounter++;
|
||||
if (saveMessageCounter > 240)
|
||||
{
|
||||
showSaveMessage = false;
|
||||
saveMessageCounter = 0;
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
// NOTE: Render texture must be y-flipped due to default OpenGL coordinates (left-bottom)
|
||||
Rectangle source = new(0, 0, target.Texture.Width, -target.Texture.Height);
|
||||
DrawTextureRec(target.Texture, source, new Vector2(0, 0), Color.White);
|
||||
|
||||
// Draw drawing circle for reference
|
||||
if (mousePos.Y > 50)
|
||||
{
|
||||
if (IsMouseButtonDown(MouseButton.Right))
|
||||
{
|
||||
DrawCircleLines((int)mousePos.X, (int)mousePos.Y, brushSize, colors[colorSelected]);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawCircle(GetMouseX(), GetMouseY(), brushSize, colors[colorSelected]);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw top panel
|
||||
DrawRectangle(0, 0, GetScreenWidth(), 50, Color.RayWhite);
|
||||
DrawLine(0, 50, GetScreenWidth(), 50, Color.LightGray);
|
||||
|
||||
// Draw color selection rectangles
|
||||
for (int i = 0; i < colors.Length; i++)
|
||||
{
|
||||
DrawRectangleRec(colorsRecs[i], colors[i]);
|
||||
}
|
||||
|
||||
DrawRectangleLines(10, 10, 30, 30, Color.LightGray);
|
||||
|
||||
if (colorMouseHover >= 0)
|
||||
{
|
||||
DrawRectangleRec(colorsRecs[colorMouseHover], ColorAlpha(Color.White, 0.6f));
|
||||
}
|
||||
|
||||
Rectangle rec = new(
|
||||
colorsRecs[colorSelected].X - 2,
|
||||
colorsRecs[colorSelected].Y - 2,
|
||||
colorsRecs[colorSelected].Width + 4,
|
||||
colorsRecs[colorSelected].Height + 4
|
||||
);
|
||||
DrawRectangleLinesEx(rec, 2, Color.Black);
|
||||
|
||||
// Draw save image button
|
||||
DrawRectangleLinesEx(btnSaveRec, 2, btnSaveMouseHover ? Color.Red : Color.Black);
|
||||
DrawText("SAVE!", 755, 20, 10, btnSaveMouseHover ? Color.Red : Color.Black);
|
||||
|
||||
// Draw save image message
|
||||
if (showSaveMessage)
|
||||
{
|
||||
DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), ColorAlpha(Color.RayWhite, 0.8f));
|
||||
DrawRectangle(0, 150, GetScreenWidth(), 80, Color.Black);
|
||||
DrawText("IMAGE SAVED: my_amazing_texture_painting.png", 150, 180, 20, Color.RayWhite);
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadRenderTexture(target);
|
||||
|
||||
CloseWindow();
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -1,49 +1,64 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [textures] example - N-patch drawing
|
||||
* raylib [textures] example - npatch drawing
|
||||
*
|
||||
* Example complexity rating: [★★★☆] 3/4
|
||||
*
|
||||
* NOTE: Images are loaded in CPU memory (RAM); textures are loaded in GPU memory (VRAM)
|
||||
*
|
||||
* This example has been created using raylib 2.0 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
* Example originally created with raylib 2.0, last time updated with raylib 2.5
|
||||
*
|
||||
* Example contributed by Jorge A. Gomes (@overdev) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Copyright (c) 2018 Jorge A. Gomes (@overdev) and Ramon Santamaria (@raysan5)
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2018-2025 Jorge A. Gomes (@overdev) and Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Numerics;
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
namespace Examples.Textures;
|
||||
|
||||
public class NpatchDrawing
|
||||
public partial class NpatchDrawing : IExample
|
||||
{
|
||||
public static int Main()
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
public string Name => "Textures / N-patch Drawing";
|
||||
|
||||
public string Title => "raylib [textures] example - npatch drawing";
|
||||
|
||||
private Texture2D nPatchTexture;
|
||||
|
||||
private Vector2 mousePosition;
|
||||
private Vector2 origin;
|
||||
|
||||
private Rectangle dstRec1;
|
||||
private Rectangle dstRec2;
|
||||
private Rectangle dstRecH;
|
||||
private Rectangle dstRecV;
|
||||
|
||||
private NPatchInfo ninePatchInfo1;
|
||||
private NPatchInfo ninePatchInfo2;
|
||||
private NPatchInfo h3PatchInfo;
|
||||
private NPatchInfo v3PatchInfo;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - N-patch drawing");
|
||||
|
||||
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
|
||||
Texture2D nPatchTexture = LoadTexture("resources/ninepatch_button.png");
|
||||
nPatchTexture = LoadTexture("resources/ninepatch_button.png");
|
||||
|
||||
Vector2 mousePosition = new(0.0f, 0.0f);
|
||||
Vector2 origin = new(0.0f, 0.0f);
|
||||
mousePosition = new(0.0f, 0.0f);
|
||||
origin = new(0.0f, 0.0f);
|
||||
|
||||
// Position and size of the n-patches
|
||||
Rectangle dstRec1 = new(480.0f, 160.0f, 32.0f, 32.0f);
|
||||
Rectangle dstRec2 = new(160.0f, 160.0f, 32.0f, 32.0f);
|
||||
Rectangle dstRecH = new(160.0f, 93.0f, 32.0f, 32.0f);
|
||||
Rectangle dstRecV = new(92.0f, 160.0f, 32.0f, 32.0f);
|
||||
dstRec1 = new(480.0f, 160.0f, 32.0f, 32.0f);
|
||||
dstRec2 = new(160.0f, 160.0f, 32.0f, 32.0f);
|
||||
dstRecH = new(160.0f, 93.0f, 32.0f, 32.0f);
|
||||
dstRecV = new(92.0f, 160.0f, 32.0f, 32.0f);
|
||||
|
||||
// A 9-patch (NPT_9PATCH) changes its sizes in both axis
|
||||
NPatchInfo ninePatchInfo1 = new NPatchInfo
|
||||
// A 9-patch (NPATCH_NINE_PATCH) changes its sizes in both axis
|
||||
ninePatchInfo1 = new NPatchInfo
|
||||
{
|
||||
Source = new Rectangle(0.0f, 0.0f, 64.0f, 64.0f),
|
||||
Left = 12,
|
||||
|
|
@ -52,7 +67,7 @@ public class NpatchDrawing
|
|||
Bottom = 12,
|
||||
Layout = NPatchLayout.NinePatch
|
||||
};
|
||||
NPatchInfo ninePatchInfo2 = new NPatchInfo
|
||||
ninePatchInfo2 = new NPatchInfo
|
||||
{
|
||||
Source = new Rectangle(0.0f, 128.0f, 64.0f, 64.0f),
|
||||
Left = 16,
|
||||
|
|
@ -62,8 +77,8 @@ public class NpatchDrawing
|
|||
Layout = NPatchLayout.NinePatch
|
||||
};
|
||||
|
||||
// A horizontal 3-patch (NPT_3PATCH_HORIZONTAL) changes its sizes along the x axis only
|
||||
NPatchInfo h3PatchInfo = new NPatchInfo
|
||||
// A horizontal 3-patch (NPATCH_THREE_PATCH_HORIZONTAL) changes its sizes along the x axis only
|
||||
h3PatchInfo = new NPatchInfo
|
||||
{
|
||||
Source = new Rectangle(0.0f, 64.0f, 64.0f, 64.0f),
|
||||
Left = 8,
|
||||
|
|
@ -73,8 +88,8 @@ public class NpatchDrawing
|
|||
Layout = NPatchLayout.ThreePatchHorizontal
|
||||
};
|
||||
|
||||
// A vertical 3-patch (NPT_3PATCH_VERTICAL) changes its sizes along the y axis only
|
||||
NPatchInfo v3PatchInfo = new NPatchInfo
|
||||
// A vertical 3-patch (NPATCH_THREE_PATCH_VERTICAL) changes its sizes along the y axis only
|
||||
v3PatchInfo = new NPatchInfo
|
||||
{
|
||||
Source = new Rectangle(0.0f, 192.0f, 64.0f, 64.0f),
|
||||
Left = 6,
|
||||
|
|
@ -83,61 +98,81 @@ public class NpatchDrawing
|
|||
Bottom = 6,
|
||||
Layout = NPatchLayout.ThreePatchVertical
|
||||
};
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
mousePosition = GetMousePosition();
|
||||
|
||||
// Resize the n-patches based on mouse position
|
||||
dstRec1.Width = mousePosition.X - dstRec1.X;
|
||||
dstRec1.Height = mousePosition.Y - dstRec1.Y;
|
||||
dstRec2.Width = mousePosition.X - dstRec2.X;
|
||||
dstRec2.Height = mousePosition.Y - dstRec2.Y;
|
||||
dstRecH.Width = mousePosition.X - dstRecH.X;
|
||||
dstRecV.Height = mousePosition.Y - dstRecV.Y;
|
||||
|
||||
// Set a minimum width and/or height
|
||||
dstRec1.Width = Math.Clamp(dstRec1.Width, 1.0f, 300.0f);
|
||||
dstRec1.Height = MathF.Max(dstRec1.Height, 1.0f);
|
||||
dstRec2.Width = Math.Clamp(dstRec2.Width, 1.0f, 300.0f);
|
||||
dstRec2.Height = MathF.Max(dstRec2.Height, 1.0f);
|
||||
dstRecH.Width = MathF.Max(dstRecH.Width, 1.0f);
|
||||
dstRecV.Height = MathF.Max(dstRecV.Height, 1.0f);
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
// Draw the n-patches
|
||||
DrawTextureNPatch(nPatchTexture, ninePatchInfo2, dstRec2, origin, 0.0f, Color.White);
|
||||
DrawTextureNPatch(nPatchTexture, ninePatchInfo1, dstRec1, origin, 0.0f, Color.White);
|
||||
DrawTextureNPatch(nPatchTexture, h3PatchInfo, dstRecH, origin, 0.0f, Color.White);
|
||||
DrawTextureNPatch(nPatchTexture, v3PatchInfo, dstRecV, origin, 0.0f, Color.White);
|
||||
|
||||
// Draw the source texture
|
||||
DrawRectangleLines(5, 88, 74, 266, Color.Blue);
|
||||
DrawTexture(nPatchTexture, 10, 93, Color.White);
|
||||
DrawText("TEXTURE", 15, 360, 10, Color.DarkGray);
|
||||
|
||||
DrawText("Move the mouse to stretch or shrink the n-patches", 10, 20, 20, Color.DarkGray);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
UnloadTexture(nPatchTexture); // Texture unloading
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - npatch drawing");
|
||||
|
||||
SetTargetFPS(60);
|
||||
//---------------------------------------------------------------------------------------
|
||||
|
||||
var game = new NpatchDrawing();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
mousePosition = GetMousePosition();
|
||||
|
||||
// Resize the n-patches based on mouse position
|
||||
dstRec1.Width = mousePosition.X - dstRec1.X;
|
||||
dstRec1.Height = mousePosition.Y - dstRec1.Y;
|
||||
dstRec2.Width = mousePosition.X - dstRec2.X;
|
||||
dstRec2.Height = mousePosition.Y - dstRec2.Y;
|
||||
dstRecH.Width = mousePosition.X - dstRecH.X;
|
||||
dstRecV.Height = mousePosition.Y - dstRecV.Y;
|
||||
|
||||
// Set a minimum width and/or height
|
||||
dstRec1.Width = Math.Clamp(dstRec1.Width, 1.0f, 300.0f);
|
||||
dstRec1.Height = MathF.Max(dstRec1.Height, 1.0f);
|
||||
dstRec2.Width = Math.Clamp(dstRec2.Width, 1.0f, 300.0f);
|
||||
dstRec2.Height = MathF.Max(dstRec2.Height, 1.0f);
|
||||
dstRecH.Width = MathF.Max(dstRecH.Width, 1.0f);
|
||||
dstRecV.Height = MathF.Max(dstRecV.Height, 1.0f);
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
// Draw the n-patches
|
||||
DrawTextureNPatch(nPatchTexture, ninePatchInfo2, dstRec2, origin, 0.0f, Color.White);
|
||||
DrawTextureNPatch(nPatchTexture, ninePatchInfo1, dstRec1, origin, 0.0f, Color.White);
|
||||
DrawTextureNPatch(nPatchTexture, h3PatchInfo, dstRecH, origin, 0.0f, Color.White);
|
||||
DrawTextureNPatch(nPatchTexture, v3PatchInfo, dstRecV, origin, 0.0f, Color.White);
|
||||
|
||||
// Draw the source texture
|
||||
DrawRectangleLines(5, 88, 74, 266, Color.Blue);
|
||||
DrawTexture(nPatchTexture, 10, 93, Color.White);
|
||||
DrawText("TEXTURE", 15, 360, 10, Color.DarkGray);
|
||||
|
||||
DrawText("Move the mouse to stretch or shrink the n-patches", 10, 20, 20, Color.DarkGray);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadTexture(nPatchTexture);
|
||||
|
||||
CloseWindow();
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -1,25 +1,33 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib example - particles blending
|
||||
* raylib [textures] example - particles blending
|
||||
*
|
||||
* This example has been created using raylib 1.7 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
* Example complexity rating: [★☆☆☆] 1/4
|
||||
*
|
||||
* Copyright (c) 2017 Ramon Santamaria (@raysan5)
|
||||
* Example originally created with raylib 1.7, last time updated with raylib 3.5
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2017-2025 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using System.Numerics;
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
namespace Examples.Textures;
|
||||
|
||||
public class ParticlesBlending
|
||||
public partial class ParticlesBlending : IExample
|
||||
{
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
public const int MaxParticles = 200;
|
||||
|
||||
public string Name => "Textures / Particles Blending";
|
||||
|
||||
public string Title => "raylib [textures] example - particles blending";
|
||||
|
||||
// Particle structure with basic data
|
||||
struct Particle
|
||||
private struct Particle
|
||||
{
|
||||
public Vector2 Position;
|
||||
public Color Color;
|
||||
|
|
@ -30,20 +38,18 @@ public class ParticlesBlending
|
|||
public bool Active;
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
private Particle[] mouseTail;
|
||||
private float gravity;
|
||||
private Texture2D smoke;
|
||||
private BlendMode blending;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - particles blending");
|
||||
|
||||
// Particles pool, reuse them!
|
||||
Particle[] mouseTail = new Particle[MaxParticles];
|
||||
mouseTail = new Particle[MaxParticles];
|
||||
|
||||
// Initialize particles
|
||||
for (int i = 0; i < mouseTail.Length; i++)
|
||||
for (var i = 0; i < mouseTail.Length; i++)
|
||||
{
|
||||
mouseTail[i].Position = new Vector2(0, 0);
|
||||
mouseTail[i].Color = new Color(
|
||||
|
|
@ -58,113 +64,133 @@ public class ParticlesBlending
|
|||
mouseTail[i].Active = false;
|
||||
}
|
||||
|
||||
float gravity = 3.0f;
|
||||
Texture2D smoke = LoadTexture("resources/spark_flame.png");
|
||||
BlendMode blending = BlendMode.Alpha;
|
||||
gravity = 3.0f;
|
||||
smoke = LoadTexture("resources/spark_flame.png");
|
||||
blending = BlendMode.Alpha;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Activate one particle every frame and Update active particles
|
||||
// NOTE: Particles initial position should be mouse position when activated
|
||||
// NOTE: Particles fall down with gravity and rotation... and disappear after 2 seconds (alpha = 0)
|
||||
// NOTE: When a particle disappears, active = false and it can be reused
|
||||
for (var i = 0; i < mouseTail.Length; i++)
|
||||
{
|
||||
if (!mouseTail[i].Active)
|
||||
{
|
||||
mouseTail[i].Active = true;
|
||||
mouseTail[i].Alpha = 1.0f;
|
||||
mouseTail[i].Position = GetMousePosition();
|
||||
i = mouseTail.Length;
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < mouseTail.Length; i++)
|
||||
{
|
||||
if (mouseTail[i].Active)
|
||||
{
|
||||
mouseTail[i].Position.Y += gravity / 2;
|
||||
mouseTail[i].Alpha -= 0.005f;
|
||||
|
||||
if (mouseTail[i].Alpha <= 0.0f)
|
||||
{
|
||||
mouseTail[i].Active = false;
|
||||
}
|
||||
|
||||
mouseTail[i].Rotation += 2.0f;
|
||||
}
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KeyboardKey.Space))
|
||||
{
|
||||
if (blending == BlendMode.Alpha)
|
||||
{
|
||||
blending = BlendMode.Additive;
|
||||
}
|
||||
else
|
||||
{
|
||||
blending = BlendMode.Alpha;
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.DarkGray);
|
||||
|
||||
BeginBlendMode(blending);
|
||||
|
||||
// Draw active particles
|
||||
for (var i = 0; i < mouseTail.Length; i++)
|
||||
{
|
||||
if (mouseTail[i].Active)
|
||||
{
|
||||
Rectangle source = new(0, 0, smoke.Width, smoke.Height);
|
||||
Rectangle dest = new(
|
||||
mouseTail[i].Position.X,
|
||||
mouseTail[i].Position.Y,
|
||||
smoke.Width * mouseTail[i].Size,
|
||||
smoke.Height * mouseTail[i].Size
|
||||
);
|
||||
Vector2 position = new(
|
||||
smoke.Width * mouseTail[i].Size / 2,
|
||||
smoke.Height * mouseTail[i].Size / 2
|
||||
);
|
||||
var color = Fade(mouseTail[i].Color, mouseTail[i].Alpha);
|
||||
DrawTexturePro(smoke, source, dest, position, mouseTail[i].Rotation, color);
|
||||
}
|
||||
}
|
||||
|
||||
EndBlendMode();
|
||||
|
||||
DrawText("PRESS SPACE to CHANGE BLENDING MODE", 180, 20, 20, Color.Black);
|
||||
|
||||
if (blending == BlendMode.Alpha)
|
||||
{
|
||||
DrawText("ALPHA BLENDING", 290, screenHeight - 40, 20, Color.Black);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawText("ADDITIVE BLENDING", 280, screenHeight - 40, 20, Color.RayWhite);
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
UnloadTexture(smoke);
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - particles blending");
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
var game = new ParticlesBlending();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Activate one particle every frame and Update active particles
|
||||
// NOTE: Particles initial position should be mouse position when activated
|
||||
// NOTE: Particles fall down with gravity and rotation... and disappear after 2 seconds (alpha = 0)
|
||||
// NOTE: When a particle disappears, active = false and it can be reused.
|
||||
for (int i = 0; i < mouseTail.Length; i++)
|
||||
{
|
||||
if (!mouseTail[i].Active)
|
||||
{
|
||||
mouseTail[i].Active = true;
|
||||
mouseTail[i].Alpha = 1.0f;
|
||||
mouseTail[i].Position = GetMousePosition();
|
||||
i = mouseTail.Length;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < mouseTail.Length; i++)
|
||||
{
|
||||
if (mouseTail[i].Active)
|
||||
{
|
||||
mouseTail[i].Position.Y += gravity / 2;
|
||||
mouseTail[i].Alpha -= 0.005f;
|
||||
|
||||
if (mouseTail[i].Alpha <= 0.0f)
|
||||
{
|
||||
mouseTail[i].Active = false;
|
||||
}
|
||||
|
||||
mouseTail[i].Rotation += 2.0f;
|
||||
}
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KeyboardKey.Space))
|
||||
{
|
||||
if (blending == BlendMode.Alpha)
|
||||
{
|
||||
blending = BlendMode.Additive;
|
||||
}
|
||||
else
|
||||
{
|
||||
blending = BlendMode.Alpha;
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.DarkGray);
|
||||
|
||||
BeginBlendMode(blending);
|
||||
|
||||
// Draw active particles
|
||||
for (int i = 0; i < mouseTail.Length; i++)
|
||||
{
|
||||
if (mouseTail[i].Active)
|
||||
{
|
||||
Rectangle source = new(0, 0, smoke.Width, smoke.Height);
|
||||
Rectangle dest = new(
|
||||
mouseTail[i].Position.X,
|
||||
mouseTail[i].Position.Y,
|
||||
smoke.Width * mouseTail[i].Size,
|
||||
smoke.Height * mouseTail[i].Size
|
||||
);
|
||||
Vector2 position = new(
|
||||
smoke.Width * mouseTail[i].Size / 2,
|
||||
smoke.Height * mouseTail[i].Size / 2
|
||||
);
|
||||
Color color = ColorAlpha(mouseTail[i].Color, mouseTail[i].Alpha);
|
||||
DrawTexturePro(smoke, source, dest, position, mouseTail[i].Rotation, color);
|
||||
}
|
||||
}
|
||||
|
||||
EndBlendMode();
|
||||
|
||||
DrawText("PRESS SPACE to CHANGE BLENDING MODE", 180, 20, 20, Color.Black);
|
||||
|
||||
if (blending == BlendMode.Alpha)
|
||||
{
|
||||
DrawText("ALPHA BLENDING", 290, screenHeight - 40, 20, Color.Black);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawText("ADDITIVE BLENDING", 280, screenHeight - 40, 20, Color.RayWhite);
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadTexture(smoke);
|
||||
|
||||
CloseWindow();
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -1,51 +1,59 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - Draw Textured Polygon
|
||||
* raylib [textures] example - polygon drawing
|
||||
*
|
||||
* This example has been created using raylib 99.98 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
* Example complexity rating: [★☆☆☆] 1/4
|
||||
*
|
||||
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
|
||||
* Copyright (c) 2021 Chris Camacho (codifies - bedroomcoders.co.uk)
|
||||
* Example originally created with raylib 3.7, last time updated with raylib 3.7
|
||||
*
|
||||
* Example contributed by Chris Camacho (@chriscamacho) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2021-2025 Chris Camacho (@chriscamacho) and Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using System.Numerics;
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
namespace Examples.Textures;
|
||||
|
||||
public class Polygon
|
||||
public partial class Polygon : IExample
|
||||
{
|
||||
public static int Main()
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
public string Name => "Textures / Textured Polygon";
|
||||
|
||||
public string Title => "raylib [textures] example - polygon drawing";
|
||||
|
||||
private Vector2[] texcoords;
|
||||
private Vector2[] points;
|
||||
private Vector2[] positions;
|
||||
private Texture2D texture;
|
||||
private float angle;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
texcoords = new[] {
|
||||
new Vector2(0.75f, 0),
|
||||
new Vector2(0.25f, 0),
|
||||
new Vector2(0, 0.5f),
|
||||
new Vector2(0, 0.75f),
|
||||
new Vector2(0.25f, 1),
|
||||
new Vector2(0.375f, 0.875f),
|
||||
new Vector2(0.625f, 0.875f),
|
||||
new Vector2(0.75f, 1),
|
||||
new Vector2(1, 0.75f),
|
||||
new Vector2(1, 0.5f),
|
||||
// Close the poly
|
||||
new Vector2(0.75f, 0)
|
||||
};
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - Textured Polygon");
|
||||
|
||||
Vector2[] texcoords = new[] {
|
||||
new Vector2(0.75f, 0),
|
||||
new Vector2(0.25f, 0),
|
||||
new Vector2(0, 0.5f),
|
||||
new Vector2(0, 0.75f),
|
||||
new Vector2(0.25f, 1),
|
||||
new Vector2(0.375f, 0.875f),
|
||||
new Vector2(0.625f, 0.875f),
|
||||
new Vector2(0.75f, 1),
|
||||
new Vector2(1, 0.75f),
|
||||
new Vector2(1, 0.5f),
|
||||
// Close the poly
|
||||
new Vector2(0.75f, 0)
|
||||
};
|
||||
|
||||
Vector2[] points = new Vector2[11];
|
||||
points = new Vector2[11];
|
||||
|
||||
// Define the base poly vertices from the UV's
|
||||
// NOTE: They can be specified in any other way
|
||||
for (int i = 0; i < points.Length; i++)
|
||||
for (var i = 0; i < points.Length; i++)
|
||||
{
|
||||
points[i].X = (texcoords[i].X - 0.5f) * 256.0f;
|
||||
points[i].Y = (texcoords[i].Y - 0.5f) * 256.0f;
|
||||
|
|
@ -53,58 +61,49 @@ public class Polygon
|
|||
|
||||
// Define the vertices drawing position
|
||||
// NOTE: Initially same as points but updated every frame
|
||||
Vector2[] positions = new Vector2[points.Length];
|
||||
for (int i = 0; i < positions.Length; i++)
|
||||
positions = new Vector2[points.Length];
|
||||
for (var i = 0; i < positions.Length; i++)
|
||||
{
|
||||
positions[i] = points[i];
|
||||
}
|
||||
|
||||
Texture2D texture = LoadTexture("resources/cat.png");
|
||||
float angle = 0;
|
||||
texture = LoadTexture("resources/cat.png");
|
||||
angle = 0;
|
||||
}
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
angle += 1;
|
||||
for (var i = 0; i < positions.Length; i++)
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// Update your variables here
|
||||
//----------------------------------------------------------------------------------
|
||||
angle += 1;
|
||||
for (int i = 0; i < positions.Length; i++)
|
||||
{
|
||||
positions[i] = Raymath.Vector2Rotate(points[i], angle * Raylib.DEG2RAD);
|
||||
}
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
DrawText("Textured Polygon", 20, 20, 20, Color.DarkGray);
|
||||
Vector2 center = new(screenWidth / 2, screenHeight / 2);
|
||||
DrawTexturePoly(texture, center, positions, texcoords, positions.Length, Color.White);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
positions[i] = Raymath.Vector2Rotate(points[i], angle * Raylib.DEG2RAD);
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
DrawText("textured polygon", 20, 20, 20, Color.DarkGray);
|
||||
Vector2 center = new(screenWidth / 2, screenHeight / 2);
|
||||
DrawTexturePoly(texture, center, positions, texcoords, positions.Length, Color.White);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
UnloadTexture(texture);
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow();
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Draw textured polygon, defined by vertex and texture coordinates
|
||||
// NOTE: Polygon center must have straight line path to all points
|
||||
// without crossing perimeter, points must be in anticlockwise order
|
||||
static void DrawTexturePoly(
|
||||
private static void DrawTexturePoly(
|
||||
Texture2D texture,
|
||||
Vector2 center,
|
||||
Vector2[] points,
|
||||
|
|
@ -114,13 +113,11 @@ public class Polygon
|
|||
)
|
||||
{
|
||||
Rlgl.SetTexture(texture.Id);
|
||||
|
||||
// Texturing is only supported on RL_QUADS
|
||||
Rlgl.Begin(DrawMode.Quads);
|
||||
Rlgl.Begin(DrawMode.Triangles);
|
||||
|
||||
Rlgl.Color4ub(tint.R, tint.G, tint.B, tint.A);
|
||||
|
||||
for (int i = 0; i < pointCount - 1; i++)
|
||||
for (var i = 0; i < pointCount - 1; i++)
|
||||
{
|
||||
Rlgl.TexCoord2f(0.5f, 0.5f);
|
||||
Rlgl.Vertex2f(center.X, center.Y);
|
||||
|
|
@ -130,12 +127,37 @@ public class Polygon
|
|||
|
||||
Rlgl.TexCoord2f(texcoords[i + 1].X, texcoords[i + 1].Y);
|
||||
Rlgl.Vertex2f(points[i + 1].X + center.X, points[i + 1].Y + center.Y);
|
||||
|
||||
Rlgl.TexCoord2f(texcoords[i + 1].X, texcoords[i + 1].Y);
|
||||
Rlgl.Vertex2f(points[i + 1].X + center.X, points[i + 1].Y + center.Y);
|
||||
}
|
||||
Rlgl.End();
|
||||
|
||||
Rlgl.SetTexture(0);
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - polygon drawing");
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
var game = new Polygon();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
{
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow();
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,112 +1,141 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [textures] example - Load textures from raw data
|
||||
* raylib [textures] example - raw data
|
||||
*
|
||||
* Example complexity rating: [★★★☆] 3/4
|
||||
*
|
||||
* NOTE: Images are loaded in CPU memory (RAM); textures are loaded in GPU memory (VRAM)
|
||||
*
|
||||
* This example has been created using raylib 1.3 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
* Example originally created with raylib 1.3, last time updated with raylib 3.5
|
||||
*
|
||||
* Copyright (c) 2015 Ramon Santamaria (@raysan5)
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2015-2025 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
namespace Examples.Textures;
|
||||
|
||||
public class RawData
|
||||
public partial class RawData : IExample
|
||||
{
|
||||
public unsafe static int Main()
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
public string Name => "Textures / Raw Data";
|
||||
|
||||
public string Title => "raylib [textures] example - raw data";
|
||||
|
||||
private Texture2D fudesumi;
|
||||
private Texture2D checkedTex;
|
||||
|
||||
public unsafe void Init()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - texture from raw data");
|
||||
|
||||
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
|
||||
|
||||
// Load RAW image data (512x512, 32bit RGBA, no file header)
|
||||
Image fudesumiRaw = LoadImageRaw(
|
||||
var fudesumiRaw = LoadImageRaw(
|
||||
"resources/fudesumi.raw",
|
||||
384,
|
||||
512,
|
||||
PixelFormat.UncompressedR8G8B8A8,
|
||||
0
|
||||
);
|
||||
Texture2D fudesumi = LoadTextureFromImage(fudesumiRaw);
|
||||
UnloadImage(fudesumiRaw);
|
||||
fudesumi = LoadTextureFromImage(fudesumiRaw); // Upload CPU (RAM) image to GPU (VRAM)
|
||||
UnloadImage(fudesumiRaw); // Unload CPU (RAM) image data
|
||||
|
||||
// Generate a checked texture by code
|
||||
int width = 960;
|
||||
int height = 480;
|
||||
var imWidth = 960;
|
||||
var imHeight = 480;
|
||||
|
||||
// Store pixel data
|
||||
Color* pixels = (Color*)Raylib.MemAlloc((uint)(width * height * sizeof(Color)));
|
||||
for (int y = 0; y < height; y++)
|
||||
// Dynamic memory allocation to store pixels data (Color type)
|
||||
// WARNING: Using raylib provided MemAlloc() that uses default raylib
|
||||
// internal memory allocator, so this data can be freed using UnloadImage()
|
||||
// that also uses raylib internal memory de-allocator
|
||||
var pixels = (Color*)Raylib.MemAlloc((uint)(imWidth * imHeight * sizeof(Color)));
|
||||
|
||||
for (var y = 0; y < imHeight; y++)
|
||||
{
|
||||
for (int x = 0; x < width; x++)
|
||||
for (var x = 0; x < imWidth; x++)
|
||||
{
|
||||
if (((x / 32 + y / 32) / 1) % 2 == 0)
|
||||
{
|
||||
pixels[y * width + x] = Color.Orange;
|
||||
pixels[y * imWidth + x] = Color.Orange;
|
||||
}
|
||||
else
|
||||
{
|
||||
pixels[y * width + x] = Color.Gold;
|
||||
pixels[y * imWidth + x] = Color.Gold;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Load pixels data into an image structure and create texture
|
||||
Image checkedIm = new Image
|
||||
// NOTE: We can assign pixels directly to data because Color is R8G8B8A8
|
||||
// data structure defining that pixelformat, format must be set properly
|
||||
var checkedIm = new Image
|
||||
{
|
||||
Data = pixels,
|
||||
Width = width,
|
||||
Height = height,
|
||||
Width = imWidth,
|
||||
Height = imHeight,
|
||||
Format = PixelFormat.UncompressedR8G8B8A8,
|
||||
Mipmaps = 1,
|
||||
};
|
||||
Texture2D checkedTex = LoadTextureFromImage(checkedIm);
|
||||
Raylib.MemFree(pixels);
|
||||
|
||||
checkedTex = LoadTextureFromImage(checkedIm);
|
||||
Raylib.MemFree(pixels); // Unload CPU (RAM) image data (pixels)
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
var x = screenWidth / 2 - checkedTex.Width / 2;
|
||||
var y = screenHeight / 2 - checkedTex.Height / 2;
|
||||
DrawTexture(checkedTex, x, y, Fade(Color.White, 0.5f));
|
||||
DrawTexture(fudesumi, 430, -30, Color.White);
|
||||
|
||||
DrawText("CHECKED TEXTURE ", 84, 85, 30, Color.Brown);
|
||||
DrawText("GENERATED by CODE", 72, 148, 30, Color.Brown);
|
||||
DrawText("and RAW IMAGE LOADING", 46, 210, 30, Color.Brown);
|
||||
|
||||
DrawText("(c) Fudesumi sprite by Eiden Marsal", 310, screenHeight - 20, 10, Color.Brown);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
UnloadTexture(fudesumi); // Texture unloading
|
||||
UnloadTexture(checkedTex); // Texture unloading
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - raw data");
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//---------------------------------------------------------------------------------------
|
||||
|
||||
var game = new RawData();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// TODO: Update your variables here
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
int x = screenWidth / 2 - checkedTex.Width / 2;
|
||||
int y = screenHeight / 2 - checkedTex.Height / 2;
|
||||
DrawTexture(checkedTex, x, y, ColorAlpha(Color.White, 0.5f));
|
||||
DrawTexture(fudesumi, 430, -30, Color.White);
|
||||
|
||||
DrawText("CHECKED TEXTURE ", 84, 85, 30, Color.Brown);
|
||||
DrawText("GENERATED by CODE", 72, 148, 30, Color.Brown);
|
||||
DrawText("and RAW IMAGE LOADING", 46, 210, 30, Color.Brown);
|
||||
|
||||
DrawText("(c) Fudesumi sprite by Eiden Marsal", 310, screenHeight - 20, 10, Color.Brown);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadTexture(fudesumi);
|
||||
UnloadTexture(checkedTex);
|
||||
|
||||
CloseWindow();
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
178
Examples/Textures/ScreenBuffer.cs
Normal file
178
Examples/Textures/ScreenBuffer.cs
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [textures] example - screen buffer
|
||||
*
|
||||
* Example complexity rating: [★★☆☆] 2/4
|
||||
*
|
||||
* Example originally created with raylib 5.5, last time updated with raylib 5.5
|
||||
*
|
||||
* Example contributed by Agnis Aldiņš (@nezvers) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2025 Agnis Aldiņš (@nezvers)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
namespace Examples.Textures;
|
||||
|
||||
public partial class ScreenBuffer : IExample
|
||||
{
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
private const int MaxColors = 256;
|
||||
private const int ScaleFactor = 2;
|
||||
|
||||
private const int imageWidth = screenWidth / ScaleFactor;
|
||||
private const int imageHeight = screenHeight / ScaleFactor;
|
||||
private const int flameWidth = screenWidth / ScaleFactor;
|
||||
|
||||
public string Name => "Textures / Screen Buffer";
|
||||
|
||||
public string Title => "raylib [textures] example - screen buffer";
|
||||
|
||||
private Color[] palette;
|
||||
private byte[] indexBuffer;
|
||||
private byte[] flameRootBuffer;
|
||||
private Image screenImage;
|
||||
private Texture2D screenTexture;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
palette = new Color[MaxColors];
|
||||
indexBuffer = new byte[imageWidth * imageWidth];
|
||||
flameRootBuffer = new byte[flameWidth];
|
||||
|
||||
screenImage = GenImageColor(imageWidth, imageHeight, Color.Black);
|
||||
screenTexture = LoadTextureFromImage(screenImage);
|
||||
|
||||
// Generate flame color palette
|
||||
for (var i = 0; i < MaxColors; i++)
|
||||
{
|
||||
var t = (float)i / (float)(MaxColors - 1);
|
||||
var hue = t * t;
|
||||
var saturation = t;
|
||||
var value = t;
|
||||
|
||||
palette[i] = ColorFromHSV(250.0f + 150.0f * hue, saturation, value);
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// Grow flameRoot
|
||||
for (var x = 2; x < flameWidth; x++)
|
||||
{
|
||||
var flame = (int)flameRootBuffer[x];
|
||||
flame += GetRandomValue(0, 2);
|
||||
flameRootBuffer[x] = (flame > 255) ? (byte)255 : (byte)flame;
|
||||
}
|
||||
|
||||
// Transfer flameRoot to indexBuffer
|
||||
for (var x = 0; x < flameWidth; x++)
|
||||
{
|
||||
var i = x + (imageHeight - 1) * imageWidth;
|
||||
indexBuffer[i] = flameRootBuffer[x];
|
||||
}
|
||||
|
||||
// Clear top row, because it can't move any higher
|
||||
for (var x = 0; x < imageWidth; x++)
|
||||
{
|
||||
if (indexBuffer[x] != 0)
|
||||
{
|
||||
indexBuffer[x] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Skip top row, it is already cleared
|
||||
for (var y = 1; y < imageHeight; y++)
|
||||
{
|
||||
for (var x = 0; x < imageWidth; x++)
|
||||
{
|
||||
var i = x + y * imageWidth;
|
||||
int colorIndex = indexBuffer[i];
|
||||
|
||||
if (colorIndex != 0)
|
||||
{
|
||||
// Move pixel a row above
|
||||
indexBuffer[i] = 0;
|
||||
var moveX = GetRandomValue(0, 2) - 1;
|
||||
var newX = x + moveX;
|
||||
|
||||
if ((newX > 0) && (newX < imageWidth))
|
||||
{
|
||||
var iabove = i - imageWidth + moveX;
|
||||
var decay = GetRandomValue(0, 3);
|
||||
colorIndex -= (decay < colorIndex) ? decay : colorIndex;
|
||||
indexBuffer[iabove] = (byte)colorIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update screenImage with palette colors
|
||||
for (var y = 1; y < imageHeight; y++)
|
||||
{
|
||||
for (var x = 0; x < imageWidth; x++)
|
||||
{
|
||||
var i = x + y * imageWidth;
|
||||
int colorIndex = indexBuffer[i];
|
||||
var col = palette[colorIndex];
|
||||
|
||||
ImageDrawPixel(ref screenImage, x, y, col);
|
||||
}
|
||||
}
|
||||
|
||||
UpdateTexture(screenTexture, screenImage.Data);
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
DrawTextureEx(screenTexture, new Vector2(0, 0), 0.0f, 2.0f, Color.White);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
UnloadTexture(screenTexture);
|
||||
UnloadImage(screenImage);
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - screen buffer");
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
var game = new ScreenBuffer();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,122 +1,147 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [textures] example - Texture loading and drawing a part defined by a rectangle
|
||||
* raylib [textures] example - sprite animation
|
||||
*
|
||||
* This example has been created using raylib 1.3 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
* Example complexity rating: [★★☆☆] 2/4
|
||||
*
|
||||
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
|
||||
* Example originally created with raylib 1.3, last time updated with raylib 1.3
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2014-2025 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Numerics;
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
namespace Examples.Textures;
|
||||
|
||||
public class SpriteAnim
|
||||
public partial class SpriteAnim : IExample
|
||||
{
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
public const int MaxFrameSpeed = 15;
|
||||
public const int MinFrameSpeed = 1;
|
||||
|
||||
public string Name => "Textures / Sprite Anim";
|
||||
|
||||
public string Title => "raylib [textures] example - sprite animation";
|
||||
|
||||
private Texture2D scarfy;
|
||||
private Vector2 position;
|
||||
private Rectangle frameRec;
|
||||
private int currentFrame;
|
||||
private int framesCounter;
|
||||
private int framesSpeed;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
|
||||
scarfy = LoadTexture("resources/scarfy.png"); // Texture loading
|
||||
|
||||
position = new(350.0f, 280.0f);
|
||||
frameRec = new(0.0f, 0.0f, (float)scarfy.Width / 6, (float)scarfy.Height);
|
||||
currentFrame = 0;
|
||||
|
||||
framesCounter = 0;
|
||||
framesSpeed = 8; // Number of spritesheet frames shown by second
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
framesCounter++;
|
||||
|
||||
if (framesCounter >= (60 / framesSpeed))
|
||||
{
|
||||
framesCounter = 0;
|
||||
currentFrame++;
|
||||
|
||||
if (currentFrame > 5)
|
||||
{
|
||||
currentFrame = 0;
|
||||
}
|
||||
|
||||
frameRec.X = (float)currentFrame * (float)scarfy.Width / 6;
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KeyboardKey.Right))
|
||||
{
|
||||
framesSpeed++;
|
||||
}
|
||||
else if (IsKeyPressed(KeyboardKey.Left))
|
||||
{
|
||||
framesSpeed--;
|
||||
}
|
||||
|
||||
framesSpeed = Math.Clamp(framesSpeed, MinFrameSpeed, MaxFrameSpeed);
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
DrawTexture(scarfy, 15, 40, Color.White);
|
||||
DrawRectangleLines(15, 40, scarfy.Width, scarfy.Height, Color.Lime);
|
||||
DrawRectangleLines(
|
||||
15 + (int)frameRec.X,
|
||||
40 + (int)frameRec.Y,
|
||||
(int)frameRec.Width,
|
||||
(int)frameRec.Height,
|
||||
Color.Red
|
||||
);
|
||||
|
||||
DrawText("FRAME SPEED: ", 165, 210, 10, Color.DarkGray);
|
||||
DrawText($"{framesSpeed:D2} FPS", 575, 210, 10, Color.DarkGray);
|
||||
DrawText("PRESS RIGHT/LEFT KEYS to CHANGE SPEED!", 290, 240, 10, Color.DarkGray);
|
||||
|
||||
for (var i = 0; i < MaxFrameSpeed; i++)
|
||||
{
|
||||
if (i < framesSpeed)
|
||||
{
|
||||
DrawRectangle(250 + 21 * i, 205, 20, 20, Color.Red);
|
||||
}
|
||||
DrawRectangleLines(250 + 21 * i, 205, 20, 20, Color.Maroon);
|
||||
}
|
||||
|
||||
DrawTextureRec(scarfy, frameRec, position, Color.White); // Draw part of the texture
|
||||
|
||||
DrawText("(c) Scarfy sprite by Eiden Marsal", screenWidth - 200, screenHeight - 20, 10, Color.Gray);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
UnloadTexture(scarfy); // Texture unloading
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - sprite animation");
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [texture] example - texture rectangle");
|
||||
|
||||
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
|
||||
Texture2D scarfy = LoadTexture("resources/scarfy.png");
|
||||
|
||||
Vector2 position = new(350.0f, 280.0f);
|
||||
Rectangle frameRec = new(0.0f, 0.0f, (float)scarfy.Width / 6, (float)scarfy.Height);
|
||||
int currentFrame = 0;
|
||||
|
||||
int framesCounter = 0;
|
||||
|
||||
// Number of spritesheet frames shown by second
|
||||
int framesSpeed = 8;
|
||||
|
||||
SetTargetFPS(60);
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
var game = new SpriteAnim();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
framesCounter++;
|
||||
|
||||
if (framesCounter >= (60 / framesSpeed))
|
||||
{
|
||||
framesCounter = 0;
|
||||
currentFrame++;
|
||||
|
||||
if (currentFrame > 5)
|
||||
{
|
||||
currentFrame = 0;
|
||||
}
|
||||
|
||||
frameRec.X = (float)currentFrame * (float)scarfy.Width / 6;
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KeyboardKey.Right))
|
||||
{
|
||||
framesSpeed++;
|
||||
}
|
||||
else if (IsKeyPressed(KeyboardKey.Left))
|
||||
{
|
||||
framesSpeed--;
|
||||
}
|
||||
|
||||
framesSpeed = Math.Clamp(framesSpeed, MinFrameSpeed, MaxFrameSpeed);
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
DrawTexture(scarfy, 15, 40, Color.White);
|
||||
DrawRectangleLines(15, 40, scarfy.Width, scarfy.Height, Color.Lime);
|
||||
DrawRectangleLines(
|
||||
15 + (int)frameRec.X,
|
||||
40 + (int)frameRec.Y,
|
||||
(int)frameRec.Width,
|
||||
(int)frameRec.Height,
|
||||
Color.Red
|
||||
);
|
||||
|
||||
DrawText("FRAME SPEED: ", 165, 210, 10, Color.DarkGray);
|
||||
DrawText($"{framesSpeed:2F} FPS", 575, 210, 10, Color.DarkGray);
|
||||
DrawText("PRESS RIGHT/LEFT KEYS to CHANGE SPEED!", 290, 240, 10, Color.DarkGray);
|
||||
|
||||
for (int i = 0; i < MaxFrameSpeed; i++)
|
||||
{
|
||||
if (i < framesSpeed)
|
||||
{
|
||||
DrawRectangle(250 + 21 * i, 205, 20, 20, Color.Red);
|
||||
}
|
||||
DrawRectangleLines(250 + 21 * i, 205, 20, 20, Color.Maroon);
|
||||
}
|
||||
|
||||
// Draw part of the texture
|
||||
DrawTextureRec(scarfy, frameRec, position, Color.White);
|
||||
DrawText("(c) Scarfy sprite by Eiden Marsal", screenWidth - 200, screenHeight - 20, 10, Color.Gray);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadTexture(scarfy);
|
||||
|
||||
CloseWindow();
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -2,43 +2,53 @@
|
|||
*
|
||||
* raylib [textures] example - sprite button
|
||||
*
|
||||
* This example has been created using raylib 2.5 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
* Example complexity rating: [★★☆☆] 2/4
|
||||
*
|
||||
* Copyright (c) 2019 Ramon Santamaria (@raysan5)
|
||||
* Example originally created with raylib 2.5, last time updated with raylib 2.5
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2019-2025 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using System.Numerics;
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
namespace Examples.Textures;
|
||||
|
||||
public class SpriteButton
|
||||
public partial class SpriteButton : IExample
|
||||
{
|
||||
// Number of frames (rectangles) for the button sprite texture
|
||||
public const int NumFrames = 3;
|
||||
|
||||
public static int Main()
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
public string Name => "Textures / Sprite Button";
|
||||
|
||||
public string Title => "raylib [textures] example - sprite button";
|
||||
|
||||
private Sound fxButton;
|
||||
private Texture2D button;
|
||||
private int frameHeight;
|
||||
private Rectangle sourceRec;
|
||||
private Rectangle btnBounds;
|
||||
private int btnState;
|
||||
private bool btnAction;
|
||||
private Vector2 mousePoint;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
InitAudioDevice(); // Initialize audio device
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - sprite button");
|
||||
|
||||
InitAudioDevice();
|
||||
|
||||
Sound fxButton = LoadSound("resources/audio/buttonfx.wav");
|
||||
Texture2D button = LoadTexture("resources/button.png");
|
||||
fxButton = LoadSound("resources/audio/buttonfx.wav"); // Load button sound
|
||||
button = LoadTexture("resources/button.png"); // Load button texture
|
||||
|
||||
// Define frame rectangle for drawing
|
||||
int frameHeight = button.Height / NumFrames;
|
||||
Rectangle sourceRec = new(0, 0, button.Width, frameHeight);
|
||||
frameHeight = button.Height / NumFrames;
|
||||
sourceRec = new(0, 0, button.Width, frameHeight);
|
||||
|
||||
// Define button bounds on screen
|
||||
Rectangle btnBounds = new(
|
||||
btnBounds = new(
|
||||
screenWidth / 2 - button.Width / 2,
|
||||
screenHeight / 2 - button.Height / NumFrames / 2,
|
||||
button.Width,
|
||||
|
|
@ -46,75 +56,95 @@ public class SpriteButton
|
|||
);
|
||||
|
||||
// Button state: 0-NORMAL, 1-MOUSE_HOVER, 2-PRESSED
|
||||
int btnState = 0;
|
||||
btnState = 0;
|
||||
|
||||
// Button action should be activated
|
||||
bool btnAction = false;
|
||||
btnAction = false;
|
||||
|
||||
Vector2 mousePoint = new(0.0f, 0.0f);
|
||||
mousePoint = new(0.0f, 0.0f);
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
mousePoint = GetMousePosition();
|
||||
btnAction = false;
|
||||
|
||||
// Check button state
|
||||
if (CheckCollisionPointRec(mousePoint, btnBounds))
|
||||
{
|
||||
if (IsMouseButtonDown(MouseButton.Left))
|
||||
{
|
||||
btnState = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
btnState = 1;
|
||||
}
|
||||
|
||||
if (IsMouseButtonReleased(MouseButton.Left))
|
||||
{
|
||||
btnAction = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
btnState = 0;
|
||||
}
|
||||
|
||||
if (btnAction)
|
||||
{
|
||||
PlaySound(fxButton);
|
||||
// TODO: Any desired action
|
||||
}
|
||||
|
||||
// Calculate button frame rectangle to draw depending on button state
|
||||
sourceRec.Y = btnState * frameHeight;
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
DrawTextureRec(button, sourceRec, new Vector2(btnBounds.X, btnBounds.Y), Color.White); // Draw button frame
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
UnloadTexture(button); // Unload button texture
|
||||
UnloadSound(fxButton); // Unload sound
|
||||
|
||||
CloseAudioDevice(); // Close audio device
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - sprite button");
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
var game = new SpriteButton();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
mousePoint = GetMousePosition();
|
||||
btnAction = false;
|
||||
|
||||
// Check button state
|
||||
if (CheckCollisionPointRec(mousePoint, btnBounds))
|
||||
{
|
||||
if (IsMouseButtonDown(MouseButton.Left))
|
||||
{
|
||||
btnState = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
btnState = 1;
|
||||
}
|
||||
|
||||
if (IsMouseButtonReleased(MouseButton.Left))
|
||||
{
|
||||
btnAction = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
btnState = 0;
|
||||
}
|
||||
|
||||
if (btnAction)
|
||||
{
|
||||
PlaySound(fxButton);
|
||||
// TODO: Any desired action
|
||||
}
|
||||
|
||||
// Calculate button frame rectangle to draw depending on button state
|
||||
sourceRec.Y = btnState * frameHeight;
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
// Draw button frame
|
||||
DrawTextureRec(button, sourceRec, new Vector2(btnBounds.X, btnBounds.Y), Color.White);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadTexture(button);
|
||||
UnloadSound(fxButton);
|
||||
|
||||
CloseAudioDevice();
|
||||
CloseWindow();
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -2,129 +2,157 @@
|
|||
*
|
||||
* raylib [textures] example - sprite explosion
|
||||
*
|
||||
* This example has been created using raylib 2.5 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
* Example complexity rating: [★★☆☆] 2/4
|
||||
*
|
||||
* Copyright (c) 2019 Anata and Ramon Santamaria (@raysan5)
|
||||
* Example originally created with raylib 2.5, last time updated with raylib 3.5
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2019-2025 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using System.Numerics;
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
namespace Examples.Textures;
|
||||
|
||||
public class SpriteExplosion
|
||||
public partial class SpriteExplosion : IExample
|
||||
{
|
||||
const int NumFramesPerLine = 5;
|
||||
const int NumLines = 5;
|
||||
private const int NumFramesPerLine = 5;
|
||||
private const int NumLines = 5;
|
||||
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
public string Name => "Textures / Sprite Explosion";
|
||||
|
||||
public string Title => "raylib [textures] example - sprite explosion";
|
||||
|
||||
private Sound fxBoom;
|
||||
private Texture2D explosion;
|
||||
private int frameWidth;
|
||||
private int frameHeight;
|
||||
private int currentFrame;
|
||||
private int currentLine;
|
||||
private Rectangle frameRec;
|
||||
private Vector2 position;
|
||||
private bool active;
|
||||
private int framesCounter;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
InitAudioDevice();
|
||||
|
||||
// Load explosion sound
|
||||
fxBoom = LoadSound("resources/audio/boom.wav");
|
||||
|
||||
// Load explosion texture
|
||||
explosion = LoadTexture("resources/explosion.png");
|
||||
|
||||
// Init variables for animation
|
||||
frameWidth = explosion.Width / NumFramesPerLine; // Sprite one frame rectangle width
|
||||
frameHeight = explosion.Height / NumLines; // Sprite one frame rectangle height
|
||||
currentFrame = 0;
|
||||
currentLine = 0;
|
||||
|
||||
frameRec = new(0, 0, frameWidth, frameHeight);
|
||||
position = new(0.0f, 0.0f);
|
||||
|
||||
active = false;
|
||||
framesCounter = 0;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Check for mouse button pressed and activate explosion (if not active)
|
||||
if (IsMouseButtonPressed(MouseButton.Left) && !active)
|
||||
{
|
||||
position = GetMousePosition();
|
||||
active = true;
|
||||
|
||||
position.X -= frameWidth / 2;
|
||||
position.Y -= frameHeight / 2;
|
||||
|
||||
PlaySound(fxBoom);
|
||||
}
|
||||
|
||||
// Compute explosion animation frames
|
||||
if (active)
|
||||
{
|
||||
framesCounter++;
|
||||
|
||||
if (framesCounter > 2)
|
||||
{
|
||||
currentFrame++;
|
||||
|
||||
if (currentFrame >= NumFramesPerLine)
|
||||
{
|
||||
currentFrame = 0;
|
||||
currentLine++;
|
||||
|
||||
if (currentLine >= NumLines)
|
||||
{
|
||||
currentLine = 0;
|
||||
active = false;
|
||||
}
|
||||
}
|
||||
|
||||
framesCounter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
frameRec.X = frameWidth * currentFrame;
|
||||
frameRec.Y = frameHeight * currentLine;
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
// Draw explosion required frame rectangle
|
||||
if (active)
|
||||
{
|
||||
DrawTextureRec(explosion, frameRec, position, Color.White);
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
UnloadTexture(explosion); // Unload texture
|
||||
UnloadSound(fxBoom); // Unload sound
|
||||
|
||||
CloseAudioDevice();
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - sprite explosion");
|
||||
InitAudioDevice();
|
||||
|
||||
// Load explosion sound
|
||||
Sound fxBoom = LoadSound("resources/audio/boom.wav");
|
||||
|
||||
// Load explosion texture
|
||||
Texture2D explosion = LoadTexture("resources/explosion.png");
|
||||
|
||||
// Init variables for animation
|
||||
|
||||
// Sprite one frame rectangle width
|
||||
int frameWidth = explosion.Width / NumFramesPerLine;
|
||||
|
||||
// Sprite one frame rectangle height
|
||||
int frameHeight = explosion.Height / NumLines;
|
||||
|
||||
int currentFrame = 0;
|
||||
int currentLine = 0;
|
||||
|
||||
Rectangle frameRec = new(0, 0, frameWidth, frameHeight);
|
||||
Vector2 position = new(0.0f, 0.0f);
|
||||
|
||||
bool active = false;
|
||||
int framesCounter = 0;
|
||||
|
||||
SetTargetFPS(120);
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
var game = new SpriteExplosion();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Check for mouse button pressed and activate explosion (if not active)
|
||||
if (IsMouseButtonPressed(MouseButton.Left) && !active)
|
||||
{
|
||||
position = GetMousePosition();
|
||||
active = true;
|
||||
|
||||
position.X -= frameWidth / 2;
|
||||
position.Y -= frameHeight / 2;
|
||||
|
||||
PlaySound(fxBoom);
|
||||
}
|
||||
|
||||
// Compute explosion animation frames
|
||||
if (active)
|
||||
{
|
||||
framesCounter++;
|
||||
|
||||
if (framesCounter > 2)
|
||||
{
|
||||
currentFrame++;
|
||||
|
||||
if (currentFrame >= NumFramesPerLine)
|
||||
{
|
||||
currentFrame = 0;
|
||||
currentLine++;
|
||||
|
||||
if (currentLine >= NumLines)
|
||||
{
|
||||
currentLine = 0;
|
||||
active = false;
|
||||
}
|
||||
}
|
||||
|
||||
framesCounter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
frameRec.X = frameWidth * currentFrame;
|
||||
frameRec.Y = frameHeight * currentLine;
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
// Draw explosion required frame rectangle
|
||||
if (active)
|
||||
{
|
||||
DrawTextureRec(explosion, frameRec, position, Color.White);
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadTexture(explosion);
|
||||
UnloadSound(fxBoom);
|
||||
|
||||
CloseAudioDevice();
|
||||
|
||||
CloseWindow();
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
137
Examples/Textures/SpriteStacking.cs
Normal file
137
Examples/Textures/SpriteStacking.cs
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [textures] example - sprite stacking
|
||||
*
|
||||
* Example complexity rating: [★★☆☆] 2/4
|
||||
*
|
||||
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||
*
|
||||
* Example contributed by Robin (@RobinsAviary) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Redbooth model (c) 2017-2025 @kluchek under https://creativecommons.org/licenses/by/4.0/ https://github.com/kluchek/vox-models/
|
||||
* Copyright (c) 2025 Robin (@RobinsAviary)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
namespace Examples.Textures;
|
||||
|
||||
public partial class SpriteStacking : IExample
|
||||
{
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
private const float speedChange = 0.25f; // Amount speed will change by when the user presses A/D
|
||||
|
||||
public string Name => "Textures / Sprite Stacking";
|
||||
|
||||
public string Title => "raylib [textures] example - sprite stacking";
|
||||
|
||||
private Texture2D booth;
|
||||
private float stackScale; // Overall scale of the stacked sprite
|
||||
private float stackSpacing; // Vertical spacing between each layer
|
||||
private uint stackCount; // Number of layers, used for calculating the size of a single slice
|
||||
private float rotationSpeed; // Stacked sprites rotation speed
|
||||
private float rotation; // Current rotation of the stacked sprite
|
||||
|
||||
public void Init()
|
||||
{
|
||||
booth = LoadTexture("resources/booth.png");
|
||||
|
||||
stackScale = 3.0f;
|
||||
stackSpacing = 2.0f;
|
||||
stackCount = 122;
|
||||
rotationSpeed = 30.0f;
|
||||
rotation = 0.0f;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// Use mouse wheel to affect stack separation
|
||||
stackSpacing += GetMouseWheelMove() * 0.1f;
|
||||
stackSpacing = Math.Clamp(stackSpacing, 0.0f, 5.0f);
|
||||
|
||||
// Add a positive/negative offset to spin right/left at different speeds
|
||||
if (IsKeyDown(KeyboardKey.Left) || IsKeyDown(KeyboardKey.A))
|
||||
{
|
||||
rotationSpeed -= speedChange;
|
||||
}
|
||||
if (IsKeyDown(KeyboardKey.Right) || IsKeyDown(KeyboardKey.D))
|
||||
{
|
||||
rotationSpeed += speedChange;
|
||||
}
|
||||
|
||||
rotation += rotationSpeed * GetFrameTime();
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
// Get the size of a single slice
|
||||
var frameWidth = (float)booth.Width;
|
||||
var frameHeight = (float)booth.Height / (float)stackCount;
|
||||
|
||||
// Get the scaled resolution to draw at
|
||||
var scaledWidth = frameWidth * stackScale;
|
||||
var scaledHeight = frameHeight * stackScale;
|
||||
|
||||
// Draw the stacked sprite, rotated to the correct angle, with an vertical offset applied based on its y location
|
||||
for (var i = (int)stackCount - 1; i >= 0; i--)
|
||||
{
|
||||
// Center vertically
|
||||
Rectangle source = new(0.0f, (float)i * frameHeight, frameWidth, frameHeight);
|
||||
Rectangle dest = new(screenWidth / 2.0f, (screenHeight / 2.0f) + (i * stackSpacing) - (stackSpacing * stackCount / 2.0f), scaledWidth, scaledHeight);
|
||||
Vector2 origin = new(scaledWidth / 2.0f, scaledHeight / 2.0f);
|
||||
|
||||
DrawTexturePro(booth, source, dest, origin, rotation, Color.White);
|
||||
}
|
||||
|
||||
DrawText("A/D to spin\nmouse wheel to change separation (aka 'angle')", 10, 10, 20, Color.DarkGray);
|
||||
DrawText($"current spacing: {stackSpacing:F1}", 10, 50, 20, Color.DarkGray);
|
||||
DrawText($"current speed: {rotationSpeed:F2}", 10, 70, 20, Color.DarkGray);
|
||||
DrawText("redbooth model (c) kluchek under cc 4.0", 10, 420, 20, Color.DarkGray);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
UnloadTexture(booth);
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - sprite stacking");
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
var game = new SpriteStacking();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,85 +1,112 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [textures] example - Texture source and destination rectangles
|
||||
* raylib [textures] example - srcrec dstrec
|
||||
*
|
||||
* This example has been created using raylib 1.3 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
* Example complexity rating: [★★★☆] 3/4
|
||||
*
|
||||
* Copyright (c) 2015 Ramon Santamaria (@raysan5)
|
||||
* Example originally created with raylib 1.3, last time updated with raylib 1.3
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2015-2025 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using System.Numerics;
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
namespace Examples.Textures;
|
||||
|
||||
public class SrcRecDstRec
|
||||
public partial class SrcRecDstRec : IExample
|
||||
{
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
public string Name => "Textures / Src and Dst Rectangles";
|
||||
|
||||
public string Title => "raylib [textures] example - srcrec dstrec";
|
||||
|
||||
private Texture2D scarfy;
|
||||
private Rectangle sourceRec;
|
||||
private Rectangle destRec;
|
||||
private Vector2 origin;
|
||||
private int rotation;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
|
||||
|
||||
scarfy = LoadTexture("resources/scarfy.png"); // Texture loading
|
||||
|
||||
var frameWidth = scarfy.Width / 6;
|
||||
var frameHeight = scarfy.Height;
|
||||
|
||||
// Source rectangle (part of the texture to use for drawing)
|
||||
sourceRec = new(0, 0, frameWidth, frameHeight);
|
||||
|
||||
// Destination rectangle (screen rectangle where drawing part of texture)
|
||||
destRec = new(screenWidth / 2, screenHeight / 2, frameWidth * 2, frameHeight * 2);
|
||||
|
||||
// Origin of the texture (rotation/scale point), it's relative to destination rectangle size
|
||||
origin = new(frameWidth, frameHeight);
|
||||
|
||||
rotation = 0;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
rotation++;
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
// NOTE: Using DrawTexturePro() we can easily rotate and scale the part of the texture we draw
|
||||
// sourceRec defines the part of the texture we use for drawing
|
||||
// destRec defines the rectangle where our texture part will fit (scaling it to fit)
|
||||
// origin defines the point of the texture used as reference for rotation and scaling
|
||||
// rotation defines the texture rotation (using origin as rotation point)
|
||||
DrawTexturePro(scarfy, sourceRec, destRec, origin, rotation, Color.White);
|
||||
|
||||
DrawLine((int)destRec.X, 0, (int)destRec.X, screenHeight, Color.Gray);
|
||||
DrawLine(0, (int)destRec.Y, screenWidth, (int)destRec.Y, Color.Gray);
|
||||
|
||||
DrawText("(c) Scarfy sprite by Eiden Marsal", screenWidth - 200, screenHeight - 20, 10, Color.Gray);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
UnloadTexture(scarfy); // Texture unloading
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
string title = "raylib [textures] examples - texture source and destination rectangles";
|
||||
InitWindow(screenWidth, screenHeight, title);
|
||||
|
||||
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
|
||||
Texture2D scarfy = LoadTexture("resources/scarfy.png");
|
||||
|
||||
int frameWidth = scarfy.Width / 6;
|
||||
int frameHeight = scarfy.Height;
|
||||
|
||||
// NOTE: Source rectangle (part of the texture to use for drawing)
|
||||
Rectangle sourceRec = new(0, 0, frameWidth, frameHeight);
|
||||
|
||||
// NOTE: Destination rectangle (screen rectangle where drawing part of texture)
|
||||
Rectangle destRec = new(screenWidth / 2, screenHeight / 2, frameWidth * 2, frameHeight * 2);
|
||||
|
||||
// NOTE: Origin of the texture (rotation/scale point), it's relative to destination rectangle size
|
||||
Vector2 origin = new(frameWidth, frameHeight);
|
||||
|
||||
int rotation = 0;
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - srcrec dstrec");
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
var game = new SrcRecDstRec();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
rotation++;
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
// NOTE: Using DrawTexturePro() we can easily rotate and scale the part of the texture we draw
|
||||
// sourceRec defines the part of the texture we use for drawing
|
||||
// destRec defines the rectangle where our texture part will fit (scaling it to fit)
|
||||
// origin defines the point of the texture used as reference for rotation and scaling
|
||||
// rotation defines the texture rotation (using origin as rotation point)
|
||||
DrawTexturePro(scarfy, sourceRec, destRec, origin, rotation, Color.White);
|
||||
|
||||
DrawLine((int)destRec.X, 0, (int)destRec.X, screenHeight, Color.Gray);
|
||||
DrawLine(0, (int)destRec.Y, screenWidth, (int)destRec.Y, Color.Gray);
|
||||
|
||||
DrawText("(c) Scarfy sprite by Eiden Marsal", screenWidth - 200, screenHeight - 20, 10, Color.Gray);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadTexture(scarfy);
|
||||
|
||||
CloseWindow();
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,33 @@
|
|||
using System;
|
||||
using System.Numerics;
|
||||
using static Raylib_cs.Raylib;
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [textures] example - textured curve
|
||||
*
|
||||
* Example complexity rating: [★★★☆] 3/4
|
||||
*
|
||||
* Example originally created with raylib 4.5, last time updated with raylib 4.5
|
||||
*
|
||||
* Example contributed by Jeffery Myers (@JeffM2501) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2022-2025 Jeffery Myers (@JeffM2501) and Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
namespace Examples.Textures;
|
||||
|
||||
public unsafe class TexturedCurve
|
||||
public unsafe partial class TexturedCurve : IExample
|
||||
{
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
public string Name => "Textures / Textured Curve";
|
||||
|
||||
public string Title => "raylib [textures] example - textured curve";
|
||||
|
||||
public ConfigFlags ConfigFlags => ConfigFlags.VSyncHint | ConfigFlags.Msaa4xHint;
|
||||
|
||||
public class CurvePoint
|
||||
{
|
||||
public Vector2 value;
|
||||
|
|
@ -17,26 +39,18 @@ public unsafe class TexturedCurve
|
|||
public static implicit operator Vector2(CurvePoint v) => v.value;
|
||||
}
|
||||
|
||||
static Texture2D texRoad;
|
||||
static bool showCurve = false;
|
||||
static float curveWidth = 50;
|
||||
static int curveSegments = 24;
|
||||
static CurvePoint curveStartPosition;
|
||||
static CurvePoint curveStartPositionTangent;
|
||||
static CurvePoint curveEndPosition;
|
||||
static CurvePoint curveEndPositionTangent;
|
||||
static CurvePoint curveSelectedPoint;
|
||||
private Texture2D texRoad;
|
||||
private bool showCurve;
|
||||
private float curveWidth;
|
||||
private int curveSegments;
|
||||
private CurvePoint curveStartPosition;
|
||||
private CurvePoint curveStartPositionTangent;
|
||||
private CurvePoint curveEndPosition;
|
||||
private CurvePoint curveEndPositionTangent;
|
||||
private CurvePoint curveSelectedPoint;
|
||||
|
||||
public static int Main()
|
||||
public void Init()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
SetConfigFlags(ConfigFlags.VSyncHint | ConfigFlags.Msaa4xHint);
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] examples - textured curve");
|
||||
|
||||
// Load the road texture
|
||||
texRoad = LoadTexture("resources/road.png");
|
||||
SetTextureFilter(texRoad, TextureFilter.Bilinear);
|
||||
|
|
@ -48,45 +62,42 @@ public unsafe class TexturedCurve
|
|||
curveEndPosition = new Vector2(700, 350);
|
||||
curveEndPositionTangent = new Vector2(600, 100);
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
UpdateCurve();
|
||||
UpdateOptions();
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
DrawTexturedCurve();
|
||||
DrawCurve();
|
||||
|
||||
DrawText("Drag points to move curve, press SPACE to show/hide base curve", 10, 10, 10, Color.DarkGray);
|
||||
DrawText($"Curve width: {curveWidth} (Use + and - to adjust)", 10, 30, 10, Color.DarkGray);
|
||||
DrawText($"Curve segments: {curveSegments} (Use LEFT and RIGHT to adjust)", 10, 50, 10, Color.DarkGray);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadTexture(texRoad);
|
||||
|
||||
CloseWindow();
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
showCurve = false;
|
||||
curveWidth = 50;
|
||||
curveSegments = 24;
|
||||
curveSelectedPoint = null;
|
||||
}
|
||||
|
||||
static void DrawCurve()
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
UpdateCurve();
|
||||
UpdateOptions();
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
DrawTexturedCurve();
|
||||
DrawCurve();
|
||||
|
||||
DrawText("Drag points to move curve, press SPACE to show/hide base curve", 10, 10, 10, Color.DarkGray);
|
||||
DrawText($"Curve width: {curveWidth} (Use + and - to adjust)", 10, 30, 10, Color.DarkGray);
|
||||
DrawText($"Curve segments: {curveSegments} (Use LEFT and RIGHT to adjust)", 10, 50, 10, Color.DarkGray);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
UnloadTexture(texRoad);
|
||||
}
|
||||
|
||||
private void DrawCurve()
|
||||
{
|
||||
if (showCurve)
|
||||
{
|
||||
|
|
@ -104,7 +115,7 @@ public unsafe class TexturedCurve
|
|||
DrawLineV(curveStartPosition, curveStartPositionTangent, Color.SkyBlue);
|
||||
DrawLineV(curveStartPositionTangent, curveEndPositionTangent, Fade(Color.LightGray, 0.4f));
|
||||
DrawLineV(curveEndPosition, curveEndPositionTangent, Color.Purple);
|
||||
Vector2 mouse = GetMousePosition();
|
||||
var mouse = GetMousePosition();
|
||||
|
||||
if (CheckCollisionPointCircle(mouse, curveStartPosition, 6))
|
||||
{
|
||||
|
|
@ -131,11 +142,12 @@ public unsafe class TexturedCurve
|
|||
DrawCircleV(curveEndPositionTangent, 5, Color.DarkGreen);
|
||||
}
|
||||
|
||||
static void UpdateCurve()
|
||||
private void UpdateCurve()
|
||||
{
|
||||
// If the mouse is not down, we are not editing the curve so clear the selection
|
||||
if (!IsMouseButtonDown(MouseButton.Left))
|
||||
{
|
||||
curveSelectedPoint = null;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -146,7 +158,7 @@ public unsafe class TexturedCurve
|
|||
}
|
||||
|
||||
// The mouse is down, and nothing was selected, so see if anything was picked
|
||||
Vector2 mouse = GetMousePosition();
|
||||
var mouse = GetMousePosition();
|
||||
|
||||
if (CheckCollisionPointCircle(mouse, curveStartPosition, 6))
|
||||
{
|
||||
|
|
@ -166,28 +178,28 @@ public unsafe class TexturedCurve
|
|||
}
|
||||
}
|
||||
|
||||
static void DrawTexturedCurve()
|
||||
private void DrawTexturedCurve()
|
||||
{
|
||||
float step = 1.0f / curveSegments;
|
||||
var step = 1.0f / curveSegments;
|
||||
|
||||
Vector2 previous = curveStartPosition;
|
||||
Vector2 previousTangent = Vector2.Zero;
|
||||
var previousTangent = Vector2.Zero;
|
||||
float previousV = 0;
|
||||
|
||||
// We can't compute a tangent for the first point, so we need to reuse the tangent from the first segment
|
||||
bool tangentSet = false;
|
||||
var tangentSet = false;
|
||||
|
||||
Vector2 current = Vector2.Zero;
|
||||
float t = 0.0f;
|
||||
var current = Vector2.Zero;
|
||||
var t = 0.0f;
|
||||
|
||||
for (int i = 1; i <= curveSegments; i++)
|
||||
for (var i = 1; i <= curveSegments; i++)
|
||||
{
|
||||
// Segment the curve
|
||||
t = step * i;
|
||||
float a = MathF.Pow(1 - t, 3);
|
||||
float b = 3 * MathF.Pow(1 - t, 2) * t;
|
||||
float c = 3 * (1 - t) * MathF.Pow(t, 2);
|
||||
float d = MathF.Pow(t, 3);
|
||||
var a = MathF.Pow(1 - t, 3);
|
||||
var b = 3 * MathF.Pow(1 - t, 2) * t;
|
||||
var c = 3 * (1 - t) * MathF.Pow(t, 2);
|
||||
var d = MathF.Pow(t, 3);
|
||||
|
||||
// Compute the endpoint for this segment
|
||||
current.Y = a * curveStartPosition.Y + b * curveStartPositionTangent.Y;
|
||||
|
|
@ -199,10 +211,10 @@ public unsafe class TexturedCurve
|
|||
Vector2 delta = new(current.X - previous.X, current.Y - previous.Y);
|
||||
|
||||
// The right hand normal to the delta vector
|
||||
Vector2 normal = Vector2.Normalize(new Vector2(-delta.Y, delta.X));
|
||||
var normal = Vector2.Normalize(new Vector2(-delta.Y, delta.X));
|
||||
|
||||
// The v teXture coordinate of the segment (add up the length of all the segments so far)
|
||||
float v = previousV + delta.Length();
|
||||
// The v texture coordinate of the segment (add up the length of all the segments so far)
|
||||
var v = previousV + delta.Length() / (texRoad.Height * 2);
|
||||
|
||||
// Make sure the start point has a normal
|
||||
if (!tangentSet)
|
||||
|
|
@ -211,12 +223,12 @@ public unsafe class TexturedCurve
|
|||
tangentSet = true;
|
||||
}
|
||||
|
||||
// EXtend out the normals from the previous and current points to get the quad for this segment
|
||||
Vector2 prevPosNormal = previous + (previousTangent * curveWidth);
|
||||
Vector2 prevNegNormal = previous + (previousTangent * -curveWidth);
|
||||
// Extend out the normals from the previous and current points to get the quad for this segment
|
||||
var prevPosNormal = previous + (previousTangent * curveWidth);
|
||||
var prevNegNormal = previous + (previousTangent * -curveWidth);
|
||||
|
||||
Vector2 currentPosNormal = current + (normal * curveWidth);
|
||||
Vector2 currentNegNormal = current + (normal * -curveWidth);
|
||||
var currentPosNormal = current + (normal * curveWidth);
|
||||
var currentNegNormal = current + (normal * -curveWidth);
|
||||
|
||||
// Draw the segment as a quad
|
||||
Rlgl.SetTexture(texRoad.Id);
|
||||
|
|
@ -239,21 +251,21 @@ public unsafe class TexturedCurve
|
|||
|
||||
Rlgl.End();
|
||||
|
||||
// The current step is the start of the neXt step
|
||||
// The current step is the start of the next step
|
||||
previous = current;
|
||||
previousTangent = normal;
|
||||
previousV = v;
|
||||
}
|
||||
}
|
||||
|
||||
static void UpdateOptions()
|
||||
private void UpdateOptions()
|
||||
{
|
||||
if (IsKeyPressed(KeyboardKey.Space))
|
||||
{
|
||||
showCurve = !showCurve;
|
||||
}
|
||||
|
||||
// Update with
|
||||
// Update width
|
||||
if (IsKeyPressed(KeyboardKey.Equal))
|
||||
{
|
||||
curveWidth += 2;
|
||||
|
|
@ -282,4 +294,33 @@ public unsafe class TexturedCurve
|
|||
curveSegments = 2;
|
||||
}
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
SetConfigFlags(ConfigFlags.VSyncHint | ConfigFlags.Msaa4xHint);
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - textured curve");
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
var game = new TexturedCurve();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,72 +1,93 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [textures] example - Retrieve image data from texture: GetTextureData()
|
||||
* raylib [textures] example - to image
|
||||
*
|
||||
* Example complexity rating: [★☆☆☆] 1/4
|
||||
*
|
||||
* NOTE: Images are loaded in CPU memory (RAM); textures are loaded in GPU memory (VRAM)
|
||||
*
|
||||
* This example has been created using raylib 1.3 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
* Example originally created with raylib 1.3, last time updated with raylib 4.0
|
||||
*
|
||||
* Copyright (c) 2015 Ramon Santamaria (@raysan5)
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2015-2025 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
namespace Examples.Textures;
|
||||
|
||||
public class ToImage
|
||||
public partial class ToImage : IExample
|
||||
{
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
public string Name => "Textures / Texture to Image";
|
||||
|
||||
public string Title => "raylib [textures] example - to image";
|
||||
|
||||
private Texture2D texture;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
|
||||
|
||||
var image = LoadImage("resources/raylib-cs_logo.png"); // Load image data into CPU memory (RAM)
|
||||
texture = LoadTextureFromImage(image); // Image converted to texture, GPU memory (RAM -> VRAM)
|
||||
UnloadImage(image); // Unload image data from CPU memory (RAM)
|
||||
|
||||
image = LoadImageFromTexture(texture); // Load image from GPU texture (VRAM -> RAM)
|
||||
UnloadTexture(texture); // Unload texture from GPU memory (VRAM)
|
||||
|
||||
texture = LoadTextureFromImage(image); // Recreate texture from retrieved image data (RAM -> VRAM)
|
||||
UnloadImage(image); // Unload retrieved image data from CPU memory (RAM)
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
var x = screenWidth / 2 - texture.Width / 2;
|
||||
var y = screenHeight / 2 - texture.Height / 2;
|
||||
DrawTexture(texture, x, y, Color.White);
|
||||
|
||||
DrawText("this IS a texture loaded from an image!", 300, 370, 10, Color.Gray);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
UnloadTexture(texture); // Texture unloading
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - to image");
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - texture to image");
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
|
||||
|
||||
Image image = LoadImage("resources/raylib-cs_logo.png");
|
||||
Texture2D texture = LoadTextureFromImage(image);
|
||||
UnloadImage(image);
|
||||
|
||||
image = LoadImageFromTexture(texture);
|
||||
UnloadTexture(texture);
|
||||
|
||||
texture = LoadTextureFromImage(image);
|
||||
UnloadImage(image);
|
||||
//---------------------------------------------------------------------------------------
|
||||
var game = new ToImage();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// TODO: Update your variables here
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
int x = screenWidth / 2 - texture.Width / 2;
|
||||
int y = screenHeight / 2 - texture.Height / 2;
|
||||
DrawTexture(texture, x, y, Color.White);
|
||||
|
||||
DrawText("this IS a texture loaded from an image!", 300, 370, 10, Color.Gray);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadTexture(texture);
|
||||
|
||||
CloseWindow();
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
Loading…
Reference in a new issue