raylib-zig/inject.zig
2024-02-10 19:13:34 +02:00

1000 lines
28 KiB
Zig

const std = @import("std");
const raylib = @cImport({
@cInclude("raylib.h");
@cDefine("GRAPHICS_API_OPENGL_11", {});
// @cDefine("RLGL_IMPLEMENTATION", {});
@cInclude("rlgl.h");
@cDefine("RAYMATH_IMPLEMENTATION", {});
@cInclude("raymath.h");
@cInclude("marshal.h");
});
//--- structs -------------------------------------------------------------------------------------
/// System/Window config flags
pub const ConfigFlags = packed struct(u32) {
FLAG_UNKNOWN_1: bool = false, // 0x0001
/// Set to run program in fullscreen
FLAG_FULLSCREEN_MODE: bool = false, // 0x0002,
/// Set to allow resizable window
FLAG_WINDOW_RESIZABLE: bool = false, // 0x0004,
/// Set to disable window decoration (frame and buttons)
FLAG_WINDOW_UNDECORATED: bool = false, // 0x0008,
/// Set to allow transparent framebuffer
FLAG_WINDOW_TRANSPARENT: bool = false, // 0x0010,
/// Set to try enabling MSAA 4X
FLAG_MSAA_4X_HINT: bool = false, // 0x0020,
/// Set to try enabling V-Sync on GPU
FLAG_VSYNC_HINT: bool = false, // 0x0040,
/// Set to hide window
FLAG_WINDOW_HIDDEN: bool = false, // 0x0080,
/// Set to allow windows running while minimized
FLAG_WINDOW_ALWAYS_RUN: bool = false, // 0x0100,
/// Set to minimize window (iconify)
FLAG_WINDOW_MINIMIZED: bool = false, // 0x0200,
/// Set to maximize window (expanded to monitor)
FLAG_WINDOW_MAXIMIZED: bool = false, // 0x0400,
/// Set to window non focused
FLAG_WINDOW_UNFOCUSED: bool = false, // 0x0800,
/// Set to window always on top
FLAG_WINDOW_TOPMOST: bool = false, // 0x1000,
/// Set to support HighDPI
FLAG_WINDOW_HIGHDPI: bool = false, // 0x2000,
/// Set to support mouse passthrough, only supported when FLAG_WINDOW_UNDECORATED
FLAG_WINDOW_MOUSE_PASSTHROUGH: bool = false, // 0x4000,
FLAG_UNKNOWN_2: bool = false, // 0x8000
/// Set to try enabling interlaced video format (for V3D)
FLAG_INTERLACED_HINT: bool = false, // 0x10000
FLAG_PADDING: u15 = 0, // 0xFFFE0000
};
/// Transform, vectex transformation data
pub const Transform = extern struct {
/// Translation
translation: Vector3,
/// Rotation
rotation: Vector4,
/// Scale
scale: Vector3,
};
/// Matrix, 4x4 components, column major, OpenGL style, right handed
pub const Matrix = extern struct {
/// Matrix first row (4 components) [m0, m4, m8, m12]
m0: f32,
m4: f32,
m8: f32,
m12: f32,
/// Matrix second row (4 components) [m1, m5, m9, m13]
m1: f32,
m5: f32,
m9: f32,
m13: f32,
/// Matrix third row (4 components) [m2, m6, m10, m14]
m2: f32,
m6: f32,
m10: f32,
m14: f32,
/// Matrix fourth row (4 components) [m3, m7, m11, m15]
m3: f32,
m7: f32,
m11: f32,
m15: f32,
pub fn zero() @This() {
return @This(){
.m0 = 0,
.m1 = 0,
.m2 = 0,
.m3 = 0,
.m4 = 0,
.m5 = 0,
.m6 = 0,
.m7 = 0,
.m8 = 0,
.m9 = 0,
.m10 = 0,
.m11 = 0,
.m12 = 0,
.m13 = 0,
.m14 = 0,
.m15 = 0,
};
}
pub fn identity() @This() {
return MatrixIdentity();
}
};
pub const Rectangle = extern struct {
x: f32 = 0,
y: f32 = 0,
width: f32 = 0,
height: f32 = 0,
pub fn toI32(self: @This()) RectangleI {
return .{
.x = @as(i32, @intFromFloat(self.x)),
.y = @as(i32, @intFromFloat(self.y)),
.width = @as(i32, @intFromFloat(self.width)),
.height = @as(i32, @intFromFloat(self.height)),
};
}
pub fn pos(self: @This()) Vector2 {
return .{
.x = self.x,
.y = self.y,
};
}
pub fn size(self: @This()) Vector2 {
return .{
.x = self.width,
.y = self.height,
};
}
pub fn topLeft(self: @This()) Vector2 {
return .{
.x = self.x,
.y = self.y,
};
}
pub fn topCenter(self: @This()) Vector2 {
return .{
.x = self.x + self.width / 2,
.y = self.y,
};
}
pub fn topRight(self: @This()) Vector2 {
return .{
.x = self.x + self.width,
.y = self.y,
};
}
pub fn centerLeft(self: @This()) Vector2 {
return .{
.x = self.x,
.y = self.y + self.height / 2,
};
}
pub fn center(self: @This()) Vector2 {
return .{
.x = self.x + self.width / 2,
.y = self.y + self.height / 2,
};
}
pub fn centerRight(self: @This()) Vector2 {
return .{
.x = self.x + self.width,
.y = self.y + self.height / 2,
};
}
pub fn bottomLeft(self: @This()) Vector2 {
return .{
.x = self.x + 0,
.y = self.y + self.height,
};
}
pub fn bottomCenter(self: @This()) Vector2 {
return .{
.x = self.x + self.width / 2,
.y = self.y + self.height,
};
}
pub fn bottomRight(self: @This()) Vector2 {
return .{
.x = self.x + self.width,
.y = self.y + self.height,
};
}
pub fn area(self: @This()) f32 {
return self.width * self.height;
}
pub fn include(self: @This(), other: @This()) @This() {
return self.includePoint(other.topLeft()).includePoint(other.bottomRight());
}
pub fn includePoint(self: @This(), point: Vector2) @This() {
const minX = @min(self.x, point.x);
const minY = @min(self.y, point.y);
const maxX = @max(self.x + self.width, point.x);
const maxY = @max(self.y + self.height, point.y);
return .{
.x = minX,
.y = minY,
.width = maxX - minX,
.height = maxY - minY,
};
}
};
pub const RectangleI = extern struct {
x: i32 = 0,
y: i32 = 0,
width: i32 = 0,
height: i32 = 0,
pub fn toF32(self: @This()) Rectangle {
return .{
.x = @as(f32, @floatFromInt(self.x)),
.y = @as(f32, @floatFromInt(self.y)),
.width = @as(f32, @floatFromInt(self.width)),
.height = @as(f32, @floatFromInt(self.height)),
};
}
pub fn pos(self: @This()) Vector2i {
return .{
.x = self.x,
.y = self.y,
};
}
};
pub const Vector2 = extern struct {
x: f32 = 0,
y: f32 = 0,
pub fn zero() @This() {
return .{ .x = 0, .y = 0 };
}
pub fn setZero(self: *@This()) void {
self.x = 0;
self.y = 0;
}
pub fn one() @This() {
return @This(){ .x = 1, .y = 1 };
}
pub fn neg(self: @This()) @This() {
return @This(){ .x = -self.x, .y = -self.y };
}
pub fn length2(self: @This()) f32 {
var sum = self.x * self.x;
sum += self.y * self.y;
return sum;
}
pub fn length(self: @This()) f32 {
return std.math.sqrt(self.length2());
}
pub fn distanceTo(self: @This(), other: @This()) f32 {
return self.sub(other).length();
}
pub fn distanceToSquared(self: @This(), other: @This()) f32 {
return self.sub(other).length2();
}
pub fn normalize(self: @This()) @This() {
const l = self.length();
if (l == 0.0) return @This().zero();
return self.scale(1.0 / l);
}
pub fn scale(self: @This(), factor: f32) @This() {
return @This(){
.x = self.x * factor,
.y = self.y * factor,
};
}
pub fn add(self: @This(), other: @This()) @This() {
return @This(){
.x = self.x + other.x,
.y = self.y + other.y,
};
}
/// same as add but assign result directly to this
pub fn addSet(self: *@This(), other: @This()) void {
self.x += other.x;
self.y += other.y;
}
pub fn sub(self: @This(), other: @This()) @This() {
return @This(){
.x = self.x - other.x,
.y = self.y - other.y,
};
}
pub fn lerp(self: @This(), other: @This(), t: f32) @This() {
return self.scale(1 - t).add(other.scale(t));
}
pub fn randomInUnitCircle(rng: std.rand.Random) @This() {
return randomOnUnitCircle(rng).scale(randomF32(rng, 0, 1));
}
pub fn randomOnUnitCircle(rng: std.rand.Random) @This() {
return (Vector2{ .x = 1 }).rotate(randomF32(rng, -PI, PI));
}
pub fn clampX(self: @This(), minX: f32, maxX: f32) @This() {
return .{
.x = std.math.clamp(self.x, minX, maxX),
.y = self.y,
};
}
pub fn clampY(self: @This(), minY: f32, maxY: f32) @This() {
return .{
.x = self.x,
.y = std.math.clamp(self.y, minY, maxY),
};
}
pub fn int(self: @This()) Vector2i {
return .{ .x = @as(i32, @intFromFloat(self.x)), .y = @as(i32, @intFromFloat(self.y)) };
}
/// Cross product
pub fn cross(self: @This(), other: @This()) f32 {
return self.x * other.y - self.y * other.x;
}
/// Dot product.
pub fn dot(self: @This(), other: @This()) f32 {
return self.x * other.x + self.y * other.y;
}
pub fn rotate(self: @This(), a: f32) @This() {
return Vector2Rotate(self, a);
}
pub fn fromAngle(a: f32) @This() {
return Vector2Rotate(.{ .x = 1 }, a);
}
pub fn angle(this: @This()) f32 {
const zeroRotation: Vector2 = .{ .x = 1, .y = 0 };
if (this.x == zeroRotation.x and this.y == zeroRotation.y) return 0;
const c = zeroRotation.cross(this);
const d = zeroRotation.dot(this);
return std.math.atan2(f32, c, d);
}
pub fn xy0(self: @This()) Vector3 {
return .{ .x = self.x, .y = self.y };
}
pub fn x0z(self: @This()) Vector3 {
return .{ .x = self.x, .z = self.y };
}
pub fn set(self: @This(), setter: struct { x: ?f32 = null, y: ?f32 = null }) Vector2 {
var copy = self;
if (setter.x) |x| copy.x = x;
if (setter.y) |y| copy.y = y;
return copy;
}
};
pub const Vector2i = extern struct {
x: i32 = 0,
y: i32 = 0,
pub fn float(self: @This()) Vector2 {
return .{ .x = @as(f32, @floatFromInt(self.x)), .y = @as(f32, @floatFromInt(self.y)) };
}
};
pub const Vector3 = extern struct {
x: f32 = 0,
y: f32 = 0,
z: f32 = 0,
pub fn new(x: f32, y: f32, z: f32) @This() {
return @This(){ .x = x, .y = y, .z = z };
}
pub fn zero() @This() {
return @This(){ .x = 0, .y = 0, .z = 0 };
}
pub fn one() @This() {
return @This(){ .x = 1, .y = 1, .z = 1 };
}
pub fn length2(self: @This()) f32 {
var sum = self.x * self.x;
sum += self.y * self.y;
sum += self.z * self.z;
return sum;
}
pub fn length(self: @This()) f32 {
return std.math.sqrt(self.length2());
}
pub fn normalize(self: @This()) @This() {
const l = self.length();
if (l == 0.0) return @This().zero();
return self.scale(1.0 / l);
}
pub fn scale(self: @This(), factor: f32) @This() {
return @This(){
.x = self.x * factor,
.y = self.y * factor,
.z = self.z * factor,
};
}
pub fn add(self: @This(), other: @This()) @This() {
return @This(){
.x = self.x + other.x,
.y = self.y + other.y,
.z = self.z + other.z,
};
}
pub fn sub(self: @This(), other: @This()) @This() {
return @This(){
.x = self.x - other.x,
.y = self.y - other.y,
.z = self.z - other.z,
};
}
pub fn neg(this: @This()) @This() {
return .{
.x = -this.x,
.y = -this.y,
.z = -this.z,
};
}
pub fn lerp(self: @This(), other: @This(), t: f32) @This() {
return self.scale(1 - t).add(other.scale(t));
}
pub fn forward() @This() {
return @This().new(0, 0, 1);
}
pub fn rotate(self: @This(), quaternion: Vector4) @This() {
return Vector3RotateByQuaternion(self, quaternion);
}
pub fn angleBetween(self: @This(), other: Vector3) f32 {
return Vector3Angle(self, other);
// return std.math.acos(self.dot(other) / (self.length() * other.length()));
}
/// Dot product.
pub fn dot(self: @This(), other: @This()) f32 {
return self.x * other.x + self.y * other.y + self.z * other.z;
}
pub fn xy(self: @This()) Vector2 {
return .{ .x = self.x, .y = self.y };
}
pub fn set(self: @This(), setter: struct { x: ?f32 = null, y: ?f32 = null, z: ?f32 = null }) Vector3 {
var copy = self;
if (setter.x) |x| copy.x = x;
if (setter.y) |y| copy.y = y;
if (setter.z) |z| copy.z = z;
return copy;
}
};
pub const Vector4 = extern struct {
x: f32 = 0,
y: f32 = 0,
z: f32 = 0,
w: f32 = 0,
pub fn zero() @This() {
return @This(){ .x = 0, .y = 0, .z = 0 };
}
pub fn one() @This() {
return @This(){ .x = 1, .y = 1, .z = 1 };
}
pub fn length2(self: @This()) f32 {
var sum = self.x * self.x;
sum += self.y * self.y;
sum += self.z * self.z;
sum += self.w * self.w;
return sum;
}
pub fn length(self: @This()) f32 {
return std.math.sqrt(self.length2());
}
pub fn normalize(self: @This()) @This() {
const l = self.length();
if (l == 0.0) return @This().zero();
return self.scale(1.0 / l);
}
pub fn scale(self: @This(), factor: f32) @This() {
return @This(){
.x = self.x * factor,
.y = self.y * factor,
.z = self.z * factor,
.w = self.w * factor,
};
}
pub fn add(self: @This(), other: @This()) @This() {
return @This(){
.x = self.x + other.x,
.y = self.y + other.y,
.z = self.z + other.z,
.w = self.w + other.w,
};
}
pub fn sub(self: @This(), other: @This()) @This() {
return @This(){
.x = self.x - other.x,
.y = self.y - other.y,
.z = self.z - other.z,
.w = self.w - other.w,
};
}
pub fn lerp(self: @This(), other: @This(), t: f32) @This() {
return self.scale(1 - t).add(other.scale(t));
}
pub fn toColor(self: @This()) Color {
return .{
.r = @as(u8, @intFromFloat(std.math.clamp(self.x * 255, 0, 255))),
.g = @as(u8, @intFromFloat(std.math.clamp(self.y * 255, 0, 255))),
.b = @as(u8, @intFromFloat(std.math.clamp(self.z * 255, 0, 255))),
.a = @as(u8, @intFromFloat(std.math.clamp(self.w * 255, 0, 255))),
};
}
pub fn fromAngleAxis(axis: Vector3, angle: f32) @This() {
return QuaternionFromAxisAngle(axis, angle);
}
};
/// Color type, RGBA (32bit)
pub const Color = extern struct {
r: u8 = 0,
g: u8 = 0,
b: u8 = 0,
a: u8 = 255,
pub const ColorChangeConfig = struct {
r: ?u8 = null,
g: ?u8 = null,
b: ?u8 = null,
a: ?u8 = null,
};
pub fn set(self: @This(), c: ColorChangeConfig) Color {
return .{
.r = if (c.r) |_r| _r else self.r,
.g = if (c.g) |_g| _g else self.g,
.b = if (c.b) |_b| _b else self.b,
.a = if (c.a) |_a| _a else self.a,
};
}
pub fn lerp(self: @This(), other: @This(), t: f32) @This() {
return self.toVector4().lerp(other.toVector4(), t).toColor();
}
pub fn lerpA(self: @This(), targetAlpha: u8, t: f32) @This() {
var copy = self;
const a = @as(f32, @floatFromInt(self.a));
copy.a = @as(u8, @intFromFloat(a * (1 - t) + @as(f32, @floatFromInt(targetAlpha)) * t));
return copy;
}
pub fn toVector4(self: @This()) Vector4 {
return .{
.x = @as(f32, @floatFromInt(self.r)) / 255.0,
.y = @as(f32, @floatFromInt(self.g)) / 255.0,
.z = @as(f32, @floatFromInt(self.b)) / 255.0,
.w = @as(f32, @floatFromInt(self.a)) / 255.0,
};
}
/// negate color (keep alpha)
pub fn neg(self: @This()) @This() {
return .{
.r = 255 - self.r,
.g = 255 - self.g,
.b = 255 - self.b,
.a = self.a,
};
}
};
/// Camera2D, defines position/orientation in 2d space
pub const Camera2D = extern struct {
/// Camera offset (displacement from target)
offset: Vector2 = Vector2.zero(),
/// Camera target (rotation and zoom origin)
target: Vector2,
/// Camera rotation in degrees
rotation: f32 = 0,
/// Camera zoom (scaling), should be 1.0f by default
zoom: f32 = 1,
};
pub const MATERIAL_MAP_DIFFUSE = @as(usize, @intCast(@intFromEnum(MaterialMapIndex.MATERIAL_MAP_ALBEDO)));
pub const MATERIAL_MAP_SPECULAR = @as(usize, @intCast(@intFromEnum(MaterialMapIndex.MATERIAL_MAP_METALNESS)));
//--- callbacks -----------------------------------------------------------------------------------
/// Logging: Redirect trace log messages
pub const TraceLogCallback = *const fn (logLevel: c_int, text: [*c]const u8, args: ?*anyopaque) void;
/// FileIO: Load binary data
pub const LoadFileDataCallback = *const fn (fileName: [*c]const u8, bytesRead: [*c]c_uint) [*c]u8;
/// FileIO: Save binary data
pub const SaveFileDataCallback = *const fn (fileName: [*c]const u8, data: ?*anyopaque, bytesToWrite: c_uint) bool;
/// FileIO: Load text data
pub const LoadFileTextCallback = *const fn (fileName: [*c]const u8) [*c]u8;
/// FileIO: Save text data
pub const SaveFileTextCallback = *const fn (fileName: [*c]const u8, text: [*c]const u8) bool;
/// Audio Loading and Playing Functions (Module: audio)
pub const AudioCallback = *const fn (bufferData: ?*anyopaque, frames: u32) void;
//--- utils ---------------------------------------------------------------------------------------
// Camera global state context data [56 bytes]
pub const CameraData = extern struct {
/// Current camera mode
mode: u32,
/// Camera distance from position to target
targetDistance: f32,
/// Player eyes position from ground (in meters)
playerEyesPosition: f32,
/// Camera angle in plane XZ
angle: Vector2,
/// Previous mouse position
previousMousePosition: Vector2,
// Camera movement control keys
/// Move controls (CAMERA_FIRST_PERSON)
moveControl: i32[6],
/// Smooth zoom control key
smoothZoomControl: i32,
/// Alternative control key
altControl: i32,
/// Pan view control key
panControl: i32,
};
pub fn randomF32(rng: std.rand.Random, min: f32, max: f32) f32 {
return rng.float(f32) * (max - min) + min;
}
//--- functions -----------------------------------------------------------------------------------
/// Setup init configuration flags (view FLAGS)
pub fn SetConfigFlags(
flags: ConfigFlags,
) void {
raylib.SetConfigFlags(@as(c_uint, @bitCast(flags)));
}
/// Load file data as byte array (read)
pub fn LoadFileData(fileName: [*:0]const u8) ![]const u8 {
var bytesRead: u32 = undefined;
const data = raylib.LoadFileData(
@as([*c]const u8, @ptrFromInt(@intFromPtr(fileName))),
@as([*c]c_int, @ptrCast(&bytesRead)),
);
if (data == null) return error.FileNotFound;
return data[0..bytesRead];
}
/// Unload file data allocated by LoadFileData()
pub fn UnloadFileData(
data: []const u8,
) void {
raylib.UnloadFileData(
@as([*c]u8, @ptrFromInt(@intFromPtr(data.ptr))),
);
}
/// Set custom trace log
pub fn SetTraceLogCallback(
_: TraceLogCallback,
) void {
@panic("use log.zig for that");
}
/// Generate image font atlas using chars info
pub fn GenImageFontAtlas(
chars: [*]const GlyphInfo,
recs: [*]const [*]const Rectangle,
glyphCount: i32,
fontSize: i32,
padding: i32,
packMethod: i32,
) Image {
var out: Image = undefined;
mGenImageFontAtlas(
@as([*c]raylib.Image, @ptrCast(&out)),
@as([*c]raylib.GlyphInfo, @ptrCast(chars)),
@as([*c][*c]raylib.Rectangle, @ptrCast(recs)),
glyphCount,
fontSize,
padding,
packMethod,
);
return out;
}
export fn mGenImageFontAtlas(
out: [*c]raylib.Image,
chars: [*c]raylib.GlyphInfo,
recs: [*c][*c]raylib.Rectangle,
glyphCount: i32,
fontSize: i32,
padding: i32,
packMethod: i32,
) void {
out.* = raylib.GenImageFontAtlas(
chars,
recs,
glyphCount,
fontSize,
padding,
packMethod,
);
}
/// Get native window handle
pub fn GetWindowHandle() ?*anyopaque {
return raylib.GetWindowHandle();
}
/// Internal memory allocator
pub fn MemAlloc(
size: i32,
) ?*anyopaque {
return raylib.MemAlloc(size);
}
/// Internal memory reallocator
pub fn MemRealloc(
ptr: ?*anyopaque,
size: i32,
) ?*anyopaque {
return raylib.MemRealloc(ptr, size);
}
/// Internal memory free
pub fn MemFree(
ptr: ?*anyopaque,
) void {
raylib.MemFree(ptr);
}
/// Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR...)
pub fn TraceLog(
logLevel: i32,
text: [*:0]const u8,
) void {
raylib.TraceLog(logLevel, text);
}
/// Text formatting with variables (sprintf() style)
/// caller owns memory
pub fn TextFormat(allocator: std.mem.Allocator, comptime fmt: []const u8, args: anytype) std.fmt.AllocPrintError![*:0]const u8 {
return (try std.fmt.allocPrintZ(allocator, fmt, args)).ptr;
}
/// Split text into multiple strings
pub fn TextSplit(allocator: std.mem.Allocator, text: []const u8, delimiter: []const u8, count: i32) ![]const []const u8 {
var list = std.ArrayList([]const u8).init(allocator);
var it = std.mem.split(u8, text, delimiter);
var i = 0;
var n = 0;
while (it.next()) |slice| : (i += 1) {
if (i >= count) {
break;
}
try list.append(slice);
n += slice.len;
}
if (n < text.len) {
try list.append(text[n..]);
}
return list.toOwnedSlice();
}
/// Join text strings with delimiter
pub fn TextJoin(allocator: std.mem.Allocator, textList: []const []const u8, delimiter: []const u8) ![:0]const u8 {
return (try std.mem.joinZ(allocator, delimiter, textList)).ptr;
}
/// Append text at specific position and move cursor!
pub fn TextAppend(allocator: std.mem.Allocator, text: []const u8, append: []const u8, position: i32) std.fmt.AllocPrintError![:0]u8 {
return (try std.fmt.allocPrintZ(allocator, "{s}{s}{s}", .{
text[0..position],
append,
text[position..],
})).ptr;
}
//--- RLGL ----------------------------------------------------------------------------------------
pub const DEG2RAD: f32 = PI / 180;
pub const RAD2DEG: f32 = 180 / PI;
///
pub const rlglData = extern struct {
/// Current render batch
currentBatch: ?*rlRenderBatch,
/// Default internal render batch
defaultBatch: rlRenderBatch,
pub const State = extern struct {
/// Current active render batch vertex counter (generic, used for all batches)
vertexCounter: i32,
/// Current active texture coordinate X (added on glVertex*())
texcoordx: f32,
/// Current active texture coordinate Y (added on glVertex*())
texcoordy: f32,
/// Current active normal X (added on glVertex*())
normalx: f32,
/// Current active normal Y (added on glVertex*())
normaly: f32,
/// Current active normal Z (added on glVertex*())
normalz: f32,
/// Current active color R (added on glVertex*())
colorr: u8,
/// Current active color G (added on glVertex*())
colorg: u8,
/// Current active color B (added on glVertex*())
colorb: u8,
/// Current active color A (added on glVertex*())
colora: u8,
/// Current matrix mode
currentMatrixMode: i32,
/// Current matrix pointer
currentMatrix: ?*Matrix,
/// Default modelview matrix
modelview: Matrix,
/// Default projection matrix
projection: Matrix,
/// Transform matrix to be used with rlTranslate, rlRotate, rlScale
transform: Matrix,
/// Require transform matrix application to current draw-call vertex (if required)
transformRequired: bool,
/// Matrix stack for push/pop
stack: [RL_MAX_MATRIX_STACK_SIZE]Matrix,
/// Matrix stack counter
stackCounter: i32,
/// Default texture used on shapes/poly drawing (required by shader)
defaultTextureId: u32,
/// Active texture ids to be enabled on batch drawing (0 active by default)
activeTextureId: [RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS]u32,
/// Default vertex shader id (used by default shader program)
defaultVShaderId: u32,
/// Default fragment shader id (used by default shader program)
defaultFShaderId: u32,
/// Default shader program id, supports vertex color and diffuse texture
defaultShaderId: u32,
/// Default shader locations pointer to be used on rendering
defaultShaderLocs: [*]i32,
/// Current shader id to be used on rendering (by default, defaultShaderId)
currentShaderId: u32,
/// Current shader locations pointer to be used on rendering (by default, defaultShaderLocs)
currentShaderLocs: [*]i32,
/// Stereo rendering flag
stereoRender: bool,
/// VR stereo rendering eyes projection matrices
projectionStereo: [2]Matrix,
/// VR stereo rendering eyes view offset matrices
viewOffsetStereo: [2]Matrix,
/// Blending mode active
currentBlendMode: i32,
/// Blending source factor
glBlendSrcFactor: i32,
/// Blending destination factor
glBlendDstFactor: i32,
/// Blending equation
glBlendEquation: i32,
/// Current framebuffer width
framebufferWidth: i32,
/// Current framebuffer height
framebufferHeight: i32,
};
pub const ExtSupported = extern struct {
/// VAO support (OpenGL ES2 could not support VAO extension) (GL_ARB_vertex_array_object)
vao: bool,
/// Instancing supported (GL_ANGLE_instanced_arrays, GL_EXT_draw_instanced + GL_EXT_instanced_arrays)
instancing: bool,
/// NPOT textures full support (GL_ARB_texture_non_power_of_two, GL_OES_texture_npot)
texNPOT: bool,
/// Depth textures supported (GL_ARB_depth_texture, GL_WEBGL_depth_texture, GL_OES_depth_texture)
texDepth: bool,
/// float textures support (32 bit per channel) (GL_OES_texture_float)
texFloat32: bool,
/// DDS texture compression support (GL_EXT_texture_compression_s3tc, GL_WEBGL_compressed_texture_s3tc, GL_WEBKIT_WEBGL_compressed_texture_s3tc)
texCompDXT: bool,
/// ETC1 texture compression support (GL_OES_compressed_ETC1_RGB8_texture, GL_WEBGL_compressed_texture_etc1)
texCompETC1: bool,
/// ETC2/EAC texture compression support (GL_ARB_ES3_compatibility)
texCompETC2: bool,
/// PVR texture compression support (GL_IMG_texture_compression_pvrtc)
texCompPVRT: bool,
/// ASTC texture compression support (GL_KHR_texture_compression_astc_hdr, GL_KHR_texture_compression_astc_ldr)
texCompASTC: bool,
/// Clamp mirror wrap mode supported (GL_EXT_texture_mirror_clamp)
texMirrorClamp: bool,
/// Anisotropic texture filtering support (GL_EXT_texture_filter_anisotropic)
texAnisoFilter: bool,
/// Compute shaders support (GL_ARB_compute_shader)
computeShader: bool,
/// Shader storage buffer object support (GL_ARB_shader_storage_buffer_object)
ssbo: bool,
/// Maximum anisotropy level supported (minimum is 2.0f)
maxAnisotropyLevel: f32,
/// Maximum bits for depth component
maxDepthBits: i32,
};
};
/// Enable attribute state pointer
pub fn rlEnableStatePointer(
vertexAttribType: i32,
buffer: *anyopaque,
) void {
raylib.rlEnableStatePointer(
vertexAttribType,
@as([*c]anyopaque, @ptrCast(buffer)),
);
}
/// Disable attribute state pointer
pub fn rlDisableStatePointer(
vertexAttribType: i32,
) void {
raylib.rlDisableStatePointer(
vertexAttribType,
);
}
/// Get the last gamepad button pressed
pub fn GetGamepadButtonPressed() ?GamepadButton {
if (raylib.GetGamepadButtonPressed() == -1) return null;
return @as(GamepadButton, @enumFromInt(raylib.GetGamepadButtonPressed()));
}