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

Upgrade Raylib to 6.0 (#337)

* Updated target to Raylib 6 + synced invoke called with the changes in C. [WARNING: Breaking changes!]

* Added severial examples. Corrected towards the correct return type and add utilities to prevent working with pointers

* Additional resources from the Raylib repo.

* Fixed additional pinvokes to match with the new raylib bindings. [Warning breaking changes!]

* Fixing the QOL utils

* Fixing the Mesh struct

* Applying changes after review. Merged resources.LICENSE + raylib-cs.Native.csproj only targets dotnet8

* Updated README to reflect .NET 10 and Raylib 6 compatibility changes.

* Updated shader colors, adjusted car model scale, disabled HDR in SkyboxDemo, and fixed camera mode assignment. Removed unused `Capacity` field in FilePathList struct.

* Improved XML comments for consistency, fixed spacing and formatting across examples, added new resources to `resources.LICENSE`.

* Updated XML comment for `GetDirectoryFileCountEx` to clarify behavior and filtering options.

* Updated and clarified XML comments for methods and parameters, improved naming consistency, and refined shader-related functions. Renamed enums in `Shader.cs` for so it is inline with the upstream.

* Improved XML comments for clarity and consistency in `Model.cs` and `Mesh.cs`, updated method and variable names for better readability, and adjusted logic in span creation methods.

* Corrected XML comment capitalization in `Model.cs`.

---------

Co-authored-by: Meatcorps <info@meatcorps.nl>
This commit is contained in:
Dennis Steffen 2026-05-24 08:21:12 +02:00 committed by GitHub
commit 21d83c60a9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
189 changed files with 43644 additions and 380 deletions

View file

@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<TargetRaylibTag>5.5</TargetRaylibTag>
<TargetRaylibTag>6.0</TargetRaylibTag>
<Version>8.0.0</Version>
<PackageVersion>8.0.0</PackageVersion>
</PropertyGroup>

View file

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net8.0</TargetFrameworks>
<TargetFrameworks>net8.0;net10.0</TargetFrameworks>
<EnableDefaultItems>false</EnableDefaultItems>
<AssemblyName>Raylib-cs</AssemblyName>
<RootNamespace>Raylib_cs</RootNamespace>

View file

@ -19,7 +19,7 @@ public static unsafe partial class Raylib
/// </summary>
public const string NativeLibName = "raylib";
public const string RAYLIB_VERSION = "5.5";
public const string RAYLIB_VERSION = "6.0";
public const float DEG2RAD = MathF.PI / 180.0f;
public const float RAD2DEG = 180.0f / MathF.PI;
@ -207,7 +207,7 @@ public static unsafe partial class Raylib
/// <summary>Set window configuration state using flags</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial CBool SetWindowState(ConfigFlags flag);
public static partial void SetWindowState(ConfigFlags flag);
/// <summary>Clear window configuration state flags</summary>
[LibraryImport(NativeLibName)]
@ -689,7 +689,7 @@ public static unsafe partial class Raylib
/// <summary>Set the seed for the random number generator</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial int SetRandomSeed(uint seed);
public static partial void SetRandomSeed(uint seed);
/// <summary>Load random values sequence, no values repeated</summary>
[LibraryImport(NativeLibName)]
@ -701,6 +701,8 @@ public static unsafe partial class Raylib
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void UnloadRandomSequence(int* sequence);
// Misc. functions
/// <summary>Takes a screenshot of current screen (saved a .png)</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
@ -711,6 +713,13 @@ public static unsafe partial class Raylib
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void SetConfigFlags(ConfigFlags flags);
/// <summary>Open URL with default system browser (if available)</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void OpenURL(sbyte* url);
// Logging system
/// <summary>Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR)</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
@ -721,6 +730,8 @@ public static unsafe partial class Raylib
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void SetTraceLogLevel(TraceLogLevel logLevel);
// Memory management, using internal allocators
/// <summary>Internal memory allocator</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
@ -745,29 +756,6 @@ public static unsafe partial class Raylib
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void SetTraceLogCallback(delegate* unmanaged[Cdecl]<int, sbyte*, sbyte*, void> callback);
/// <summary>Set custom file binary data loader</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void SetLoadFileDataCallback(delegate* unmanaged[Cdecl]<sbyte*, int*, byte*> callback);
/// <summary>Set custom file binary data saver</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void SetSaveFileDataCallback(
delegate* unmanaged[Cdecl]<sbyte*, void*, int, CBool> callback
);
/// <summary>Set custom file text data loader</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void SetLoadFileTextCallback(delegate* unmanaged[Cdecl]<sbyte*, sbyte*> callback);
/// <summary>Set custom file text data saver</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void SetSaveFileTextCallback(delegate* unmanaged[Cdecl]<sbyte*, sbyte*, CBool> callback);
// Files management functions
/// <summary>Load file data as byte array (read)</summary>
@ -790,27 +778,81 @@ public static unsafe partial class Raylib
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial CBool ExportDataAsCode(byte* data, int dataSize, sbyte* fileName);
// Load text data from file (read), returns a '\0' terminated string
/// <summary>Load text data from file (read), returns a '\0' terminated string</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial sbyte* LoadFileText(sbyte* fileName);
// Unload file text data allocated by LoadFileText()
/// <summary>Unload file text data allocated by LoadFileText()</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void UnloadFileText(sbyte* text);
// Save text data to file (write), string must be '\0' terminated, returns true on success
/// <summary>Save text data to file (write), string must be '\0' terminated, returns true on success</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial CBool SaveFileText(sbyte* fileName, sbyte* text);
// Check if file exists
// File access custom callbacks
// WARNING: Callbacks setup is intended for advanced users
/// <summary>Set custom file binary data loader</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void SetLoadFileDataCallback(delegate* unmanaged[Cdecl]<sbyte*, int*, byte*> callback);
/// <summary>Set custom file binary data saver</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void SetSaveFileDataCallback(
delegate* unmanaged[Cdecl]<sbyte*, void*, int, CBool> callback
);
/// <summary>Set custom file text data loader</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void SetLoadFileTextCallback(delegate* unmanaged[Cdecl]<sbyte*, sbyte*> callback);
/// <summary>Set custom file text data saver</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void SetSaveFileTextCallback(delegate* unmanaged[Cdecl]<sbyte*, sbyte*, CBool> callback);
/// <summary>Rename file (if exists)</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial int FileRename(sbyte* fileName, sbyte* fileRename);
/// <summary>Remove file (if exists)</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial int FileRemove(sbyte* fileName);
/// <summary>Copy file from one path to another, dstPath created if it doesn't exist</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial int FileCopy(sbyte* srcPath, sbyte* dstPath);
/// <summary>Move file from one path to another, dstPath created if it doesn't exist</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial int FileMove(sbyte* srcPath, sbyte* dstPath);
/// <summary>Replace text in an existing file</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial int FileTextReplace(sbyte* fileName, sbyte* search, sbyte* replacement);
/// <summary>Find text in existing file</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial int FileTextFindIndex(sbyte* fileName, sbyte* search);
/// <summary>Check if file exists</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial CBool FileExists(sbyte* fileName);
// Check if a directory path exists
/// <summary>Check if a directory path exists</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial CBool DirectoryExists(sbyte* dirPath);
@ -825,6 +867,11 @@ public static unsafe partial class Raylib
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial int GetFileLength(sbyte* fileName);
/// <summary>Get file modification time (last write time)</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial CLong GetFileModTime(sbyte* fileName);
/// <summary>Get pointer to extension for a filename string (includes dot: '.png')</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
@ -865,20 +912,10 @@ public static unsafe partial class Raylib
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial int MakeDirectory(sbyte* dirPath);
/// <summary>Load directory filepaths</summary>
/// <summary>Change working directory, return true on success</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial FilePathList LoadDirectoryFiles(sbyte* dirPath, int* count);
/// <summary>Load directory filepaths with extension filtering and recursive directory scan. Use 'DIR' in the filter string to include directories in the result</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial FilePathList LoadDirectoryFilesEx(sbyte* basePath, sbyte* filter, CBool scanSubdirs);
/// <summary>Unload filepaths</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void UnloadDirectoryFiles(FilePathList files);
public static partial CBool ChangeDirectory(sbyte* dirPath);
/// <summary>Check if a given path is a file or a directory</summary>
[LibraryImport(NativeLibName)]
@ -890,10 +927,20 @@ public static unsafe partial class Raylib
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial CBool IsFileNameValid(sbyte* fileName);
/// <summary>Change working directory, return true on success</summary>
/// <summary>Load directory filepaths</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial CBool ChangeDirectory(sbyte* dir);
public static partial FilePathList LoadDirectoryFiles(sbyte* dirPath);
/// <summary>Load directory filepaths with extension filtering and recursive directory scan. Use 'DIR' in the filter string to include directories in the result</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial FilePathList LoadDirectoryFilesEx(sbyte* basePath, sbyte* filter, CBool scanSubdirs);
/// <summary>Unload filepaths</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void UnloadDirectoryFiles(FilePathList files);
/// <summary>Check if a file has been dropped into window</summary>
[LibraryImport(NativeLibName)]
@ -910,11 +957,15 @@ public static unsafe partial class Raylib
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void UnloadDroppedFiles(FilePathList files);
/// <summary>Get file modification time (last write time)</summary>
/// <summary>Get the file count in a directory</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial long GetFileModTime(sbyte* fileName);
public static partial int GetDirectoryFileCount(sbyte* dirPath);
/// <summary>Load directory filepaths with extension filtering and subdir scan; some filters available: "*.*", "FILES*", "DIRS*"</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial int GetDirectoryFileCountEx(sbyte* dirPath, sbyte* filter, CBool scanSubdirs);
// Compression/Encoding functionality
@ -936,7 +987,7 @@ public static unsafe partial class Raylib
/// <summary>Decode Base64 string data, memory must be MemFree()</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial byte* DecodeDataBase64(byte* data, int* outputSize);
public static partial byte* DecodeDataBase64(sbyte* data, int* outputSize);
/// <summary>Compute CRC32 hash code</summary>
[LibraryImport(NativeLibName)]
@ -953,10 +1004,10 @@ public static unsafe partial class Raylib
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial uint* ComputeSHA1(byte* data, int dataSize);
/// <summary>Open URL with default system browser (if available)</summary>
/// <summary>Compute SHA256 hash code, returns static int[8] (32 bytes)</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void OpenURL(sbyte* url);
public static partial uint* ComputeSHA256(byte* data, int dataSize);
// Automation events functionality
@ -1031,11 +1082,6 @@ public static unsafe partial class Raylib
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial CBool IsKeyUp(KeyboardKey key);
/// <summary>Set a custom key to exit program (default is ESC)</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void SetExitKey(KeyboardKey key);
/// <summary>
/// Get key pressed (keycode), call it multiple times for keys queued, returns 0 when the queue is empty
/// </summary>
@ -1050,6 +1096,16 @@ public static unsafe partial class Raylib
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial int GetCharPressed();
/// <summary>Get name of a QWERTY key on the current keyboard layout (eg returns string 'q' for KEY_A on an AZERTY keyboard)</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial sbyte* GetKeyName(KeyboardKey key);
/// <summary>Set a custom key to exit program (default is ESC)</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void SetExitKey(KeyboardKey key);
// Input-related functions: gamepads
@ -1398,21 +1454,42 @@ public static unsafe partial class Raylib
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void DrawLineEx(Vector2 startPos, Vector2 endPos, float thick, Color color);
/// <summary>Draw a line using cubic-bezier curves in-out</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void DrawLineBezier(Vector2 startPos, Vector2 endPos, float thick, Color color);
/// <summary>Draw lines sequence</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void DrawLineStrip(Vector2* points, int pointCount, Color color);
/// <summary>Draw a line using cubic-bezier curves in-out</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void DrawLineBezier(Vector2 startPos, Vector2 endPos, float thick, Color color);
/// <summary>Draw a dashed line</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void DrawLineDashed(Vector2 startPos, Vector2 endPos, int dashSize, int spaceSize, Color color);
/// <summary>Draw a color-filled circle</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void DrawCircle(int centerX, int centerY, float radius, Color color);
/// <summary>Draw a color-filled circle (Vector version)</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void DrawCircleV(Vector2 center, float radius, Color color);
/// <summary>Draw a gradient-filled circle</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void DrawCircleGradient(
Vector2 center,
float radius,
Color inner,
Color outer
);
/// <summary>Draw a piece of a circle</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
@ -1437,22 +1514,6 @@ public static unsafe partial class Raylib
Color color
);
/// <summary>Draw a gradient-filled circle</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void DrawCircleGradient(
int centerX,
int centerY,
float radius,
Color inner,
Color outer
);
/// <summary>Draw a color-filled circle (Vector version)</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void DrawCircleV(Vector2 center, float radius, Color color);
/// <summary>Draw circle outline</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
@ -1468,11 +1529,21 @@ public static unsafe partial class Raylib
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void DrawEllipse(int centerX, int centerY, float radiusH, float radiusV, Color color);
/// <summary>Draw ellipse (Vector version)</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void DrawEllipseV(Vector2 center, float radiusH, float radiusV, Color color);
/// <summary>Draw ellipse outline</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void DrawEllipseLines(int centerX, int centerY, float radiusH, float radiusV, Color color);
/// <summary>Draw ellipse outline (Vector version)</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void DrawEllipseLinesV(Vector2 center, float radiusH, float radiusV, Color color);
/// <summary>Draw ring</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
@ -1812,6 +1883,11 @@ public static unsafe partial class Raylib
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial Image LoadImageAnim(sbyte* fileName, int* frames);
/// <summary>Load image sequence from memory buffer</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial Image LoadImageAnimFromMemory(sbyte* fileType, byte* fileData, int dataSize, int* frames);
/// <summary>Load image from memory buffer, fileType refers to extension: i.e. ".png"</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
@ -2372,6 +2448,11 @@ public static unsafe partial class Raylib
// Color/pixel related functions
/// <summary>Check if two colors are equal</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial CBool ColorIsEqual(Color col1, Color col2);
/// <summary>Get hexadecimal value for a Color (0xRRGGBBAA)</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
@ -2613,6 +2694,11 @@ public static unsafe partial class Raylib
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial Vector2 MeasureTextEx(Font font, sbyte* text, float fontSize, float spacing);
/// <summary>Measure string size for Font</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial Vector2 MeasureTextCodepoints(Font font, int* codepoints, int length, float fontSize, float spacing);
/// <summary>
/// Get glyph index position in font for a codepoint (unicode character), fallback to '?' if not found
/// </summary>
@ -2684,8 +2770,21 @@ public static unsafe partial class Raylib
// Text strings management functions (no UTF-8 strings, only byte chars)
// WARNING 1: Most of these functions use internal static buffers[], it's recommended to store returned data on user-side for re-use
// WARNING 2: Some functions allocate memory internally for the returned strings, those strings must be freed by user using MemFree()
// NOTE: Some strings allocate memory internally for returned strings, just be careful!
/// <summary>Load text as separate lines ('\n')</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial sbyte** LoadTextLines(sbyte* text, int* count);
/// <summary>Unload text lines</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void UnloadTextLines(sbyte** text, int* lineCount);
/// <summary>Copy one string to another, returns bytes copied</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
@ -2711,15 +2810,45 @@ public static unsafe partial class Raylib
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial sbyte* TextSubtext(sbyte* text, int position, int length);
/// <summary>Remove text spaces, concat words</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial sbyte* TextRemoveSpaces(sbyte* text);
/// <summary>Get text between two strings</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial sbyte* GetTextBetween(sbyte* text, sbyte* begin, sbyte* end);
/// <summary>Replace text string</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial sbyte* TextReplace(sbyte* text, sbyte* search, sbyte* replacement);
/// <summary>Replace text string (WARNING: memory must be freed!)</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial sbyte* TextReplace(sbyte* text, sbyte* replace, sbyte* by);
public static partial sbyte* TextReplaceAlloc(sbyte* text, sbyte* search, sbyte* replacement);
/// <summary>Replace text between two specific strings</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial sbyte* TextReplaceBetween(sbyte* text, sbyte* start, sbyte* end, sbyte* replacement);
/// <summary>Replace text between two specific strings, (WARNING: memory must be freed!)</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial sbyte* TextReplaceBetweenAlloc(sbyte* text, sbyte* start, sbyte* end, sbyte* replacement);
/// <summary>Insert text in a position</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial sbyte* TextInsert(sbyte* text, sbyte* insert, int position);
/// <summary>Insert text in a position (WARNING: memory must be freed!)</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial sbyte* TextInsert(sbyte* text, sbyte* insert, int position);
public static partial sbyte* TextInsertAlloc(sbyte* text, sbyte* insert, int position);
/// <summary>Join text strings with delimiter</summary>
[LibraryImport(NativeLibName)]
@ -3004,23 +3133,6 @@ public static unsafe partial class Raylib
Color tint
);
/// <summary>Draw a model as points</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void DrawModelPoints(Model model, Vector3 position, float scale, Color tint);
/// <summary>Draw a model as points with extended parameters</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void DrawModelPointsEx(
Model model,
Vector3 position,
Vector3 rotationAxis,
float rotationAngle,
Vector3 scale,
Color tint
);
/// <summary>Draw bounding box (wires)</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
@ -3211,20 +3323,15 @@ public static unsafe partial class Raylib
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial ModelAnimation* LoadModelAnimations(sbyte* fileName, int* animCount);
/// <summary>Update model animation pose (CPU)</summary>
/// <summary>Update model animation pose (vertex buffers and bone matrices)</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void UpdateModelAnimation(Model model, ModelAnimation anim, int frame);
public static partial void UpdateModelAnimation(Model model, ModelAnimation anim, float frame);
/// <summary>Update model animation mesh bone matrices (GPU skinning)</summary>
/// <summary>Update model animation pose, blending two animations</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void UpdateModelAnimationBones(Model model, ModelAnimation anim, int frame);
/// <summary>Unload animation data</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void UnloadModelAnimation(ModelAnimation anim);
public static partial void UpdateModelAnimationEx(Model model, ModelAnimation anim, float frame, ModelAnimation animB, float frameB, float blend);
/// <summary>Unload animation array data</summary>
[LibraryImport(NativeLibName)]
@ -3247,7 +3354,6 @@ public static unsafe partial class Raylib
Vector3 center2,
float radius2
);
/// <summary>Detect collision between two bounding boxes</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
@ -3421,7 +3527,7 @@ public static unsafe partial class Raylib
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void SetSoundPitch(Sound sound, float pitch);
/// <summary>Set pan for a sound (0.5 is center)</summary>
/// <summary>Set pan for a sound (-1.0 left, 0.0 center, 1.0 right)</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void SetSoundPan(Sound sound, float pan);
@ -3518,7 +3624,7 @@ public static unsafe partial class Raylib
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void SetMusicPitch(Music music, float pitch);
/// <summary>Set pan for a music (0.5 is center)</summary>
/// <summary>Set pan for a music (-1.0 left, 0.0 center, 1.0 right)</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void SetMusicPan(Music music, float pan);
@ -3596,7 +3702,7 @@ public static unsafe partial class Raylib
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void SetAudioStreamPitch(AudioStream stream, float pitch);
/// <summary>Set pan for audio stream (0.5 is centered)</summary>
/// <summary>Set pan for audio stream (-1.0 to 1.0 range, 0.0 is centered)</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void SetAudioStreamPan(AudioStream stream, float pan);
@ -3614,7 +3720,7 @@ public static unsafe partial class Raylib
delegate* unmanaged[Cdecl]<void*, uint, void> callback
);
/// <summary>Attach audio stream processor to stream</summary>
/// <summary>Attach audio stream processor to stream, receives frames x 2 samples as 'float' (stereo)</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void AttachAudioStreamProcessor(
@ -3630,7 +3736,7 @@ public static unsafe partial class Raylib
delegate* unmanaged[Cdecl]<void*, uint, void> processor
);
/// <summary>Attach audio stream processor to the entire audio pipeline</summary>
/// <summary>Attach audio stream processor to the entire audio pipeline, receives frames x 2 samples as 'float' (stereo)</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void AttachAudioMixedProcessor(

View file

@ -102,6 +102,11 @@ public static unsafe partial class Raymath
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial float Vector2DotProduct(Vector2 v1, Vector2 v2);
/// <summary>Calculate two vectors cross product</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial float Vector2CrossProduct(Vector2 v1, Vector2 v2);
/// <summary>Calculate distance between two vectors</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
@ -113,8 +118,9 @@ public static unsafe partial class Raymath
public static partial float Vector2DistanceSqr(Vector2 v1, Vector2 v2);
/// <summary>
/// Calculate angle between two vectors
/// NOTE: Angle is calculated from origin point (0, 0)
/// Calculate the signed angle from v1 to v2, relative to the origin (0, 0)
/// NOTE: Coordinate system convention: positive X right, positive Y down
/// positive angles appear clockwise, and negative angles appear counterclockwise
/// </summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
@ -290,7 +296,7 @@ public static unsafe partial class Raymath
/// <summary>Calculate angle between two vectors in XY and XZ</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial Vector2 Vector3Angle(Vector3 v1, Vector3 v2);
public static partial float Vector3Angle(Vector3 v1, Vector3 v2);
/// <summary>Negate provided vector (invert direction)</summary>
[LibraryImport(NativeLibName)]
@ -474,6 +480,13 @@ public static unsafe partial class Raymath
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial Matrix4x4 MatrixMultiply(Matrix4x4 left, Matrix4x4 right);
/// <summary>
/// Multiply matrix components by value
/// </summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial Matrix4x4 MatrixMultiplyValue(Matrix4x4 left, float value);
/// <summary>Get translation matrix</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
@ -698,6 +711,14 @@ public static unsafe partial class Raymath
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial int QuaternionEquals(Quaternion p, Quaternion q);
/// <summary>
/// Compose a transformation matrix from rotational, translational and scaling components
/// TODO: This function is not following raymath conventions defined in header: NOT self-contained
/// </summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial Matrix4x4 MatrixCompose(Vector3 translation, Quaternion rotation, Vector3 scale);
/// <summary>Decompose a transformation matrix into its rotational, translational and scaling components</summary>
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]

View file

@ -382,7 +382,7 @@ public static unsafe partial class Rlgl
/// <summary>Blit active framebuffer to main framebuffer</summary>
[LibraryImport(NativeLibName, EntryPoint = "rlBlitFramebuffer")]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void BlitFramebuffer();
public static partial void BlitFramebuffer(int srcX, int srcY, int srcWidth, int srcHeight, int dstX, int dstY, int dstWidth, int dstHeight, int bufferMask);
/// <summary>Bind framebuffer (FBO)</summary>
[LibraryImport(NativeLibName, EntryPoint = "rlBindFramebuffer")]
@ -462,16 +462,31 @@ public static unsafe partial class Rlgl
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void Scissor(int x, int y, int width, int height);
/// <summary>Enable wire mode</summary>
[LibraryImport(NativeLibName, EntryPoint = "rlEnableWireMode")]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void EnableWireMode();
/// <summary>Enable point mode</summary>
[LibraryImport(NativeLibName, EntryPoint = "rlEnablePointMode")]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void EnablePointMode();
/// <summary>Disable point mode</summary>
[LibraryImport(NativeLibName, EntryPoint = "rlDisablePointMode")]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void DisablePointMode();
/// <summary>Set the point drawing size</summary>
[LibraryImport(NativeLibName, EntryPoint = "rlSetPointSize")]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void SetPointSize(float size);
/// <summary>Get the point drawing size</summary>
[LibraryImport(NativeLibName, EntryPoint = "rlGetPointSize")]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial float GetPointSize();
/// <summary>Enable wire mode</summary>
[LibraryImport(NativeLibName, EntryPoint = "rlEnableWireMode")]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void EnableWireMode();
/// <summary>Disable wire mode</summary>
[LibraryImport(NativeLibName, EntryPoint = "rlDisableWireMode")]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
@ -569,11 +584,26 @@ public static unsafe partial class Rlgl
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void LoadExtensions(void* loader);
/// <summary>Get OpenGL procedure address</summary>
[LibraryImport(NativeLibName, EntryPoint = "rlGetProcAddress")]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void* GetProcAddress(sbyte* procName);
/// <summary>Get current OpenGL version</summary>
[LibraryImport(NativeLibName, EntryPoint = "rlGetVersion")]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial GlVersion GetVersion();
/// <summary>Set current framebuffer width</summary>
[LibraryImport(NativeLibName, EntryPoint = "rlSetFramebufferWidth")]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial int SetFramebufferWidth(int width);
/// <summary>Set current framebuffer height</summary>
[LibraryImport(NativeLibName, EntryPoint = "rlSetFramebufferHeight")]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial int SetFramebufferHeight(int height);
/// <summary>Get default framebuffer width</summary>
[LibraryImport(NativeLibName, EntryPoint = "rlGetFramebufferWidth")]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
@ -811,36 +841,55 @@ public static unsafe partial class Rlgl
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void UnloadFramebuffer(uint id);
/// <summary>Copy framebuffer pixel data to internal buffer</summary>
[LibraryImport(NativeLibName, EntryPoint = "rlCopyFramebuffer")]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void CopyFramebuffer(int x, int y, int width, int height, int format, void* pixels);
/// <summary>Resize internal framebuffer</summary>
[LibraryImport(NativeLibName, EntryPoint = "rlResizeFramebuffer")]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void ResizeFramebuffer(int width, int height);
// Shaders management
/// <summary>Load (compile) shader and return shader id (type: RL_VERTEX_SHADER, RL_FRAGMENT_SHADER, RL_COMPUTE_SHADER)</summary>
[LibraryImport(NativeLibName, EntryPoint = "rlLoadShader")]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial uint LoadShader(sbyte* vsCode, int type);
/// <summary>Load shader from code strings</summary>
[LibraryImport(NativeLibName, EntryPoint = "rlLoadShaderCode")]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial uint LoadShaderCode(sbyte* vsCode, sbyte* fsCode);
/// <summary>Compile custom shader and return shader id<br/>
/// (type: VERTEX_SHADER, FRAGMENT_SHADER, COMPUTE_SHADER)</summary>
[LibraryImport(NativeLibName, EntryPoint = "rlCompileShader")]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial uint CompileShader(sbyte* shaderCode, int type);
/// <summary>Load custom shader program</summary>
[LibraryImport(NativeLibName, EntryPoint = "rlLoadShaderProgram")]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial uint LoadShaderProgram(uint vShaderId, uint fShaderId);
public static partial uint LoadShaderProgram(sbyte* vsCode, sbyte* fsCode);
/// <summary>Load shader program, using already loaded shader ids</summary>
[LibraryImport(NativeLibName, EntryPoint = "rlLoadShaderProgramEx")]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial uint LoadShaderProgramEx(uint vsId, uint fsId);
/// <summary>Load compute shader program</summary>
[LibraryImport(NativeLibName, EntryPoint = "rlLoadShaderProgramCompute")]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial uint LoadShaderProgramCompute(uint csId);
/// <summary>Unload shader, loaded with LoadShader()</summary>
[LibraryImport(NativeLibName, EntryPoint = "rlUnloadShader")]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void UnloadShader(uint id);
/// <summary>Unload shader program</summary>
[LibraryImport(NativeLibName, EntryPoint = "rlUnloadShaderProgram")]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void UnloadShaderProgram(uint id);
/// <summary>Get shader location uniform</summary>
/// <summary>Get shader location uniform, requires shader program id</summary>
[LibraryImport(NativeLibName, EntryPoint = "rlGetLocationUniform")]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial int GetLocationUniform(uint shaderId, sbyte* uniformName);
/// <summary>Get shader location attribute</summary>
/// <summary>Get shader location attribute, requires shader program id</summary>
[LibraryImport(NativeLibName, EntryPoint = "rlGetLocationAttrib")]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial int GetLocationAttrib(uint shaderId, sbyte* attribName);
@ -873,11 +922,6 @@ public static unsafe partial class Rlgl
// Compute shader management
/// <summary>Load compute shader program</summary>
[LibraryImport(NativeLibName, EntryPoint = "rlLoadComputeShaderProgram")]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial uint LoadComputeShaderProgram(uint shaderId);
/// <summary>Dispatch compute shader (equivalent to *draw* for graphics pilepine)</summary>
[LibraryImport(NativeLibName, EntryPoint = "rlComputeShaderDispatch")]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
@ -976,12 +1020,12 @@ public static unsafe partial class Rlgl
/// <summary>Set eyes projection matrices for stereo rendering</summary>
[LibraryImport(NativeLibName, EntryPoint = "rlSetMatrixProjectionStereo")]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void SetMatrixProjectionStereo(Matrix4x4 left, Matrix4x4 right);
public static partial void SetMatrixProjectionStereo(Matrix4x4 right, Matrix4x4 left);
/// <summary>Set eyes view offsets matrices for stereo rendering</summary>
[LibraryImport(NativeLibName, EntryPoint = "rlSetMatrixViewOffsetStereo")]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial void SetMatrixViewOffsetStereo(Matrix4x4 left, Matrix4x4 right);
public static partial void SetMatrixViewOffsetStereo(Matrix4x4 right, Matrix4x4 left);
// Quick and dirty cube/quad buffers load->draw->unload

View file

@ -181,7 +181,22 @@ public unsafe struct Mesh
#endregion
#region Animation vertex data
#region Skin data for animation
/// <summary>
/// Number of bones (MAX: 256 bones)
/// </summary>
public int BoneCount;
/// <summary>
/// Vertex bone indices, up to 4 bones influence by vertex (skinning) (shader-location = 6)
/// </summary>
public byte* BoneIndices = default;
/// <summary>
/// Vertex bone weight, up to 4 bones influence by vertex (skinning) (shader-location = 7)
/// </summary>
public float* BoneWeights = default;
/// <summary>
/// Animated vertex positions (after bones transformations)
@ -193,26 +208,6 @@ public unsafe struct Mesh
/// </summary>
public float* AnimNormals = default;
/// <summary>
/// Vertex bone ids, up to 4 bones influence by vertex (skinning)
/// </summary>
public byte* BoneIds = default;
/// <summary>
/// Vertex bone weight, up to 4 bones influence by vertex (skinning)
/// </summary>
public float* BoneWeights = default;
/// <summary>
/// Bones animated transformation matrices
/// </summary>
public Matrix4x4* BoneMatrices = default;
/// <summary>
/// Number of bones
/// </summary>
public int BoneCount;
#endregion
#region OpenGL identifiers
@ -223,7 +218,7 @@ public unsafe struct Mesh
public uint VaoId = default;
/// <summary>
/// OpenGL Vertex Buffer Objects id (default vertex data, uint[])
/// OpenGL Vertex Buffer Objects id (default vertex data)
/// </summary>
public uint* VboId = default;
@ -263,4 +258,6 @@ public unsafe struct Mesh
public const int VboIdIndexIndices = 6;
#endregion
}

View file

@ -19,8 +19,65 @@ public unsafe struct BoneInfo
/// Bone parent
/// </summary>
public int Parent;
/// <summary>
/// Bone name as string
/// </summary>
public string NameToString()
{
fixed (sbyte* name = Name)
{
return Utf8StringUtils.GetUTF8String(name);
}
}
}
/// <summary>
/// Skeleton, animation bones hierarchy
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public unsafe struct ModelSkeleton
{
/// <summary>
/// Number of bones
/// </summary>
public int BoneCount;
/// <summary>
/// Bones information (skeleton)
/// </summary>
public BoneInfo* Bones;
/// <summary>
/// Bones base transformation (Transform[])
/// </summary>
public Transform* BindPose;
public Span<Transform> BindPoseAsSpan()
{
if (BindPose == null || BoneCount <= 0)
{
return Span<Transform>.Empty;
}
return new Span<Transform>(BindPose, BoneCount);
}
public Span<BoneInfo> BonesAsSpan()
{
if (Bones == null || BoneCount <= 0)
{
return Span<BoneInfo>.Empty;
}
return new Span<BoneInfo>(Bones, BoneCount);
}
}
// Note:
// Anim pose, an array of Transform[]
// typedef Transform *ModelAnimPose; It's just a pointer array.
/// <summary>
/// Model type
/// </summary>
@ -58,92 +115,128 @@ public unsafe struct Model
public int* MeshMaterial;
/// <summary>
/// Number of bones
/// Skeleton for animation
/// </summary>
public int BoneCount;
public ModelSkeleton Skeleton;
//TODO: Span
/// <summary>
/// Bones information (skeleton, BoneInfo *)
/// Current animation pose (Transform[])
/// </summary>
public BoneInfo* Bones;
public Transform* CurrentPose;
//TODO: Span
/// <summary>
/// Bones base transformation (pose, Transform *)
/// Bones animated transformation matrices
/// </summary>
public Transform* BindPose;
public Matrix4x4* BoneMatrices;
/// <summary>
/// Bones animated transformation matrices as span. Based on Skeleton.BoneCount length
/// </summary>
public Span<Matrix4x4> BoneMatricesAsSpan()
{
if (BoneMatrices == null || Skeleton.BoneCount <= 0)
{
return Span<Matrix4x4>.Empty;
}
return new Span<Matrix4x4>(BoneMatrices, Skeleton.BoneCount);
}
/// <summary>
/// Current animation pose as span. Based on Skeleton.BoneCount length
/// </summary>
public Span<Transform> CurrentPoseAsSpan()
{
if (CurrentPose == null || Skeleton.BoneCount <= 0)
{
return Span<Transform>.Empty;
}
return new Span<Transform>(CurrentPose, Skeleton.BoneCount);
}
/// <summary>
/// Mesh material number as span. Based on MaterialCount length
/// </summary>
public Span<int> MeshMaterialAsSpan()
{
if (MeshMaterial == null || MaterialCount <= 0)
{
return Span<int>.Empty;
}
return new Span<int>(MeshMaterial, MaterialCount);
}
/// <summary>
/// Meshes as span. Based on MeshCount length
/// </summary>
public Span<Mesh> MeshesAsSpan()
{
if (Meshes == null || MeshCount <= 0)
{
return Span<Mesh>.Empty;
}
return new Span<Mesh>(Meshes, MeshCount);
}
}
/// <summary>
/// Model animation
/// ModelAnimation, contains a full animation sequence
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public unsafe struct ModelAnimation
{
/// <summary>
/// Animation name (char[32])
/// </summary>
public fixed sbyte Name[32];
/// <summary>
/// Number of bones
/// </summary>
public readonly int BoneCount;
/// <summary>
/// Number of animation frames
/// Number of animation key frames
/// </summary>
public readonly int FrameCount;
public readonly int KeyFrameCount;
/// <summary>
/// Bones information (skeleton, BoneInfo *)
/// Animation sequence keyframe poses [keyframe][pose]
/// </summary>
public readonly BoneInfo* Bones;
public Transform** KeyframePoses;
/// <inheritdoc cref="Bones"/>
public readonly ReadOnlySpan<BoneInfo> BoneInfo => new ReadOnlySpan<BoneInfo>(Bones, BoneCount);
/// <summary>
/// Poses array by frame (Transform **)
/// Animation sequence keyframe poses as span. Based on KeyFrameCount length
/// </summary>
public readonly Transform** FramePoses;
/// <summary>
/// Animation name (char[32])
/// </summary>
public fixed sbyte Name[32];
/// <inheritdoc cref="FramePoses"/>
public readonly FramePosesCollection FramePosesColl => new FramePosesCollection(FramePoses, FrameCount, BoneCount);
public readonly struct FramePosesCollection
public Span<Transform> GetKeyFramePoseAsSpan(int frame)
{
readonly Transform** _framePoses;
readonly int _frameCount;
readonly int _boneCount;
public readonly FramePoses this[int index] => new FramePoses(_framePoses[index], _boneCount);
public readonly Transform this[int index1, int index2] => new FramePoses(_framePoses[index1], _boneCount)[index2];
internal FramePosesCollection(Transform** framePoses, int frameCount, int boneCount)
if (KeyframePoses == null || frame < 0 || frame >= KeyFrameCount)
{
this._framePoses = framePoses;
this._frameCount = frameCount;
this._boneCount = boneCount;
return Span<Transform>.Empty;
}
var pose = KeyframePoses[frame];
if (pose == null || BoneCount <= 0)
{
return Span<Transform>.Empty;
}
return new Span<Transform>(KeyframePoses[frame], KeyFrameCount);
}
/// <summary>
/// Animation name as string
/// </summary>
public string NameToString()
{
fixed (sbyte* name = Name)
{
return Utf8StringUtils.GetUTF8String(name);
}
}
}
public readonly unsafe struct FramePoses
{
readonly Transform* _poses;
readonly int _count;
public readonly ref Transform this[int index] => ref _poses[index];
internal FramePoses(Transform* poses, int count)
{
this._poses = poses;
this._count = count;
}
}

View file

@ -20,6 +20,20 @@ public static unsafe partial class Raylib
SetWindowTitle(str1.AsPointer());
}
/// <summary>Set icon for window (multiple images, RGBA 32bit)</summary>
public static void SetWindowIcons(Image[] images)
{
if (images == null || images.Length == 0)
{
return;
}
fixed (Image* imagesPtr = images)
{
SetWindowIcons(imagesPtr, images.Length);
}
}
/// <summary>Get the human-readable, UTF-8 encoded name of the specified monitor</summary>
public static string GetMonitorName_(int monitor)
{
@ -102,7 +116,7 @@ public static unsafe partial class Raylib
public static long GetFileModTime(string fileName)
{
using AnsiBuffer str1 = fileName.ToAnsiBuffer();
return GetFileModTime(str1.AsPointer());
return GetFileModTime(str1.AsPointer()).Value;
}
/// <summary>Load image from file into CPU memory (RAM)</summary>
@ -112,6 +126,19 @@ public static unsafe partial class Raylib
return LoadImage(str1.AsPointer());
}
/// <summary>Load image sequence from memory buffer</summary>
public static Image LoadImageAnimFromMemory(string fileType, byte[] fileData, out int frames)
{
using AnsiBuffer type = fileType.ToAnsiBuffer();
fixed (byte* data = fileData)
{
int frameCount;
var result = LoadImageAnimFromMemory(type.AsPointer(), data, fileData.Length, &frameCount);
frames = frameCount;
return result;
}
}
/// <summary>Load image from RAW file data</summary>
public static Image LoadImageRaw(string fileName, int width, int height, PixelFormat format, int headerSize)
{
@ -192,7 +219,7 @@ public static unsafe partial class Raylib
/// <summary>Set shader uniform value</summary>
public static void SetShaderValue<T>(Shader shader, int locIndex, T value, ShaderUniformDataType uniformType)
where T : unmanaged
where T : unmanaged
{
SetShaderValue(shader, locIndex, &value, uniformType);
}
@ -244,6 +271,7 @@ public static unsafe partial class Raylib
{
return false;
}
fixed (T* ptr = data)
{
using AnsiBuffer ansiBuffer = fileName.ToAnsiBuffer();
@ -251,6 +279,16 @@ public static unsafe partial class Raylib
}
}
/// <summary>Export data to code (.h), returns true on success</summary>
public static CBool ExportDataAsCode(byte[] data, string fileName)
{
fixed (byte* ptr = data)
{
using AnsiBuffer name = fileName.ToAnsiBuffer();
return ExportDataAsCode(ptr, data.Length, name.AsPointer());
}
}
/// <summary>Load file data as byte array (read)</summary>
public static byte* LoadFileData(string fileName, ref int bytesRead)
{
@ -265,6 +303,13 @@ public static unsafe partial class Raylib
{
int length = 0;
byte* data = LoadFileData(fileName, ref length);
if (data == null)
{
return Array.Empty<byte>();
}
byte[] arr = new byte[length];
Marshal.Copy((IntPtr)data, arr, 0, length);
UnloadFileData(data);
@ -294,6 +339,7 @@ public static unsafe partial class Raylib
{
files[i] = filePathList[i];
}
UnloadDroppedFiles(filePathList);
return files;
@ -409,7 +455,7 @@ public static unsafe partial class Raylib
CBool lockView,
CBool rotateAroundTarget,
CBool rotateUp
)
)
{
fixed (Camera3D* c = &camera)
{
@ -866,7 +912,8 @@ public static unsafe partial class Raylib
}
/// <summary>Draw triangle with interpolated colors within an image</summary>
public static void ImageDrawTriangleEx(ref Image dst, Vector2 v1, Vector2 v2, Vector2 v3, Color c1, Color c2, Color c3)
public static void ImageDrawTriangleEx(ref Image dst, Vector2 v1, Vector2 v2, Vector2 v3, Color c1, Color c2,
Color c3)
{
fixed (Image* p = &dst)
{
@ -1085,6 +1132,24 @@ public static unsafe partial class Raylib
}
}
/// <summary>Load model animations from file</summary>
public static Span<ModelAnimation> LoadModelAnimations(string fileName)
{
using AnsiBuffer str1 = fileName.ToAnsiBuffer();
int count;
ModelAnimation* result = LoadModelAnimations(str1.AsPointer(), &count);
return new Span<ModelAnimation>(result, count);
}
public static void UnloadModelAnimations(Span<ModelAnimation> animations)
{
fixed (ModelAnimation* ptr = animations)
{
UnloadModelAnimations(ptr, animations.Length);
}
}
/// <summary>Compute mesh tangents</summary>
public static void GenMeshTangents(ref Mesh mesh)
{
@ -1094,6 +1159,33 @@ public static unsafe partial class Raylib
}
}
/// <summary>Update sound buffer with new data</summary>
public static void UpdateSound<T>(Sound sound, ReadOnlySpan<T> data, int sampleCount) where T : unmanaged
{
fixed (T* dataPtr = data)
{
UpdateSound(sound, dataPtr, sampleCount);
}
}
/// <summary>Update sound buffer with new data</summary>
public static void UpdateSound<T>(Sound sound, ReadOnlySpan<T> data) where T : unmanaged
{
fixed (T* dataPtr = data)
{
UpdateSound(sound, dataPtr, data.Length);
}
}
/// <summary>Update audio stream buffers with data</summary>
public static void UpdateAudioStream<T>(AudioStream sound, ReadOnlySpan<T> data, int frameCount) where T : unmanaged
{
fixed (T* dataPtr = data)
{
UpdateAudioStream(sound, dataPtr, frameCount);
}
}
/// <summary>Convert wave data to desired format</summary>
public static void WaveFormat(ref Wave wave, int sampleRate, int sampleSize, int channels)
{
@ -1214,6 +1306,33 @@ public static unsafe partial class Raylib
DrawTextPro(font, str1.AsPointer(), position, origin, rotation, fontSize, spacing, tint);
}
/// <summary>Draw multiple characters (codepoint)</summary>
public static void DrawTextCodepoints(
Font font,
int[] codepoints,
Vector2 position,
float fontSize,
float spacing,
Color tint
)
{
fixed (int* codepointsPtr = codepoints)
{
DrawTextCodepoints(font, codepointsPtr, codepoints.Length, position, fontSize, spacing, tint);
}
}
/// <summary>Measure string size for Font</summary>
public static Vector2 MeasureTextCodepoints(
Font font, int[] codepoints, float fontSize, float spacing
)
{
fixed (int* codepointsPtr = codepoints)
{
return MeasureTextCodepoints(font, codepointsPtr, codepoints.Length, fontSize, spacing);
}
}
/// <summary>Measure string width for default font</summary>
public static int MeasureText(string text, int fontSize)
{
@ -1484,12 +1603,12 @@ public static unsafe partial class Raylib
public static string GetApplicationDirectoryString()
{
return new string(GetApplicationDirectory());
return Utf8StringUtils.GetUTF8String(GetApplicationDirectory());
}
public static string GetWorkingDirectoryString()
{
return new string(GetWorkingDirectory());
return Utf8StringUtils.GetUTF8String(GetWorkingDirectory());
}
/// <summary>
@ -1511,6 +1630,7 @@ public static unsafe partial class Raylib
{
output[i] = sequence[i];
}
UnloadRandomSequence(sequence);
return output;
}
@ -1536,6 +1656,7 @@ public static unsafe partial class Raylib
float norm = (float)val / (float)maxi;
output[i] = Raymath.Lerp(min, max, norm);
}
return output;
}
@ -1549,6 +1670,373 @@ public static unsafe partial class Raylib
SaveFileText(fileBuffer.AsPointer(), textBuffer.AsPointer());
}
/// <summary>Rename file (if exists)</summary>
public static int FileRename(string filename, string fileRename)
{
using AnsiBuffer fileBuffer = filename.ToAnsiBuffer();
using AnsiBuffer textBuffer = fileRename.ToAnsiBuffer();
return FileRename(fileBuffer.AsPointer(), textBuffer.AsPointer());
}
/// <summary>Remove file (if exists)</summary>
public static int FileRemove(string filename)
{
using AnsiBuffer fileBuffer = filename.ToAnsiBuffer();
return FileRemove(fileBuffer.AsPointer());
}
/// <summary>Copy file from one path to another, dstPath created if it doesn't exist</summary>
public static int FileCopy(string srcPath, string dstPath)
{
using AnsiBuffer srcBuffer = srcPath.ToAnsiBuffer();
using AnsiBuffer dstBuffer = dstPath.ToAnsiBuffer();
return FileCopy(srcBuffer.AsPointer(), dstBuffer.AsPointer());
}
/// <summary>Move file from one path to another, dstPath created if it doesn't exist</summary>
public static int FileMove(string srcPath, string dstPath)
{
using AnsiBuffer srcBuffer = srcPath.ToAnsiBuffer();
using AnsiBuffer dstBuffer = dstPath.ToAnsiBuffer();
return FileMove(srcBuffer.AsPointer(), dstBuffer.AsPointer());
}
/// <summary>Replace text in an existing file</summary>
public static int FileTextReplace(string fileName, string search, string replacement)
{
using AnsiBuffer fileBuffer = fileName.ToAnsiBuffer();
using AnsiBuffer searchBuffer = search.ToAnsiBuffer();
using AnsiBuffer replaceBuffer = replacement.ToAnsiBuffer();
return FileTextReplace(fileBuffer.AsPointer(), searchBuffer.AsPointer(), replaceBuffer.AsPointer());
}
/// <summary>Find text in existing file</summary>
public static int FileTextFindIndex(string fileName, string search)
{
using AnsiBuffer fileBuffer = fileName.ToAnsiBuffer();
using AnsiBuffer searchBuffer = search.ToAnsiBuffer();
return FileTextFindIndex(fileBuffer.AsPointer(), searchBuffer.AsPointer());
}
/// <summary>Check if file exists</summary>
public static CBool FileExists(string fileName)
{
using AnsiBuffer fileBuffer = fileName.ToAnsiBuffer();
return FileExists(fileBuffer.AsPointer());
}
/// <summary>Check if a directory path exists</summary>
public static CBool DirectoryExists(string dirPath)
{
using AnsiBuffer dirBuffer = dirPath.ToAnsiBuffer();
return DirectoryExists(dirBuffer.AsPointer());
}
/// <summary>Get file length in bytes</summary>
public static int GetFileLength(string fileName)
{
using AnsiBuffer fileBuffer = fileName.ToAnsiBuffer();
return GetFileLength(fileBuffer.AsPointer());
}
/// <summary>Get string to extension for a filename string (includes dot: '.png')</summary>
public static string GetFileExtension(string fileName)
{
using AnsiBuffer fileBuffer = fileName.ToAnsiBuffer();
return Utf8StringUtils.GetUTF8String(GetFileExtension(fileBuffer.AsPointer()));
}
/// <summary>Get string to filename for a path string</summary>
public static string GetFileName(string fileName)
{
using AnsiBuffer fileBuffer = fileName.ToAnsiBuffer();
return Utf8StringUtils.GetUTF8String(GetFileName(fileBuffer.AsPointer()));
}
/// <summary>Get filename string without extension </summary>
public static string GetFileNameWithoutExt(string fileName)
{
using AnsiBuffer fileBuffer = fileName.ToAnsiBuffer();
return Utf8StringUtils.GetUTF8String(GetFileNameWithoutExt(fileBuffer.AsPointer()));
}
/// <summary>Get full path for a given fileName with path</summary>
public static string GetDirectoryPath(string filePath)
{
using AnsiBuffer fileBuffer = filePath.ToAnsiBuffer();
return Utf8StringUtils.GetUTF8String(GetDirectoryPath(fileBuffer.AsPointer()));
}
/// <summary>Get previous directory path for a given path</summary>
public static string GetPrevDirectoryPath(string dirPath)
{
using AnsiBuffer dirBuffer = dirPath.ToAnsiBuffer();
return Utf8StringUtils.GetUTF8String(GetPrevDirectoryPath(dirBuffer.AsPointer()));
}
/// <summary>Get current working directory</summary>
public static string GetWorkingDirectoryAsString()
{
return Utf8StringUtils.GetUTF8String(GetWorkingDirectory());
}
/// <summary>Get the directory of the running application</summary>
public static string GetApplicationDirectoryAsString()
{
return Utf8StringUtils.GetUTF8String(GetApplicationDirectory());
}
/// <summary>Change working directory, return true on success</summary>
public static CBool ChangeDirectory(string dirPath)
{
using AnsiBuffer dirBuffer = dirPath.ToAnsiBuffer();
return ChangeDirectory(dirBuffer.AsPointer());
}
/// <summary>Check if a given path is a file or a directory</summary>
public static CBool IsPathFile(string path)
{
using AnsiBuffer pathBuffer = path.ToAnsiBuffer();
return IsPathFile(pathBuffer.AsPointer());
}
/// <summary>Load directory filepaths</summary>
public static FilePathList LoadDirectoryFiles(string dirPath)
{
using AnsiBuffer dirBuffer = dirPath.ToAnsiBuffer();
return LoadDirectoryFiles(dirBuffer.AsPointer());
}
/// <summary>Get the file count in a directory</summary>
public static int GetDirectoryFileCount(string dirPath)
{
using AnsiBuffer dirBuffer = dirPath.ToAnsiBuffer();
return GetDirectoryFileCount(dirBuffer.AsPointer());
}
/// <summary>Get the file count in a directory with extension filtering and recursive directory scan. Use 'DIR' in the filter string to include directories in the result</summary>
public static int GetDirectoryFileCountEx(string dirPath, string filter, CBool scanSubdirs)
{
using AnsiBuffer dirBuffer = dirPath.ToAnsiBuffer();
using AnsiBuffer filterBuffer = filter.ToAnsiBuffer();
return GetDirectoryFileCountEx(dirBuffer.AsPointer(), filterBuffer.AsPointer(), scanSubdirs);
}
/// <summary>Load directory filepaths with extension filtering and subdir scan; some filters available: "*.*", "FILES*", "DIRS*"</summary>
public static FilePathList LoadDirectoryFilesEx(string basePath, string filter, CBool scanSubDirs)
{
using AnsiBuffer baseBuffer = basePath.ToAnsiBuffer();
using AnsiBuffer filterBuffer = filter.ToAnsiBuffer();
return LoadDirectoryFilesEx(baseBuffer.AsPointer(), filterBuffer.AsPointer(), scanSubDirs);
}
/// <summary>Compress data (DEFLATE algorithm)</summary>
public static byte[] CompressData(byte[] data)
{
fixed (byte* dataPtr = data)
{
int compressedSize;
var compressedPtr = CompressData(dataPtr, data.Length, &compressedSize);
if (compressedPtr == null || compressedSize <= 0)
{
return Array.Empty<byte>();
}
try
{
var result = new byte[compressedSize];
fixed (byte* resultPtr = result)
{
Buffer.MemoryCopy(
compressedPtr,
resultPtr,
compressedSize,
compressedSize
);
}
return result;
}
finally
{
MemFree(compressedPtr);
}
}
}
/// <summary>Decompress data (DEFLATE algorithm)</summary>
public static byte[] DecompressData(byte[] data)
{
fixed (byte* dataPtr = data)
{
int dataSize;
var compressedPtr = DecompressData(dataPtr, data.Length, &dataSize);
if (compressedPtr == null || dataSize <= 0)
{
return Array.Empty<byte>();
}
try
{
var result = new byte[dataSize];
fixed (byte* resultPtr = result)
{
Buffer.MemoryCopy(
compressedPtr,
resultPtr,
dataSize,
dataSize
);
}
return result;
}
finally
{
MemFree(compressedPtr);
}
}
}
/// <summary>Encode data to Base64 string</summary>
public static byte[] EncodeDataBase64(byte[] data)
{
fixed (byte* dataPtr = data)
{
int outputSize;
var compressedPtr = EncodeDataBase64(dataPtr, data.Length, &outputSize);
if (compressedPtr == null || outputSize <= 0)
{
return Array.Empty<byte>();
}
try
{
var result = new byte[outputSize];
fixed (byte* resultPtr = result)
{
Buffer.MemoryCopy(
compressedPtr,
resultPtr,
outputSize,
outputSize
);
}
return result;
}
finally
{
MemFree(compressedPtr);
}
}
}
/// <summary>Decode data to Base64 string</summary>
public static byte[] DecodeDataBase64(string data)
{
using Utf8Buffer ptr = data.ToUtf8Buffer();
int outputSize;
var compressedPtr = DecodeDataBase64(ptr.AsPointer(), &outputSize);
if (compressedPtr == null || outputSize <= 0)
{
return Array.Empty<byte>();
}
try
{
var result = new byte[outputSize];
fixed (byte* resultPtr = result)
{
Buffer.MemoryCopy(
compressedPtr,
resultPtr,
outputSize,
outputSize
);
}
return result;
}
finally
{
MemFree(compressedPtr);
}
}
/// <summary>Compute CRC32 hash code</summary>
public static uint ComputeCRC32(byte[] data)
{
fixed (byte* dataPtr = data)
{
return ComputeCRC32(dataPtr, data.Length);
}
}
/// <summary>Compute MD5 hash code, returns uint[4] array</summary>
public static uint[] ComputeMD5(byte[] data)
{
fixed (byte* dataPtr = data)
{
var result = ComputeMD5(dataPtr, data.Length);
return
[
result[0],
result[1],
result[2],
result[3],
];
}
}
/// <summary>Compute SHA1 hash code, returns uint[5] array</summary>
public static uint[] ComputeSHA1(byte[] data)
{
fixed (byte* dataPtr = data)
{
var result = ComputeSHA1(dataPtr, data.Length);
return
[
result[0],
result[1],
result[2],
result[3],
result[4],
];
}
}
/// <summary>Compute SHA256 hash code, returns int[8] (32 bytes)</summary>
public static uint[] ComputeSHA256(byte[] data)
{
fixed (byte* dataPtr = data)
{
var result = ComputeSHA256(dataPtr, data.Length);
return
[
result[0],
result[1],
result[2],
result[3],
result[4],
result[5],
result[6],
result[7],
];
}
}
/// <summary>
/// Loads text from a file, reads it, saves it, unloads the file, and returns the loaded text.
/// </summary>
@ -1569,4 +2057,5 @@ public static unsafe partial class Raylib
center.Y = GetScreenHeight() / 2.0f;
return center;
}
}

View file

@ -35,7 +35,8 @@ public enum ShaderLocationIndex
MapBrdf,
VertexBoneIds,
VertexBoneWeights,
BoneMatrices,
MatrixBoneTransforms,
VertexInstanceTransform,
MapDiffuse = MapAlbedo,
MapSpecular = MapMetalness,

View file

@ -1,3 +1,4 @@
using System;
using System.Runtime.InteropServices;
namespace Raylib_cs;
@ -8,11 +9,6 @@ namespace Raylib_cs;
[StructLayout(LayoutKind.Sequential)]
public unsafe struct FilePathList
{
/// <summary>
/// Filepaths max entries
/// </summary>
public uint Capacity;
/// <summary>
/// Filepaths entries count
/// </summary>

View file

@ -21,6 +21,11 @@ public readonly ref struct Utf8Buffer
return (sbyte*)_data.ToPointer();
}
public unsafe byte* AsBytePointer()
{
return (byte*)_data.ToPointer();
}
public void Dispose()
{
Marshal.ZeroFreeCoTaskMemUTF8(_data);