#![doc(
html_logo_url = "https://github.com/deltaphc/raylib-rs/raw/master/logo/raylib-rust_256x256.png",
html_favicon_url = "https://github.com/deltaphc/raylib-rs/raw/master/logo/raylib-rust.ico"
)]
use std::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering};
use std::ffi::{CString, CStr};
use lazy_static::lazy_static;
mod raiiwrap;
mod raymath;
pub mod ease;
use raylib_sys::ffi;
pub mod consts {
pub use raylib_sys::ffi_consts::*;
}
use crate::consts::*;
pub use raylib_sys::ffi_types::{
BoundingBox,
Camera2D, Camera3D,
CharInfo,
Ray, RayHitInfo,
Rectangle,
VrDeviceInfo,
};
pub use crate::raymath::*;
pub use crate::raiiwrap::*;
macro_rules! bitflag_type {
($name:ident, $t:ty) => {
#[repr(C)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct $name(pub $t);
impl std::ops::BitOr<$name> for $name {
type Output = Self;
#[inline]
fn bitor(self, other: Self) -> Self {
$name(self.0 | other.0)
}
}
impl std::ops::BitOrAssign for $name {
#[inline]
fn bitor_assign(&mut self, rhs: $name) {
self.0 |= rhs.0;
}
}
impl std::ops::BitAnd<$name> for $name {
type Output = Self;
#[inline]
fn bitand(self, other: Self) -> Self {
$name(self.0 & other.0)
}
}
impl std::ops::BitAndAssign for $name {
#[inline]
fn bitand_assign(&mut self, rhs: $name) {
self.0 &= rhs.0;
}
}
};
}
macro_rules! enum_from_i32 {
($name:ident: $repr:ident { $($variant:ident = $value:path, )* }) => {
#[repr($repr)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum $name {
$($variant = $value,)*
}
impl From<i32> for $name {
#[inline]
fn from(format: i32) -> $name {
match format as $repr {
$($value => $name::$variant,)*
_ => panic!("Invalid integer {} passed to {}::from(i32)", format, stringify!($name)),
}
}
}
}
}
macro_rules! impl_bidirectional_from {
($t1:path, $t2:path, $($field:ident),*) => {
impl From<$t1> for $t2 {
#[inline]
fn from(v: $t1) -> $t2 {
$t2 {
$($field: v.$field,)*
}
}
}
impl From<$t2> for $t1 {
#[inline]
fn from(v: $t2) -> $t1 {
$t1 {
$($field: v.$field,)*
}
}
}
};
}
bitflag_type!(Log, u32);
impl Log {
pub const INFO: Log = Log(ffi::LOG_INFO);
pub const WARNING: Log = Log(ffi::LOG_WARNING);
pub const ERROR: Log = Log(ffi::LOG_ERROR);
pub const DEBUG: Log = Log(ffi::LOG_DEBUG);
pub const OTHER: Log = Log(ffi::LOG_OTHER);
}
bitflag_type!(Gesture, u32);
impl Gesture {
pub const NONE: Gesture = Gesture(ffi::GESTURE_NONE);
pub const TAP: Gesture = Gesture(ffi::GESTURE_TAP);
pub const DOUBLETAP: Gesture = Gesture(ffi::GESTURE_DOUBLETAP);
pub const HOLD: Gesture = Gesture(ffi::GESTURE_HOLD);
pub const DRAG: Gesture = Gesture(ffi::GESTURE_DRAG);
pub const SWIPE_RIGHT: Gesture = Gesture(ffi::GESTURE_SWIPE_RIGHT);
pub const SWIPE_LEFT: Gesture = Gesture(ffi::GESTURE_SWIPE_LEFT);
pub const SWIPE_UP: Gesture = Gesture(ffi::GESTURE_SWIPE_UP);
pub const SWIPE_DOWN: Gesture = Gesture(ffi::GESTURE_SWIPE_DOWN);
pub const PINCH_IN: Gesture = Gesture(ffi::GESTURE_PINCH_IN);
pub const PINCH_OUT: Gesture = Gesture(ffi::GESTURE_PINCH_OUT);
}
enum_from_i32! {
ShaderLoc: u32 {
VertexPosition = ffi::LOC_VERTEX_POSITION,
VertexTexCoord01 = ffi::LOC_VERTEX_TEXCOORD01,
VertexTexCoord02 = ffi::LOC_VERTEX_TEXCOORD02,
VertexNormal = ffi::LOC_VERTEX_NORMAL,
VertexTangent = ffi::LOC_VERTEX_TANGENT,
VertexColor = ffi::LOC_VERTEX_COLOR,
MatrixMVP = ffi::LOC_MATRIX_MVP,
MatrixModel = ffi::LOC_MATRIX_MODEL,
MatrixView = ffi::LOC_MATRIX_VIEW,
MatrixProjection = ffi::LOC_MATRIX_PROJECTION,
VectorView = ffi::LOC_VECTOR_VIEW,
ColorDiffuse = ffi::LOC_COLOR_DIFFUSE,
ColorSpecular = ffi::LOC_COLOR_SPECULAR,
ColorAmbient = ffi::LOC_COLOR_AMBIENT,
MapAlbedo = ffi::LOC_MAP_ALBEDO,
MapMetalness = ffi::LOC_MAP_METALNESS,
MapNormal = ffi::LOC_MAP_NORMAL,
MapRoughness = ffi::LOC_MAP_ROUGHNESS,
MapOcclusion = ffi::LOC_MAP_OCCLUSION,
MapEmission = ffi::LOC_MAP_EMISSION,
MapHeight = ffi::LOC_MAP_HEIGHT,
MapCubeMap = ffi::LOC_MAP_CUBEMAP,
MapIrradiance = ffi::LOC_MAP_IRRADIANCE,
MapPrefilter = ffi::LOC_MAP_PREFILTER,
MapBRDF = ffi::LOC_MAP_BRDF,
}
}
enum_from_i32! {
Texmap: u32 {
Albedo = ffi::MAP_ALBEDO,
Metalness = ffi::MAP_METALNESS,
Normal = ffi::MAP_NORMAL,
Roughness = ffi::MAP_ROUGHNESS,
Occlusion = ffi::MAP_OCCLUSION,
Emission = ffi::MAP_EMISSION,
Height = ffi::MAP_HEIGHT,
CubeMap = ffi::MAP_CUBEMAP,
Irradiance = ffi::MAP_IRRADIANCE,
Prefilter = ffi::MAP_PREFILTER,
BRDF = ffi::MAP_BRDF,
}
}
enum_from_i32! {
PixelFormat: u32 {
UncompressedGrayscale = ffi::UNCOMPRESSED_GRAYSCALE,
UncompressedGrayAlpha = ffi::UNCOMPRESSED_GRAY_ALPHA,
UncompressedR5G6B5 = ffi::UNCOMPRESSED_R5G6B5,
UncompressedR8G8B8 = ffi::UNCOMPRESSED_R8G8B8,
UncompressedR5G5B5A1 = ffi::UNCOMPRESSED_R5G5B5A1,
UncompressedR4G4B4A4 = ffi::UNCOMPRESSED_R4G4B4A4,
UncompressedR8G8B8A8 = ffi::UNCOMPRESSED_R8G8B8A8,
UncompressedR32 = ffi::UNCOMPRESSED_R32,
UncompressedR32G32B32 = ffi::UNCOMPRESSED_R32G32B32,
UncompressedR32G32B32A32 = ffi::UNCOMPRESSED_R32G32B32A32,
CompressedDXT1RGB = ffi::COMPRESSED_DXT1_RGB,
CompressedDXT1RGBA = ffi::COMPRESSED_DXT1_RGBA,
CompressedDXT3RGBA = ffi::COMPRESSED_DXT3_RGBA,
CompressedDXT5RGBA = ffi::COMPRESSED_DXT5_RGBA,
CompressedETC1RGB = ffi::COMPRESSED_ETC1_RGB,
CompressedETC2RGB = ffi::COMPRESSED_ETC2_RGB,
CompressedETC2EACRGBA = ffi::COMPRESSED_ETC2_EAC_RGBA,
CompressedPVRTRGB = ffi::COMPRESSED_PVRT_RGB,
CompressedPVRTRGBA = ffi::COMPRESSED_PVRT_RGBA,
CompressedASTC4x4RGBA = ffi::COMPRESSED_ASTC_4x4_RGBA,
CompressedASTC8x8RGBA = ffi::COMPRESSED_ASTC_8x8_RGBA,
}
}
enum_from_i32! {
TextureFilter: u32 {
Point = ffi::FILTER_POINT,
Bilinear = ffi::FILTER_BILINEAR,
Trilinear = ffi::FILTER_TRILINEAR,
Anisotropic4x = ffi::FILTER_ANISOTROPIC_4X,
Anisotropic8x = ffi::FILTER_ANISOTROPIC_8X,
Anisotropic16x = ffi::FILTER_ANISOTROPIC_16X,
}
}
enum_from_i32! {
TextureWrap: u32 {
Repeat = ffi::WRAP_REPEAT,
Clamp = ffi::WRAP_CLAMP,
Mirror = ffi::WRAP_MIRROR,
}
}
enum_from_i32! {
BlendMode: u32 {
Alpha = ffi::BLEND_ALPHA,
Additive = ffi::BLEND_ADDITIVE,
Multiplied = ffi::BLEND_MULTIPLIED,
}
}
enum_from_i32! {
CameraMode: u32 {
Custom = ffi::CAMERA_CUSTOM,
Free = ffi::CAMERA_FREE,
Orbital = ffi::CAMERA_ORBITAL,
FirstPerson = ffi::CAMERA_FIRST_PERSON,
ThirdPerson = ffi::CAMERA_THIRD_PERSON,
}
}
enum_from_i32! {
CameraType: u32 {
Perspective = ffi::CAMERA_PERSPECTIVE,
Orthographic = ffi::CAMERA_ORTHOGRAPHIC,
}
}
enum_from_i32! {
VrDevice: u32 {
Default = ffi::HMD_DEFAULT_DEVICE,
OculusRiftDK2 = ffi::HMD_OCULUS_RIFT_DK2,
OculusRiftCV1 = ffi::HMD_OCULUS_RIFT_CV1,
OculusGo = ffi::HMD_OCULUS_GO,
ValveHTCVive = ffi::HMD_VALVE_HTC_VIVE,
SonyPSVR = ffi::HMD_SONY_PSVR,
}
}
impl_bidirectional_from!(Vector2, ffi::Vector2, x, y);
impl_bidirectional_from!(Vector3, ffi::Vector3, x, y, z);
impl_bidirectional_from!(Vector4, ffi::Vector4, x, y, z, w);
impl_bidirectional_from!(Matrix, ffi::Matrix,
m0, m4, m8, m12,
m1, m5, m9, m13,
m2, m6, m10, m14,
m3, m7, m11, m15);
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Color {
pub r: u8,
pub g: u8,
pub b: u8,
pub a: u8,
}
impl Color {
pub const LIGHTGRAY : Color = Color { r: 200, g: 200, b: 200, a: 255 };
pub const GRAY : Color = Color { r: 130, g: 130, b: 130, a: 255 };
pub const DARKGRAY : Color = Color { r: 80, g: 80, b: 80, a: 255 };
pub const YELLOW : Color = Color { r: 253, g: 249, b: 0, a: 255 };
pub const GOLD : Color = Color { r: 255, g: 203, b: 0, a: 255 };
pub const ORANGE : Color = Color { r: 255, g: 161, b: 0, a: 255 };
pub const PINK : Color = Color { r: 255, g: 109, b: 194, a: 255 };
pub const RED : Color = Color { r: 230, g: 41, b: 55, a: 255 };
pub const MAROON : Color = Color { r: 190, g: 33, b: 55, a: 255 };
pub const GREEN : Color = Color { r: 0, g: 228, b: 48, a: 255 };
pub const LIME : Color = Color { r: 0, g: 158, b: 47, a: 255 };
pub const DARKGREEN : Color = Color { r: 0, g: 117, b: 44, a: 255 };
pub const SKYBLUE : Color = Color { r: 102, g: 191, b: 255, a: 255 };
pub const BLUE : Color = Color { r: 0, g: 121, b: 241, a: 255 };
pub const DARKBLUE : Color = Color { r: 0, g: 82, b: 172, a: 255 };
pub const PURPLE : Color = Color { r: 200, g: 122, b: 255, a: 255 };
pub const VIOLET : Color = Color { r: 135, g: 60, b: 190, a: 255 };
pub const DARKPURPLE : Color = Color { r: 112, g: 31, b: 126, a: 255 };
pub const BEIGE : Color = Color { r: 211, g: 176, b: 131, a: 255 };
pub const BROWN : Color = Color { r: 127, g: 106, b: 79, a: 255 };
pub const DARKBROWN : Color = Color { r: 76, g: 63, b: 47, a: 255 };
pub const WHITE : Color = Color { r: 255, g: 255, b: 255, a: 255 };
pub const BLACK : Color = Color { r: 0, g: 0, b: 0, a: 255 };
pub const BLANK : Color = Color { r: 0, g: 0, b: 0, a: 0 };
pub const MAGENTA : Color = Color { r: 255, g: 0, b: 255, a: 255 };
pub const RAYWHITE : Color = Color { r: 245, g: 245, b: 245, a: 255 };
#[inline]
pub fn new(r: u8, g: u8, b: u8, a: u8) -> Color {
Color { r, g, b, a }
}
}
impl_bidirectional_from!(Color, ffi::Color, r, g, b, a);
impl From<(u8, u8, u8)> for Color {
#[inline]
fn from((r, g, b): (u8, u8, u8)) -> Color {
Color { r, g, b, a: 255 }
}
}
impl From<(u8, u8, u8, u8)> for Color {
#[inline]
fn from((r, g, b, a): (u8, u8, u8, u8)) -> Color {
Color { r, g, b, a }
}
}
pub trait AudioSample { }
impl AudioSample for u8 { }
impl AudioSample for i16 { }
impl AudioSample for f32 { }
static IS_INITIALIZED: AtomicBool = ATOMIC_BOOL_INIT;
lazy_static! {
static ref FONT_DEFAULT: Font = {
unsafe { Font(ffi::GetFontDefault()) }
};
}
lazy_static! {
static ref MATERIAL_DEFAULT: Material = {
unsafe { Material(ffi::LoadMaterialDefault()) }
};
}
lazy_static! {
static ref SHADER_DEFAULT: Shader = {
unsafe { Shader(ffi::GetShaderDefault()) }
};
}
lazy_static! {
static ref TEXTURE_DEFAULT: Texture2D = {
unsafe {
Texture2D(ffi::GetTextureDefault())
}
};
}
#[derive(Debug, Default)]
pub struct RaylibBuilder {
show_logo: bool,
fullscreen_mode: bool,
window_resizable: bool,
window_undecorated: bool,
window_transparent: bool,
msaa_4x_hint: bool,
vsync_hint: bool,
width: i32,
height: i32,
title: String,
}
impl RaylibBuilder {
pub fn with_logo(&mut self) -> &mut Self {
self.show_logo = true;
self
}
pub fn fullscreen(&mut self) -> &mut Self {
self.fullscreen_mode = true;
self
}
pub fn resizable(&mut self) -> &mut Self {
self.window_resizable = true;
self
}
pub fn undecorated(&mut self) -> &mut Self {
self.window_undecorated = true;
self
}
pub fn transparent(&mut self) -> &mut Self {
self.window_transparent = true;
self
}
pub fn msaa_4x(&mut self) -> &mut Self {
self.msaa_4x_hint = true;
self
}
pub fn vsync(&mut self) -> &mut Self {
self.vsync_hint = true;
self
}
pub fn width(&mut self, w: i32) -> &mut Self {
self.width = w;
self
}
pub fn height(&mut self, h: i32) -> &mut Self {
self.height = h;
self
}
pub fn size(&mut self, w: i32, h: i32) -> &mut Self {
self.width = w;
self.height = h;
self
}
pub fn title(&mut self, text: &str) -> &mut Self {
self.title = text.to_string();
self
}
pub fn build(&self) -> RaylibHandle {
let mut flags = 0u32;
if self.show_logo { flags |= FLAG_SHOW_LOGO; }
if self.fullscreen_mode { flags |= FLAG_FULLSCREEN_MODE; }
if self.window_resizable { flags |= FLAG_WINDOW_RESIZABLE; }
if self.window_undecorated { flags |= FLAG_WINDOW_UNDECORATED; }
if self.window_transparent { flags |= FLAG_WINDOW_TRANSPARENT; }
if self.msaa_4x_hint { flags |= FLAG_MSAA_4X_HINT; }
if self.vsync_hint { flags |= FLAG_VSYNC_HINT; }
unsafe { ffi::SetConfigFlags(flags as u8); }
init_window(self.width, self.height, &self.title)
}
}
#[inline]
pub fn set_trace_log(types: Log) {
unsafe {
ffi::SetTraceLog(types.0 as u8);
}
}
#[inline]
pub fn trace_log(msg_type: Log, text: &str) {
unsafe {
let text = CString::new(text).unwrap();
ffi::TraceLog(msg_type.0 as i32, text.as_ptr());
}
}
pub struct RaylibHandle;
pub fn init() -> RaylibBuilder {
RaylibBuilder {
width: 640,
height: 480,
title: "raylib-rs".to_string(),
..Default::default()
}
}
pub fn init_window(width: i32, height: i32, title: &str) -> RaylibHandle {
if IS_INITIALIZED.load(Ordering::Relaxed) {
panic!("Attempted to initialize raylib-rs more than once");
}
else {
unsafe {
let c_title = CString::new(title).unwrap();
ffi::InitWindow(width, height, c_title.as_ptr());
}
IS_INITIALIZED.store(true, Ordering::Relaxed);
RaylibHandle
}
}
impl Drop for RaylibHandle {
fn drop(&mut self) {
if IS_INITIALIZED.load(Ordering::Relaxed) {
unsafe { ffi::CloseWindow(); }
IS_INITIALIZED.store(false, Ordering::Relaxed);
}
}
}
impl RaylibHandle {
#[inline]
pub fn is_window_ready(&self) -> bool {
unsafe {
ffi::IsWindowReady()
}
}
#[inline]
pub fn window_should_close(&self) -> bool {
unsafe {
ffi::WindowShouldClose()
}
}
#[inline]
pub fn is_window_minimized(&self) -> bool {
unsafe {
ffi::IsWindowMinimized()
}
}
#[inline]
pub fn toggle_fullscreen(&self) {
unsafe {
ffi::ToggleFullscreen();
}
}
#[inline]
pub fn set_window_icon(&self, image: &Image) {
unsafe {
ffi::SetWindowIcon(image.0);
}
}
#[inline]
pub fn set_window_title(&self, title: &str) {
let c_title = CString::new(title).unwrap();
unsafe {
ffi::SetWindowTitle(c_title.as_ptr());
}
}
#[inline]
pub fn set_window_position(&self, x: i32, y: i32) {
unsafe {
ffi::SetWindowPosition(x, y);
}
}
#[inline]
pub fn set_window_monitor(&self, monitor: i32) {
unsafe {
ffi::SetWindowMonitor(monitor);
}
}
#[inline]
pub fn set_window_min_size(&self, width: i32, height: i32) {
unsafe {
ffi::SetWindowMinSize(width, height);
}
}
#[inline]
pub fn set_window_size(&self, width: i32, height: i32) {
unsafe {
ffi::SetWindowSize(width, height);
}
}
#[inline]
pub fn get_screen_width(&self) -> i32 {
unsafe {
ffi::GetScreenWidth()
}
}
#[inline]
pub fn get_screen_height(&self) -> i32 {
unsafe {
ffi::GetScreenHeight()
}
}
#[inline]
pub fn show_cursor(&self) {
unsafe {
ffi::ShowCursor();
}
}
#[inline]
pub fn hide_cursor(&self) {
unsafe {
ffi::HideCursor();
}
}
#[inline]
pub fn is_cursor_hidden(&self) -> bool {
unsafe {
ffi::IsCursorHidden()
}
}
#[inline]
pub fn enable_cursor(&self) {
unsafe {
ffi::EnableCursor();
}
}
#[inline]
pub fn disable_cursor(&self) {
unsafe {
ffi::DisableCursor();
}
}
#[inline]
pub fn clear_background(&self, color: impl Into<Color>) {
unsafe {
ffi::ClearBackground(color.into().into());
}
}
#[inline]
pub fn begin_drawing(&self) {
unsafe {
ffi::BeginDrawing();
}
}
#[inline]
pub fn end_drawing(&self) {
unsafe {
ffi::EndDrawing();
}
}
#[inline]
pub fn begin_mode_2d(&self, camera: Camera2D) {
unsafe {
ffi::BeginMode2D(camera);
}
}
#[inline]
pub fn end_mode_2d(&self) {
unsafe {
ffi::EndMode2D();
}
}
#[inline]
pub fn begin_mode_3d(&self, camera: Camera3D) {
unsafe {
ffi::BeginMode3D(camera);
}
}
#[inline]
pub fn end_mode_3d(&self) {
unsafe {
ffi::EndMode3D();
}
}
#[inline]
pub fn begin_texture_mode(&self, target: &RenderTexture2D) {
unsafe {
ffi::BeginTextureMode(target.0);
}
}
#[inline]
pub fn end_texture_mode(&self) {
unsafe {
ffi::EndTextureMode();
}
}
#[inline]
pub fn get_mouse_ray(&self, mouse_position: impl Into<Vector2>, camera: Camera3D) -> Ray {
unsafe {
ffi::GetMouseRay(mouse_position.into().into(), camera)
}
}
#[inline]
pub fn get_world_to_screen(&self, position: impl Into<Vector3>, camera: Camera3D) -> Vector2 {
unsafe {
ffi::GetWorldToScreen(position.into().into(), camera).into()
}
}
#[inline]
pub fn get_camera_matrix(&self, camera: Camera3D) -> Matrix {
unsafe {
ffi::GetCameraMatrix(camera).into()
}
}
#[inline]
pub fn set_target_fps(&self, fps: i32) {
unsafe {
ffi::SetTargetFPS(fps);
}
}
#[inline]
pub fn get_fps(&self) -> i32 {
unsafe {
ffi::GetFPS()
}
}
#[inline]
pub fn get_frame_time(&self) -> f32 {
unsafe {
ffi::GetFrameTime()
}
}
#[inline]
pub fn get_time(&self) -> f64 {
unsafe {
ffi::GetTime()
}
}
#[inline]
pub fn color_to_int(&self, color: impl Into<Color>) -> i32 {
unsafe {
ffi::ColorToInt(color.into().into())
}
}
#[inline]
pub fn color_normalize(&self, color: impl Into<Color>) -> Vector4 {
unsafe {
ffi::ColorNormalize(color.into().into()).into()
}
}
#[inline]
pub fn color_to_hsv(&self, color: impl Into<Color>) -> Vector3 {
unsafe {
ffi::ColorToHSV(color.into().into()).into()
}
}
#[inline]
pub fn get_color(&self, hex_value: i32) -> Color {
unsafe {
ffi::GetColor(hex_value).into()
}
}
#[inline]
pub fn fade(&self, color: impl Into<Color>, alpha: f32) -> Color {
unsafe {
ffi::Fade(color.into().into(), alpha).into()
}
}
#[inline]
pub fn take_screenshot(&self, filename: &str) {
let c_filename = CString::new(filename).unwrap();
unsafe {
ffi::TakeScreenshot(c_filename.as_ptr());
}
}
#[inline]
pub fn get_random_value(&self, min: i32, max: i32) -> i32 {
unsafe {
ffi::GetRandomValue(min, max)
}
}
#[inline]
pub fn is_file_extension(&self, filename: &str, ext: &str) -> bool {
let c_filename = CString::new(filename).unwrap();
let c_ext = CString::new(ext).unwrap();
unsafe {
ffi::IsFileExtension(c_filename.as_ptr(), c_ext.as_ptr())
}
}
#[inline]
pub fn get_extension(&self, filename: &str) -> String {
let c_filename = CString::new(filename).unwrap();
unsafe {
let ext = ffi::GetExtension(c_filename.as_ptr());
CStr::from_ptr(ext).to_str().unwrap().to_owned()
}
}
#[inline]
pub fn get_file_name(&self, file_path: &str) -> String {
let c_file_path = CString::new(file_path).unwrap();
unsafe {
let filename = ffi::GetFileName(c_file_path.as_ptr());
CStr::from_ptr(filename).to_str().unwrap().to_owned()
}
}
#[inline]
pub fn get_directory_path(&self, filename: &str) -> String {
let c_filename = CString::new(filename).unwrap();
unsafe {
let dirpath = ffi::GetDirectoryPath(c_filename.as_ptr());
CStr::from_ptr(dirpath).to_str().unwrap().to_owned()
}
}
#[inline]
pub fn get_working_directory(&self) -> String {
unsafe {
let workdir = ffi::GetWorkingDirectory();
CStr::from_ptr(workdir).to_str().unwrap().to_owned()
}
}
#[inline]
pub fn change_directory(&self, dir: &str) -> bool {
let c_dir = CString::new(dir).unwrap();
unsafe {
ffi::ChangeDirectory(c_dir.as_ptr())
}
}
#[inline]
pub fn is_file_dropped(&self) -> bool {
unsafe {
ffi::IsFileDropped()
}
}
#[inline]
pub fn get_dropped_files(&self) -> Vec<String> {
let mut v = Vec::new();
unsafe {
let mut count: i32 = 0;
let dropfiles = ffi::GetDroppedFiles(&mut count);
for i in 0..count {
let filestr = CStr::from_ptr(*dropfiles.offset(i as isize)).to_str().unwrap();
let file = String::from(filestr);
v.push(file);
}
}
v
}
#[inline]
pub fn clear_dropped_files(&self) {
unsafe {
ffi::ClearDroppedFiles();
}
}
#[inline]
pub fn storage_save_value(&self, position: i32, value: i32) {
unsafe {
ffi::StorageSaveValue(position, value);
}
}
#[inline]
pub fn storage_load_value(&self, position: i32) -> i32 {
unsafe {
ffi::StorageLoadValue(position)
}
}
#[inline]
pub fn is_key_pressed(&self, key: i32) -> bool {
unsafe {
ffi::IsKeyPressed(key)
}
}
#[inline]
pub fn is_key_down(&self, key: i32) -> bool {
unsafe {
ffi::IsKeyDown(key)
}
}
#[inline]
pub fn is_key_released(&self, key: i32) -> bool {
unsafe {
ffi::IsKeyReleased(key)
}
}
#[inline]
pub fn is_key_up(&self, key: i32) -> bool {
unsafe {
ffi::IsKeyUp(key)
}
}
#[inline]
pub fn get_key_pressed(&self) -> i32 {
unsafe {
ffi::GetKeyPressed()
}
}
#[inline]
pub fn set_exit_key(&self, key: i32) {
unsafe {
ffi::SetExitKey(key);
}
}
#[inline]
pub fn is_gamepad_available(&self, gamepad: i32) -> bool {
unsafe {
ffi::IsGamepadAvailable(gamepad)
}
}
#[inline]
pub fn is_gamepad_name(&self, gamepad: i32, name: &str) -> bool {
let c_name = CString::new(name).unwrap();
unsafe {
ffi::IsGamepadName(gamepad, c_name.as_ptr())
}
}
#[inline]
pub fn get_gamepad_name(&self, gamepad: i32) -> Option<String> {
unsafe {
let name = ffi::GetGamepadName(gamepad);
match name.is_null() {
false => Some(CStr::from_ptr(name).to_str().unwrap().to_owned()),
true => None
}
}
}
#[inline]
pub fn is_gamepad_button_pressed(&self, gamepad: i32, button: i32) -> bool {
unsafe {
ffi::IsGamepadButtonPressed(gamepad, button)
}
}
#[inline]
pub fn is_gamepad_button_down(&self, gamepad: i32, button: i32) -> bool {
unsafe {
ffi::IsGamepadButtonDown(gamepad, button)
}
}
#[inline]
pub fn is_gamepad_button_released(&self, gamepad: i32, button: i32) -> bool {
unsafe {
ffi::IsGamepadButtonReleased(gamepad, button)
}
}
#[inline]
pub fn is_gamepad_button_up(&self, gamepad: i32, button: i32) -> bool {
unsafe {
ffi::IsGamepadButtonUp(gamepad, button)
}
}
#[inline]
pub fn get_gamepad_button_pressed(&self) -> i32 {
unsafe {
ffi::GetGamepadButtonPressed()
}
}
#[inline]
pub fn get_gamepad_axis_count(&self, gamepad: i32) -> i32 {
unsafe {
ffi::GetGamepadAxisCount(gamepad)
}
}
#[inline]
pub fn get_gamepad_axis_movement(&self, gamepad: i32, axis: i32) -> f32 {
unsafe {
ffi::GetGamepadAxisMovement(gamepad, axis)
}
}
#[inline]
pub fn is_mouse_button_pressed(&self, button: i32) -> bool {
unsafe {
ffi::IsMouseButtonPressed(button)
}
}
#[inline]
pub fn is_mouse_button_down(&self, button: i32) -> bool {
unsafe {
ffi::IsMouseButtonDown(button)
}
}
#[inline]
pub fn is_mouse_button_released(&self, button: i32) -> bool {
unsafe {
ffi::IsMouseButtonReleased(button)
}
}
#[inline]
pub fn is_mouse_button_up(&self, button: i32) -> bool {
unsafe {
ffi::IsMouseButtonUp(button)
}
}
#[inline]
pub fn get_mouse_x(&self) -> i32 {
unsafe {
ffi::GetMouseX()
}
}
#[inline]
pub fn get_mouse_y(&self) -> i32 {
unsafe {
ffi::GetMouseY()
}
}
#[inline]
pub fn get_mouse_position(&self) -> Vector2 {
unsafe {
ffi::GetMousePosition().into()
}
}
#[inline]
pub fn set_mouse_position(&self, position: impl Into<Vector2>) {
unsafe {
ffi::SetMousePosition(position.into().into());
}
}
#[inline]
pub fn set_mouse_scale(&self, scale: f32) {
unsafe {
ffi::SetMouseScale(scale);
}
}
#[inline]
pub fn get_mouse_wheel_move(&self) -> i32 {
unsafe {
ffi::GetMouseWheelMove()
}
}
#[inline]
pub fn get_touch_x(&self) -> i32 {
unsafe {
ffi::GetTouchX()
}
}
#[inline]
pub fn get_touch_y(&self) -> i32 {
unsafe {
ffi::GetTouchY()
}
}
#[inline]
pub fn get_touch_position(&self, index: i32) -> Vector2 {
unsafe {
ffi::GetTouchPosition(index).into()
}
}
#[inline]
pub fn set_gestures_enabled(&self, gesture_flags: Gesture) {
unsafe {
ffi::SetGesturesEnabled(gesture_flags.0);
}
}
#[inline]
pub fn is_gesture_detected(&self, gesture: Gesture) -> bool {
unsafe {
ffi::IsGestureDetected(gesture.0 as i32)
}
}
#[inline]
pub fn get_gesture_detected(&self) -> i32 {
unsafe {
ffi::GetGestureDetected()
}
}
#[inline]
pub fn get_touch_points_count(&self) -> i32 {
unsafe {
ffi::GetTouchPointsCount()
}
}
#[inline]
pub fn get_gesture_hold_duration(&self) -> f32 {
unsafe {
ffi::GetGestureHoldDuration()
}
}
#[inline]
pub fn get_gesture_drag_vector(&self) -> Vector2 {
unsafe {
ffi::GetGestureDragVector().into()
}
}
#[inline]
pub fn get_gesture_drag_angle(&self) -> f32 {
unsafe {
ffi::GetGestureDragAngle()
}
}
#[inline]
pub fn get_gesture_pinch_vector(&self) -> Vector2 {
unsafe {
ffi::GetGesturePinchVector().into()
}
}
#[inline]
pub fn get_gesture_pinch_angle(&self) -> f32 {
unsafe {
ffi::GetGesturePinchAngle()
}
}
#[inline]
pub fn set_camera_mode(&self, camera: Camera3D, mode: CameraMode) {
unsafe {
ffi::SetCameraMode(camera, mode as i32);
}
}
#[inline]
pub fn update_camera(&self, camera: &mut Camera3D) {
unsafe {
ffi::UpdateCamera(camera);
}
}
#[inline]
pub fn set_camera_pan_control(&self, pan_key: i32) {
unsafe {
ffi::SetCameraPanControl(pan_key);
}
}
#[inline]
pub fn set_camera_alt_control(&self, alt_key: i32) {
unsafe {
ffi::SetCameraAltControl(alt_key);
}
}
#[inline]
pub fn set_camera_smooth_zoom_control(&self, sz_key: i32) {
unsafe {
ffi::SetCameraSmoothZoomControl(sz_key);
}
}
#[inline]
pub fn set_camera_move_controls(&self,
front_key: i32,
back_key: i32,
right_key: i32,
left_key: i32,
up_key: i32,
down_key: i32)
{
unsafe {
ffi::SetCameraMoveControls(front_key, back_key, right_key, left_key, up_key, down_key);
}
}
#[inline]
pub fn draw_pixel(&self, x: i32, y: i32, color: impl Into<Color>) {
unsafe {
ffi::DrawPixel(x, y, color.into().into());
}
}
#[inline]
pub fn draw_pixel_v(&self, position: impl Into<Vector2>, color: impl Into<Color>) {
unsafe {
ffi::DrawPixelV(position.into().into(), color.into().into());
}
}
#[inline]
pub fn draw_line(&self, start_pos_x: i32, start_pos_y: i32, end_pos_x: i32, end_pos_y: i32, color: impl Into<Color>) {
unsafe {
ffi::DrawLine(start_pos_x, start_pos_y, end_pos_x, end_pos_y, color.into().into());
}
}
#[inline]
pub fn draw_line_v(&self, start_pos: impl Into<Vector2>, end_pos: impl Into<Vector2>, color: impl Into<Color>) {
unsafe {
ffi::DrawLineV(start_pos.into().into(), end_pos.into().into(), color.into().into());
}
}
#[inline]
pub fn draw_line_ex(&self, start_pos: impl Into<Vector2>, end_pos: impl Into<Vector2>, thick: f32, color: impl Into<Color>) {
unsafe {
ffi::DrawLineEx(start_pos.into().into(), end_pos.into().into(), thick, color.into().into());
}
}
#[inline]
pub fn draw_line_bezier(&self, start_pos: impl Into<Vector2>, end_pos: impl Into<Vector2>, thick: f32, color: impl Into<Color>) {
unsafe {
ffi::DrawLineBezier(start_pos.into().into(), end_pos.into().into(), thick, color.into().into());
}
}
#[inline]
pub fn draw_circle(&self, center_x: i32, center_y: i32, radius: f32, color: impl Into<Color>) {
unsafe {
ffi::DrawCircle(center_x, center_y, radius, color.into().into());
}
}
#[inline]
pub fn draw_circle_gradient(&self, center_x: i32, center_y: i32, radius: f32, color1: impl Into<Color>, color2: impl Into<Color>) {
unsafe {
ffi::DrawCircleGradient(center_x, center_y, radius, color1.into().into(), color2.into().into());
}
}
#[inline]
pub fn draw_circle_v(&self, center: impl Into<Vector2>, radius: f32, color: impl Into<Color>) {
unsafe {
ffi::DrawCircleV(center.into().into(), radius, color.into().into());
}
}
#[inline]
pub fn draw_circle_lines(&self, center_x: i32, center_y: i32, radius: f32, color: impl Into<Color>) {
unsafe {
ffi::DrawCircleLines(center_x, center_y, radius, color.into().into());
}
}
#[inline]
pub fn draw_rectangle(&self, x: i32, y: i32, width: i32, height: i32, color: impl Into<Color>) {
unsafe {
ffi::DrawRectangle(x, y, width, height, color.into().into());
}
}
#[inline]
pub fn draw_rectangle_v(&self, position: impl Into<Vector2>, size: impl Into<Vector2>, color: impl Into<Color>) {
unsafe {
ffi::DrawRectangleV(position.into().into(), size.into().into(), color.into().into());
}
}
#[inline]
pub fn draw_rectangle_rec(&self, rec: Rectangle, color: impl Into<Color>) {
unsafe {
ffi::DrawRectangleRec(rec, color.into().into());
}
}
#[inline]
pub fn draw_rectangle_pro(&self, rec: Rectangle, origin: impl Into<Vector2>, rotation: f32, color: impl Into<Color>) {
unsafe {
ffi::DrawRectanglePro(rec, origin.into().into(), rotation, color.into().into());
}
}
#[inline]
pub fn draw_rectangle_gradient_v(&self, x: i32, y: i32, width: i32, height: i32, color1: impl Into<Color>, color2: impl Into<Color>) {
unsafe {
ffi::DrawRectangleGradientV(x, y, width, height, color1.into().into(), color2.into().into());
}
}
#[inline]
pub fn draw_rectangle_gradient_h(&self, x: i32, y: i32, width: i32, height: i32, color1: impl Into<Color>, color2: impl Into<Color>) {
unsafe {
ffi::DrawRectangleGradientH(x, y, width, height, color1.into().into(), color2.into().into());
}
}
#[inline]
pub fn draw_rectangle_gradient_ex(&self, rec: Rectangle, col1: impl Into<Color>, col2: impl Into<Color>, col3: impl Into<Color>, col4: impl Into<Color>) {
unsafe {
ffi::DrawRectangleGradientEx(rec, col1.into().into(), col2.into().into(), col3.into().into(), col4.into().into());
}
}
#[inline]
pub fn draw_rectangle_lines(&self, x: i32, y: i32, width: i32, height: i32, color: impl Into<Color>) {
unsafe {
ffi::DrawRectangleLines(x, y, width, height, color.into().into());
}
}
#[inline]
pub fn draw_rectangle_lines_ex(&self, rec: Rectangle, line_thick: i32, color: impl Into<Color>) {
unsafe {
ffi::DrawRectangleLinesEx(rec, line_thick, color.into().into());
}
}
#[inline]
pub fn draw_triangle(&self, v1: impl Into<Vector2>, v2: impl Into<Vector2>, v3: impl Into<Vector2>, color: impl Into<Color>) {
unsafe {
ffi::DrawTriangle(v1.into().into(), v2.into().into(), v3.into().into(), color.into().into());
}
}
#[inline]
pub fn draw_triangle_lines(&self, v1: impl Into<Vector2>, v2: impl Into<Vector2>, v3: impl Into<Vector2>, color: impl Into<Color>) {
unsafe {
ffi::DrawTriangleLines(v1.into().into(), v2.into().into(), v3.into().into(), color.into().into());
}
}
#[inline]
pub fn draw_poly(&self, center: impl Into<Vector2>, sides: i32, radius: f32, rotation: f32, color: impl Into<Color>) {
unsafe {
ffi::DrawPoly(center.into().into(), sides, radius, rotation, color.into().into());
}
}
#[inline]
pub fn draw_poly_ex(&self, points: &mut [Vector2], color: impl Into<Color>) {
unsafe {
ffi::DrawPolyEx(points.as_mut_ptr() as *mut ffi::Vector2, points.len() as i32, color.into().into());
}
}
#[inline]
pub fn draw_poly_ex_lines(&self, points: &mut [Vector2], color: impl Into<Color>) {
unsafe {
ffi::DrawPolyExLines(points.as_mut_ptr() as *mut ffi::Vector2, points.len() as i32, color.into().into());
}
}
#[inline]
pub fn check_collision_recs(&self, rec1: Rectangle, rec2: Rectangle) -> bool {
unsafe {
ffi::CheckCollisionRecs(rec1, rec2)
}
}
#[inline]
pub fn check_collision_circles(&self, center1: impl Into<Vector2>, radius1: f32, center2: impl Into<Vector2>, radius2: f32) -> bool {
unsafe {
ffi::CheckCollisionCircles(center1.into().into(), radius1, center2.into().into(), radius2)
}
}
#[inline]
pub fn check_collision_circle_rec(&self, center: impl Into<Vector2>, radius: f32, rec: Rectangle) -> bool {
unsafe {
ffi::CheckCollisionCircleRec(center.into().into(), radius, rec)
}
}
#[inline]
pub fn get_collision_rec(&self, rec1: Rectangle, rec2: Rectangle) -> Rectangle {
unsafe {
ffi::GetCollisionRec(rec1, rec2)
}
}
#[inline]
pub fn check_collision_point_rec(&self, point: impl Into<Vector2>, rec: Rectangle) -> bool {
unsafe {
ffi::CheckCollisionPointRec(point.into().into(), rec)
}
}
#[inline]
pub fn check_collision_point_circle(&self, point: impl Into<Vector2>, center: impl Into<Vector2>, radius: f32) -> bool {
unsafe {
ffi::CheckCollisionPointCircle(point.into().into(), center.into().into(), radius)
}
}
#[inline]
pub fn check_collision_point_triangle(&self, point: impl Into<Vector2>, p1: impl Into<Vector2>, p2: impl Into<Vector2>, p3: impl Into<Vector2>) -> bool {
unsafe {
ffi::CheckCollisionPointTriangle(point.into().into(), p1.into().into(), p2.into().into(), p3.into().into())
}
}
#[inline]
pub fn load_image(&self, filename: &str) -> Image {
let c_filename = CString::new(filename).unwrap();
unsafe {
Image(ffi::LoadImage(c_filename.as_ptr()))
}
}
#[inline]
pub fn load_image_ex(&self, pixels: &mut [Color], width: i32, height: i32) -> Image {
let expected_len = (width * height) as usize;
if pixels.len() != expected_len {
panic!("load_image_ex: Data is wrong size. Expected {}, got {}", expected_len, pixels.len());
}
unsafe {
Image(ffi::LoadImageEx(pixels.as_mut_ptr() as *mut ffi::Color, width, height))
}
}
#[inline]
pub fn load_image_pro(&self, data: &[u8], width: i32, height: i32, format: PixelFormat) -> Image {
let expected_len = self.get_pixel_data_size(width, height, format) as usize;
if data.len() != expected_len {
panic!("load_image_pro: Data is wrong size. Expected {}, got {}", expected_len, data.len());
}
unsafe {
Image(ffi::LoadImagePro(data.as_ptr() as *mut std::os::raw::c_void, width, height, format as i32))
}
}
#[inline]
pub fn load_image_raw(&self, filename: &str, width: i32, height: i32, format: i32, header_size: i32) -> Image {
let c_filename = CString::new(filename).unwrap();
unsafe {
Image(ffi::LoadImageRaw(c_filename.as_ptr(), width, height, format, header_size))
}
}
#[inline]
pub fn export_image(&self, filename: &str, image: &Image) {
let c_filename = CString::new(filename).unwrap();
unsafe {
ffi::ExportImage(c_filename.as_ptr(), image.0);
}
}
#[inline]
pub fn load_texture(&self, filename: &str) -> Texture2D {
let c_filename = CString::new(filename).unwrap();
unsafe {
Texture2D(ffi::LoadTexture(c_filename.as_ptr()))
}
}
#[inline]
pub fn load_texture_from_image(&self, image: &Image) -> Texture2D {
unsafe {
Texture2D(ffi::LoadTextureFromImage(image.0))
}
}
#[inline]
pub fn load_render_texture(&self, width: i32, height: i32) -> RenderTexture2D {
unsafe {
RenderTexture2D(ffi::LoadRenderTexture(width, height))
}
}
#[inline]
pub fn get_image_data(&self, image: &Image) -> Vec<Color> {
unsafe {
let image_data = ffi::GetImageData(image.0);
let image_data_len = (image.width * image.height) as usize;
let mut safe_image_data: Vec<Color> = Vec::with_capacity(image_data_len);
safe_image_data.set_len(image_data_len);
std::ptr::copy(image_data, safe_image_data.as_mut_ptr() as *mut ffi::Color, image_data_len);
libc::free(image_data as *mut libc::c_void);
safe_image_data
}
}
#[inline]
pub fn get_image_data_normalized(&self, image: &Image) -> Vec<Vector4> {
unsafe {
let image_data = ffi::GetImageDataNormalized(image.0);
let image_data_len = (image.width * image.height) as usize;
let mut safe_image_data: Vec<Vector4> = Vec::with_capacity(image_data_len);
safe_image_data.set_len(image_data_len);
std::ptr::copy(image_data, safe_image_data.as_mut_ptr() as *mut ffi::Vector4, image_data_len);
libc::free(image_data as *mut libc::c_void);
safe_image_data
}
}
#[inline]
pub fn get_pixel_data_size(&self, width: i32, height: i32, format: PixelFormat) -> i32 {
unsafe {
ffi::GetPixelDataSize(width, height, format as i32)
}
}
#[inline]
pub fn get_texture_data(&self, texture: &Texture2D) -> Image {
unsafe {
Image(ffi::GetTextureData(texture.0))
}
}
#[inline]
pub fn update_texture(&self, texture: &mut Texture2D, pixels: &[u8]) {
let expected_len = self.get_pixel_data_size(texture.width, texture.height, texture.format.into()) as usize;
if pixels.len() != expected_len {
panic!("update_texture: Data is wrong size. Expected {}, got {}", expected_len, pixels.len());
}
unsafe {
ffi::UpdateTexture(texture.0, pixels.as_ptr() as *const std::os::raw::c_void);
}
}
#[inline]
pub fn image_copy(&self, image: &Image) -> Image {
unsafe {
Image(ffi::ImageCopy(image.0))
}
}
#[inline]
pub fn image_to_pot(&self, image: &mut Image, fill_color: impl Into<Color>) {
unsafe {
ffi::ImageToPOT(&mut image.0, fill_color.into().into());
}
}
#[inline]
pub fn image_format(&self, image: &mut Image, new_format: PixelFormat) {
unsafe {
ffi::ImageFormat(&mut image.0, new_format as i32);
}
}
#[inline]
pub fn image_alpha_mask(&self, image: &mut Image, alpha_mask: &Image) {
unsafe {
ffi::ImageAlphaMask(&mut image.0, alpha_mask.0);
}
}
#[inline]
pub fn image_alpha_clear(&self, image: &mut Image, color: impl Into<Color>, threshold: f32) {
unsafe {
ffi::ImageAlphaClear(&mut image.0, color.into().into(), threshold);
}
}
#[inline]
pub fn image_alpha_crop(&self, image: &mut Image, threshold: f32) {
unsafe {
ffi::ImageAlphaCrop(&mut image.0, threshold);
}
}
#[inline]
pub fn image_alpha_premultiply(&self, image: &mut Image) {
unsafe {
ffi::ImageAlphaPremultiply(&mut image.0);
}
}
#[inline]
pub fn image_crop(&self, image: &mut Image, crop: Rectangle) {
unsafe {
ffi::ImageCrop(&mut image.0, crop);
}
}
#[inline]
pub fn image_resize(&self, image: &mut Image, new_width: i32, new_height: i32) {
unsafe {
ffi::ImageResize(&mut image.0, new_width, new_height);
}
}
#[inline]
pub fn image_resize_nn(&self, image: &mut Image, new_width: i32, new_height: i32) {
unsafe {
ffi::ImageResizeNN(&mut image.0, new_width, new_height);
}
}
#[inline]
pub fn image_resize_canvas(&self, image: &mut Image, new_width: i32, new_height: i32, offset_x: i32, offset_y: i32, color: impl Into<Color>) {
unsafe {
ffi::ImageResizeCanvas(&mut image.0, new_width, new_height, offset_x, offset_y, color.into().into());
}
}
#[inline]
pub fn image_mipmaps(&self, image: &mut Image) {
unsafe {
ffi::ImageMipmaps(&mut image.0);
}
}
#[inline]
pub fn image_dither(&self, image: &mut Image, r_bpp: i32, g_bpp: i32, b_bpp: i32, a_bpp: i32) {
unsafe {
ffi::ImageDither(&mut image.0, r_bpp, g_bpp, b_bpp, a_bpp);
}
}
#[inline]
pub fn image_text(&self, text: &str, font_size: i32, color: impl Into<Color>) -> Image {
let c_text = CString::new(text).unwrap();
unsafe {
Image(ffi::ImageText(c_text.as_ptr(), font_size, color.into().into()))
}
}
#[inline]
pub fn image_text_ex(&self, font: &Font, text: &str, font_size: f32, spacing: f32, tint: impl Into<Color>) -> Image {
let c_text = CString::new(text).unwrap();
unsafe {
Image(ffi::ImageTextEx(font.0, c_text.as_ptr(), font_size, spacing, tint.into().into()))
}
}
#[inline]
pub fn image_draw(&self, dst: &mut Image, src: &Image, src_rec: Rectangle, dst_rec: Rectangle) {
unsafe {
ffi::ImageDraw(&mut dst.0, src.0, src_rec, dst_rec);
}
}
#[inline]
pub fn image_draw_rectangle(&self, dst: &mut Image, position: impl Into<Vector2>, rec: Rectangle, color: impl Into<Color>) {
unsafe {
ffi::ImageDrawRectangle(&mut dst.0, position.into().into(), rec, color.into().into());
}
}
#[inline]
pub fn image_draw_text(&self, dst: &mut Image, position: impl Into<Vector2>, text: &str, font_size: i32, color: impl Into<Color>) {
let c_text = CString::new(text).unwrap();
unsafe {
ffi::ImageDrawText(&mut dst.0, position.into().into(), c_text.as_ptr(), font_size, color.into().into());
}
}
#[inline]
pub fn image_draw_text_ex(&self, dst: &mut Image, position: impl Into<Vector2>, font: &Font, text: &str, font_size: f32, spacing: f32, color: impl Into<Color>) {
let c_text = CString::new(text).unwrap();
unsafe {
ffi::ImageDrawTextEx(&mut dst.0, position.into().into(), font.0, c_text.as_ptr(), font_size, spacing, color.into().into());
}
}
#[inline]
pub fn image_flip_vertical(&self, image: &mut Image) {
unsafe {
ffi::ImageFlipVertical(&mut image.0);
}
}
#[inline]
pub fn image_flip_horizontal(&self, image: &mut Image) {
unsafe {
ffi::ImageFlipHorizontal(&mut image.0);
}
}
#[inline]
pub fn image_rotate_cw(&self, image: &mut Image) {
unsafe {
ffi::ImageRotateCW(&mut image.0);
}
}
#[inline]
pub fn image_rotate_ccw(&self, image: &mut Image) {
unsafe {
ffi::ImageRotateCCW(&mut image.0);
}
}
#[inline]
pub fn image_color_tint(&self, image: &mut Image, color: impl Into<Color>) {
unsafe {
ffi::ImageColorTint(&mut image.0, color.into().into());
}
}
#[inline]
pub fn image_color_invert(&self, image: &mut Image) {
unsafe {
ffi::ImageColorInvert(&mut image.0);
}
}
#[inline]
pub fn image_color_grayscale(&self, image: &mut Image) {
unsafe {
ffi::ImageColorGrayscale(&mut image.0);
}
}
#[inline]
pub fn image_color_contrast(&self, image: &mut Image, contrast: f32) {
unsafe {
ffi::ImageColorContrast(&mut image.0, contrast);
}
}
#[inline]
pub fn image_color_brightness(&self, image: &mut Image, brightness: i32) {
unsafe {
ffi::ImageColorBrightness(&mut image.0, brightness);
}
}
#[inline]
pub fn image_color_replace(&self, image: &mut Image, color: impl Into<Color>, replace: impl Into<Color>) {
unsafe {
ffi::ImageColorReplace(&mut image.0, color.into().into(), replace.into().into());
}
}
#[inline]
pub fn gen_image_color(&self, width: i32, height: i32, color: impl Into<Color>) -> Image {
unsafe {
Image(ffi::GenImageColor(width, height, color.into().into()))
}
}
#[inline]
pub fn gen_image_gradient_v(&self, width: i32, height: i32, top: impl Into<Color>, bottom: impl Into<Color>) -> Image {
unsafe {
Image(ffi::GenImageGradientV(width, height, top.into().into(), bottom.into().into()))
}
}
#[inline]
pub fn gen_image_gradient_h(&self, width: i32, height: i32, left: impl Into<Color>, right: impl Into<Color>) -> Image {
unsafe {
Image(ffi::GenImageGradientH(width, height, left.into().into(), right.into().into()))
}
}
#[inline]
pub fn gen_image_gradient_radial(&self, width: i32, height: i32, density: f32, inner: impl Into<Color>, outer: impl Into<Color>) -> Image {
unsafe {
Image(ffi::GenImageGradientRadial(width, height, density, inner.into().into(), outer.into().into()))
}
}
#[inline]
pub fn gen_image_checked(&self, width: i32, height: i32, checks_x: i32, checks_y: i32, col1: impl Into<Color>, col2: impl Into<Color>) -> Image {
unsafe {
Image(ffi::GenImageChecked(width, height, checks_x, checks_y, col1.into().into(), col2.into().into()))
}
}
#[inline]
pub fn gen_image_white_noise(&self, width: i32, height: i32, factor: f32) -> Image {
unsafe {
Image(ffi::GenImageWhiteNoise(width, height, factor))
}
}
#[inline]
pub fn gen_image_perlin_noise(&self, width: i32, height: i32, offset_x: i32, offset_y: i32, scale: f32) -> Image {
unsafe {
Image(ffi::GenImagePerlinNoise(width, height, offset_x, offset_y, scale))
}
}
#[inline]
pub fn gen_image_cellular(&self, width: i32, height: i32, tile_size: i32) -> Image {
unsafe {
Image(ffi::GenImageCellular(width, height, tile_size))
}
}
#[inline]
pub fn gen_texture_mipmaps(&self, texture: &mut Texture2D) {
unsafe {
ffi::GenTextureMipmaps(&mut texture.0);
}
}
#[inline]
pub fn set_texture_filter(&self, texture: &mut Texture2D, filter_mode: TextureFilter) {
unsafe {
ffi::SetTextureFilter(texture.0, filter_mode as i32);
}
}
#[inline]
pub fn set_texture_wrap(&self, texture: &mut Texture2D, wrap_mode: TextureWrap) {
unsafe {
ffi::SetTextureWrap(texture.0, wrap_mode as i32);
}
}
#[inline]
pub fn draw_texture(&self, texture: &Texture2D, x: i32, y: i32, tint: impl Into<Color>) {
unsafe {
ffi::DrawTexture(texture.0, x, y, tint.into().into());
}
}
#[inline]
pub fn draw_texture_v(&self, texture: &Texture2D, position: impl Into<Vector2>, tint: impl Into<Color>) {
unsafe {
ffi::DrawTextureV(texture.0, position.into().into(), tint.into().into());
}
}
#[inline]
pub fn draw_texture_ex(&self, texture: &Texture2D, position: impl Into<Vector2>, rotation: f32, scale: f32, tint: impl Into<Color>) {
unsafe {
ffi::DrawTextureEx(texture.0, position.into().into(), rotation, scale, tint.into().into());
}
}
#[inline]
pub fn draw_texture_rec(&self, texture: &Texture2D, source_rec: Rectangle, position: impl Into<Vector2>, tint: impl Into<Color>) {
unsafe {
ffi::DrawTextureRec(texture.0, source_rec, position.into().into(), tint.into().into());
}
}
#[inline]
pub fn draw_texture_pro(&self, texture: &Texture2D, source_rec: Rectangle, dest_rec: Rectangle, origin: impl Into<Vector2>, rotation: f32, tint: impl Into<Color>) {
unsafe {
ffi::DrawTexturePro(texture.0, source_rec, dest_rec, origin.into().into(), rotation, tint.into().into());
}
}
#[inline]
pub fn get_font_default(&self) -> &'static Font {
&FONT_DEFAULT
}
#[inline]
pub fn load_font(&self, filename: &str) -> Font {
let c_filename = CString::new(filename).unwrap();
unsafe {
Font(ffi::LoadFont(c_filename.as_ptr()))
}
}
#[inline]
pub fn load_font_ex(&self, filename: &str, font_size: i32, chars: Option<&[i32]>) -> Font {
let c_filename = CString::new(filename).unwrap();
unsafe {
match chars {
Some(c) => Font(ffi::LoadFontEx(c_filename.as_ptr(), font_size, c.len() as i32, c.as_ptr() as *mut i32)),
None => Font(ffi::LoadFontEx(c_filename.as_ptr(), font_size, 0, std::ptr::null_mut()))
}
}
}
#[inline]
pub fn load_font_data(&self, filename: &str, font_size: i32, chars: Option<&[i32]>, sdf: bool) -> Vec<CharInfo> {
let c_filename = CString::new(filename).unwrap();
unsafe {
let ci_arr_ptr = match chars {
Some(c) => {
ffi::LoadFontData(c_filename.as_ptr(), font_size, c.as_ptr() as *mut i32, c.len() as i32, sdf)
}
None => {
ffi::LoadFontData(c_filename.as_ptr(), font_size, std::ptr::null_mut(), 0, sdf)
}
};
let ci_size = if let Some(c) = chars { c.len() } else { 95 }; let mut ci_vec = Vec::with_capacity(ci_size);
for i in 0..ci_size {
ci_vec.push(*ci_arr_ptr.offset(i as isize));
}
libc::free(ci_arr_ptr as *mut libc::c_void);
ci_vec
}
}
#[inline]
pub fn gen_image_font_atlas(&self, chars: &mut [CharInfo], font_size: i32, padding: i32, pack_method: i32) -> Image {
unsafe {
Image(ffi::GenImageFontAtlas(chars.as_mut_ptr(), font_size, chars.len() as i32, padding, pack_method))
}
}
#[inline]
pub fn draw_fps(&self, x: i32, y: i32) {
unsafe {
ffi::DrawFPS(x, y);
}
}
#[inline]
pub fn draw_text(&self, text: &str, x: i32, y: i32, font_size: i32, color: impl Into<Color>) {
let c_text = CString::new(text).unwrap();
unsafe {
ffi::DrawText(c_text.as_ptr(), x, y, font_size, color.into().into());
}
}
#[inline]
pub fn draw_text_ex(&self, font: &Font, text: &str, position: impl Into<Vector2>, font_size: f32, spacing: f32, tint: impl Into<Color>) {
let c_text = CString::new(text).unwrap();
unsafe {
ffi::DrawTextEx(font.0, c_text.as_ptr(), position.into().into(), font_size, spacing, tint.into().into());
}
}
#[inline]
pub fn measure_text(&self, text: &str, font_size: i32) -> i32 {
let c_text = CString::new(text).unwrap();
unsafe {
ffi::MeasureText(c_text.as_ptr(), font_size)
}
}
#[inline]
pub fn measure_text_ex(&self, font: &Font, text: &str, font_size: f32, spacing: f32) -> Vector2 {
let c_text = CString::new(text).unwrap();
unsafe {
ffi::MeasureTextEx(font.0, c_text.as_ptr(), font_size, spacing).into()
}
}
#[inline]
pub fn get_glyph_index(&self, font: &Font, character: i32) -> i32 {
unsafe {
ffi::GetGlyphIndex(font.0, character)
}
}
#[inline]
pub fn draw_line_3d(&self, start_pos: impl Into<Vector3>, end_pos: impl Into<Vector3>, color: impl Into<Color>) {
unsafe {
ffi::DrawLine3D(start_pos.into().into(), end_pos.into().into(), color.into().into());
}
}
#[inline]
pub fn draw_circle_3d(&self, center: impl Into<Vector3>, radius: f32, rotation_axis: impl Into<Vector3>, rotation_angle: f32, color: impl Into<Color>) {
unsafe {
ffi::DrawCircle3D(center.into().into(), radius, rotation_axis.into().into(), rotation_angle, color.into().into());
}
}
#[inline]
pub fn draw_cube(&self, position: impl Into<Vector3>, width: f32, height: f32, length: f32, color: impl Into<Color>) {
unsafe {
ffi::DrawCube(position.into().into(), width, height, length, color.into().into());
}
}
#[inline]
pub fn draw_cube_v(&self, position: impl Into<Vector3>, size: impl Into<Vector3>, color: impl Into<Color>) {
unsafe {
ffi::DrawCubeV(position.into().into(), size.into().into(), color.into().into());
}
}
#[inline]
pub fn draw_cube_wires(&self, position: impl Into<Vector3>, width: f32, height: f32, length: f32, color: impl Into<Color>) {
unsafe {
ffi::DrawCubeWires(position.into().into(), width, height, length, color.into().into());
}
}
#[inline]
pub fn draw_cube_texture(&self, texture: &Texture2D, position: impl Into<Vector3>, width: f32, height: f32, length: f32, color: impl Into<Color>) {
unsafe {
ffi::DrawCubeTexture(texture.0, position.into().into(), width, height, length, color.into().into());
}
}
#[inline]
pub fn draw_sphere(&self, center_pos: impl Into<Vector3>, radius: f32, color: impl Into<Color>) {
unsafe {
ffi::DrawSphere(center_pos.into().into(), radius, color.into().into());
}
}
#[inline]
pub fn draw_sphere_ex(&self, center_pos: impl Into<Vector3>, radius: f32, rings: i32, slices: i32, color: impl Into<Color>) {
unsafe {
ffi::DrawSphereEx(center_pos.into().into(), radius, rings, slices, color.into().into());
}
}
#[inline]
pub fn draw_sphere_wires(&self, center_pos: impl Into<Vector3>, radius: f32, rings: i32, slices: i32, color: impl Into<Color>) {
unsafe {
ffi::DrawSphereWires(center_pos.into().into(), radius, rings, slices, color.into().into());
}
}
#[inline]
pub fn draw_cylinder(&self, position: impl Into<Vector3>, radius_top: f32, radius_bottom: f32, height: f32, slices: i32, color: impl Into<Color>) {
unsafe {
ffi::DrawCylinder(position.into().into(), radius_top, radius_bottom, height, slices, color.into().into());
}
}
#[inline]
pub fn draw_cylinder_wires(&self, position: impl Into<Vector3>, radius_top: f32, radius_bottom: f32, height: f32, slices: i32, color: impl Into<Color>) {
unsafe {
ffi::DrawCylinderWires(position.into().into(), radius_top, radius_bottom, height, slices, color.into().into());
}
}
#[inline]
pub fn draw_plane(&self, center_pos: impl Into<Vector3>, size: impl Into<Vector2>, color: impl Into<Color>) {
unsafe {
ffi::DrawPlane(center_pos.into().into(), size.into().into(), color.into().into());
}
}
#[inline]
pub fn draw_ray(&self, ray: Ray, color: impl Into<Color>) {
unsafe {
ffi::DrawRay(ray, color.into().into());
}
}
#[inline]
pub fn draw_grid(&self, slices: i32, spacing: f32) {
unsafe {
ffi::DrawGrid(slices, spacing);
}
}
#[inline]
pub fn draw_gizmo(&self, position: impl Into<Vector3>) {
unsafe {
ffi::DrawGizmo(position.into().into());
}
}
#[inline]
pub fn load_model(&self, filename: &str) -> Model {
let c_filename = CString::new(filename).unwrap();
unsafe {
Model(ffi::LoadModel(c_filename.as_ptr()))
}
}
#[inline]
pub fn load_model_from_mesh(&self, mesh: Mesh) -> Model {
unsafe {
let m = mesh.0;
std::mem::forget(mesh);
Model(ffi::LoadModelFromMesh(m))
}
}
#[inline]
pub fn load_mesh(&self, filename: &str) -> Mesh {
let c_filename = CString::new(filename).unwrap();
unsafe {
Mesh(ffi::LoadMesh(c_filename.as_ptr()))
}
}
#[inline]
pub fn export_mesh(&self, filename: &str, mesh: &Mesh) {
let c_filename = CString::new(filename).unwrap();
unsafe {
ffi::ExportMesh(c_filename.as_ptr(), mesh.0);
}
}
#[inline]
pub fn mesh_bounding_box(&self, mesh: &Mesh) -> BoundingBox {
unsafe {
ffi::MeshBoundingBox(mesh.0)
}
}
#[inline]
pub fn mesh_tangents(&self, mesh: &mut Mesh) {
unsafe {
ffi::MeshTangents(&mut mesh.0);
}
}
#[inline]
pub fn mesh_binormals(&self, mesh: &mut Mesh) {
unsafe {
ffi::MeshBinormals(&mut mesh.0);
}
}
#[inline]
pub fn gen_mesh_plane(&self, width: f32, length: f32, res_x: i32, res_z: i32) -> Mesh {
unsafe {
Mesh(ffi::GenMeshPlane(width, length, res_x, res_z))
}
}
#[inline]
pub fn gen_mesh_cube(&self, width: f32, height: f32, length: f32) -> Mesh {
unsafe {
Mesh(ffi::GenMeshCube(width, height, length))
}
}
#[inline]
pub fn gen_mesh_sphere(&self, radius: f32, rings: i32, slices: i32) -> Mesh {
unsafe {
Mesh(ffi::GenMeshSphere(radius, rings, slices))
}
}
#[inline]
pub fn gen_mesh_hemisphere(&self, radius: f32, rings: i32, slices: i32) -> Mesh {
unsafe {
Mesh(ffi::GenMeshHemiSphere(radius, rings, slices))
}
}
#[inline]
pub fn gen_mesh_cylinder(&self, radius: f32, height: f32, slices: i32) -> Mesh {
unsafe {
Mesh(ffi::GenMeshCylinder(radius, height, slices))
}
}
#[inline]
pub fn gen_mesh_torus(&self, radius: f32, size: f32, rad_seg: i32, sides: i32) -> Mesh {
unsafe {
Mesh(ffi::GenMeshTorus(radius, size, rad_seg, sides))
}
}
#[inline]
pub fn gen_mesh_knot(&self, radius: f32, size: f32, rad_seg: i32, sides: i32) -> Mesh {
unsafe {
Mesh(ffi::GenMeshKnot(radius, size, rad_seg, sides))
}
}
#[inline]
pub fn gen_mesh_heightmap(&self, heightmap: &Image, size: impl Into<Vector3>) -> Mesh {
unsafe {
Mesh(ffi::GenMeshHeightmap(heightmap.0, size.into().into()))
}
}
#[inline]
pub fn gen_mesh_cubicmap(&self, cubicmap: &Image, cube_size: impl Into<Vector3>) -> Mesh {
unsafe {
Mesh(ffi::GenMeshCubicmap(cubicmap.0, cube_size.into().into()))
}
}
#[inline]
pub fn load_material(&self, filename: &str) -> Material {
let c_filename = CString::new(filename).unwrap();
unsafe {
Material(ffi::LoadMaterial(c_filename.as_ptr()))
}
}
#[inline]
pub fn load_material_default(&self) -> &'static Material {
&MATERIAL_DEFAULT
}
#[inline]
pub fn draw_model(&self, model: &Model, position: impl Into<Vector3>, scale: f32, tint: impl Into<Color>) {
unsafe {
ffi::DrawModel(model.0, position.into().into(), scale, tint.into().into());
}
}
#[inline]
pub fn draw_model_ex(&self, model: &Model, position: impl Into<Vector3>, rotation_axis: impl Into<Vector3>, rotation_angle: f32, scale: impl Into<Vector3>, tint: impl Into<Color>) {
unsafe {
ffi::DrawModelEx(model.0, position.into().into(), rotation_axis.into().into(), rotation_angle, scale.into().into(), tint.into().into());
}
}
#[inline]
pub fn draw_model_wires(&self, model: &Model, position: impl Into<Vector3>, scale: f32, tint: impl Into<Color>) {
unsafe {
ffi::DrawModelWires(model.0, position.into().into(), scale, tint.into().into());
}
}
#[inline]
pub fn draw_model_wires_ex(&self, model: &Model, position: impl Into<Vector3>, rotation_axis: impl Into<Vector3>, rotation_angle: f32, scale: impl Into<Vector3>, tint: impl Into<Color>) {
unsafe {
ffi::DrawModelWiresEx(model.0, position.into().into(), rotation_axis.into().into(), rotation_angle, scale.into().into(), tint.into().into());
}
}
#[inline]
pub fn draw_bounding_box(&self, bbox: BoundingBox, color: impl Into<Color>) {
unsafe {
ffi::DrawBoundingBox(bbox, color.into().into());
}
}
#[inline]
pub fn draw_billboard(&self, camera: Camera3D, texture: &Texture2D, center: impl Into<Vector3>, size: f32, tint: impl Into<Color>) {
unsafe {
ffi::DrawBillboard(camera, texture.0, center.into().into(), size, tint.into().into());
}
}
#[inline]
pub fn draw_billboard_rec(&self, camera: Camera3D, texture: &Texture2D, source_rec: Rectangle, center: impl Into<Vector3>, size: f32, tint: impl Into<Color>) {
unsafe {
ffi::DrawBillboardRec(camera, texture.0, source_rec, center.into().into(), size, tint.into().into());
}
}
#[inline]
pub fn check_collision_spheres(&self, center_a: impl Into<Vector3>, radius_a: f32, center_b: impl Into<Vector3>, radius_b: f32) -> bool {
unsafe {
ffi::CheckCollisionSpheres(center_a.into().into(), radius_a, center_b.into().into(), radius_b)
}
}
#[inline]
pub fn check_collision_boxes(&self, box1: BoundingBox, box2: BoundingBox) -> bool {
unsafe {
ffi::CheckCollisionBoxes(box1, box2)
}
}
#[inline]
pub fn check_collision_box_sphere(&self, bbox: BoundingBox, center_sphere: impl Into<Vector3>, radius_sphere: f32) -> bool {
unsafe {
ffi::CheckCollisionBoxSphere(bbox, center_sphere.into().into(), radius_sphere)
}
}
#[inline]
pub fn check_collision_ray_sphere(&self, ray: Ray, sphere_position: impl Into<Vector3>, sphere_radius: f32) -> bool {
unsafe {
ffi::CheckCollisionRaySphere(ray, sphere_position.into().into(), sphere_radius)
}
}
#[inline]
pub fn check_collision_ray_sphere_ex(&self, ray: Ray, sphere_position: impl Into<Vector3>, sphere_radius: f32) -> Option<Vector3> {
unsafe {
let mut col_point = ffi::Vector3 { x: 0.0, y: 0.0, z: 0.0 };
let collision = ffi::CheckCollisionRaySphereEx(ray, sphere_position.into().into(), sphere_radius, &mut col_point);
if collision {
Some(col_point.into())
}
else {
None
}
}
}
#[inline]
pub fn check_collision_ray_box(&self, ray: Ray, bbox: BoundingBox) -> bool {
unsafe {
ffi::CheckCollisionRayBox(ray, bbox)
}
}
#[inline]
pub fn get_collision_ray_model(&self, ray: Ray, model: &Model) -> RayHitInfo {
unsafe {
let mut model = model.0;
ffi::GetCollisionRayModel(ray, &mut model)
}
}
#[inline]
pub fn get_collision_ray_triangle(&self, ray: Ray, p1: impl Into<Vector3>, p2: impl Into<Vector3>, p3: impl Into<Vector3>) -> RayHitInfo {
unsafe {
ffi::GetCollisionRayTriangle(ray, p1.into().into(), p2.into().into(), p3.into().into())
}
}
#[inline]
pub fn get_collision_ray_ground(&self, ray: Ray, ground_height: f32) -> RayHitInfo {
unsafe {
ffi::GetCollisionRayGround(ray, ground_height)
}
}
#[inline]
pub fn load_text(&self, filename: &str) -> String {
let c_filename = CString::new(filename).unwrap();
unsafe {
let text = ffi::LoadText(c_filename.as_ptr());
let safe_text = CStr::from_ptr(text).to_str().unwrap().to_owned();
libc::free(text as *mut libc::c_void);
safe_text
}
}
#[inline]
pub fn load_shader(&self, vs_filename: &str, fs_filename: &str) -> Shader {
let c_vs_filename = CString::new(vs_filename).unwrap();
let c_fs_filename = CString::new(fs_filename).unwrap();
unsafe {
Shader(ffi::LoadShader(c_vs_filename.as_ptr(), c_fs_filename.as_ptr()))
}
}
#[inline]
pub fn load_shader_code(&self, vs_code: &str, fs_code: &str) -> Shader {
let c_vs_code = CString::new(vs_code).unwrap();
let c_fs_code = CString::new(fs_code).unwrap();
unsafe {
Shader(ffi::LoadShaderCode(c_vs_code.as_ptr() as *mut i8, c_fs_code.as_ptr() as *mut i8))
}
}
#[inline]
pub fn get_shader_default(&self) -> &'static Shader {
&SHADER_DEFAULT
}
#[inline]
pub fn get_texture_default(&self) -> &'static Texture2D {
&TEXTURE_DEFAULT
}
#[inline]
pub fn get_shader_location(&self, shader: &Shader, uniform_name: &str) -> i32 {
let c_uniform_name = CString::new(uniform_name).unwrap();
unsafe {
ffi::GetShaderLocation(shader.0, c_uniform_name.as_ptr())
}
}
#[inline]
pub fn set_shader_value(&self, shader: &mut Shader, uniform_loc: i32, value: &[f32]) {
unsafe {
ffi::SetShaderValue(shader.0, uniform_loc, value.as_ptr(), value.len() as i32);
}
}
#[inline]
pub fn set_shader_value_i(&self, shader: &mut Shader, uniform_loc: i32, value: &[i32]) {
unsafe {
ffi::SetShaderValuei(shader.0, uniform_loc, value.as_ptr(), value.len() as i32);
}
}
#[inline]
pub fn set_shader_value_matrix(&self, shader: &mut Shader, uniform_loc: i32, mat: Matrix) {
unsafe {
ffi::SetShaderValueMatrix(shader.0, uniform_loc, mat.into());
}
}
#[inline]
pub fn set_matrix_projection(&self, proj: Matrix) {
unsafe {
ffi::SetMatrixProjection(proj.into());
}
}
#[inline]
pub fn set_matrix_modelview(&self, view: Matrix) {
unsafe {
ffi::SetMatrixModelview(view.into());
}
}
#[inline]
pub fn get_matrix_modelview(&self) -> Matrix {
unsafe {
ffi::GetMatrixModelview().into()
}
}
#[inline]
pub fn gen_texture_cubemap(&self, shader: &Shader, sky_hdr: &Texture2D, size: i32) -> Texture2D {
unsafe {
Texture2D(ffi::GenTextureCubemap(shader.0, sky_hdr.0, size))
}
}
#[inline]
pub fn gen_texture_irradiance(&self, shader: &Shader, cubemap: &Texture2D, size: i32) -> Texture2D {
unsafe {
Texture2D(ffi::GenTextureIrradiance(shader.0, cubemap.0, size))
}
}
#[inline]
pub fn gen_texture_prefilter(&self, shader: &Shader, cubemap: &Texture2D, size: i32) -> Texture2D {
unsafe {
Texture2D(ffi::GenTexturePrefilter(shader.0, cubemap.0, size))
}
}
#[inline]
pub fn gen_texture_brdf(&self, shader: &Shader, cubemap: &Texture2D, size: i32) -> Texture2D {
unsafe {
Texture2D(ffi::GenTextureBRDF(shader.0, cubemap.0, size))
}
}
#[inline]
pub fn begin_shader_mode(&self, shader: &Shader) {
unsafe {
ffi::BeginShaderMode(shader.0);
}
}
#[inline]
pub fn end_shader_mode(&self) {
unsafe {
ffi::EndShaderMode();
}
}
#[inline]
pub fn begin_blend_mode(&self, mode: BlendMode) {
unsafe {
ffi::BeginBlendMode(mode as i32);
}
}
#[inline]
pub fn end_blend_mode(&self) {
unsafe {
ffi::EndBlendMode();
}
}
#[inline]
pub fn get_vr_device_info(&self, vr_device_type: VrDevice) -> VrDeviceInfo {
unsafe {
ffi::GetVrDeviceInfo(vr_device_type as i32)
}
}
#[inline]
pub fn init_vr_simulator(&self, info: VrDeviceInfo) {
unsafe {
ffi::InitVrSimulator(info);
}
}
#[inline]
pub fn close_vr_simulator(&self) {
unsafe {
ffi::CloseVrSimulator();
}
}
#[inline]
pub fn is_vr_simulator_ready(&self) -> bool {
unsafe {
ffi::IsVrSimulatorReady()
}
}
#[inline]
pub fn set_vr_distortion_shader(&self, shader: &Shader) {
unsafe {
ffi::SetVrDistortionShader(shader.0);
}
}
#[inline]
pub fn update_vr_tracking(&self, camera: &mut Camera3D) {
unsafe {
ffi::UpdateVrTracking(camera);
}
}
#[inline]
pub fn toggle_vr_mode(&self) {
unsafe {
ffi::ToggleVrMode();
}
}
#[inline]
pub fn begin_vr_drawing(&self) {
unsafe {
ffi::BeginVrDrawing();
}
}
#[inline]
pub fn end_vr_drawing(&self) {
unsafe {
ffi::EndVrDrawing();
}
}
#[inline]
pub fn init_audio_device(&self) {
unsafe {
ffi::InitAudioDevice();
}
}
#[inline]
pub fn close_audio_device(&self) {
unsafe {
ffi::CloseAudioDevice();
}
}
#[inline]
pub fn is_audio_device_ready(&self) -> bool {
unsafe {
ffi::IsAudioDeviceReady()
}
}
#[inline]
pub fn set_master_volume(&self, volume: f32) {
unsafe {
ffi::SetMasterVolume(volume);
}
}
#[inline]
pub fn load_wave(&self, filename: &str) -> Wave {
let c_filename = CString::new(filename).unwrap();
unsafe {
Wave(ffi::LoadWave(c_filename.as_ptr()))
}
}
#[inline]
pub fn load_wave_ex(&self, data: &[u8], sample_count: i32, sample_rate: i32, sample_size: i32, channels: i32) -> Wave {
unsafe {
Wave(ffi::LoadWaveEx(data.as_ptr() as *mut std::os::raw::c_void, sample_count, sample_rate, sample_size, channels))
}
}
#[inline]
pub fn load_sound(&self, filename: &str) -> Sound {
let c_filename = CString::new(filename).unwrap();
unsafe {
Sound(ffi::LoadSound(c_filename.as_ptr()))
}
}
#[inline]
pub fn load_sound_from_wave(&self, wave: &Wave) -> Sound {
unsafe {
Sound(ffi::LoadSoundFromWave(wave.0))
}
}
#[inline]
pub fn update_sound(&self, sound: &mut Sound, data: &[impl AudioSample]) {
unsafe {
ffi::UpdateSound(sound.0, data.as_ptr() as *const std::os::raw::c_void, data.len() as i32);
}
}
#[inline]
pub fn play_sound(&self, sound: &Sound) {
unsafe {
ffi::PlaySound(sound.0);
}
}
#[inline]
pub fn pause_sound(&self, sound: &Sound) {
unsafe {
ffi::PauseSound(sound.0);
}
}
#[inline]
pub fn resume_sound(&self, sound: &Sound) {
unsafe {
ffi::ResumeSound(sound.0);
}
}
#[inline]
pub fn stop_sound(&self, sound: &Sound) {
unsafe {
ffi::StopSound(sound.0);
}
}
#[inline]
pub fn is_sound_playing(&self, sound: &Sound) -> bool {
unsafe {
ffi::IsSoundPlaying(sound.0)
}
}
#[inline]
pub fn set_sound_volume(&self, sound: &Sound, volume: f32) {
unsafe {
ffi::SetSoundVolume(sound.0, volume);
}
}
#[inline]
pub fn set_sound_pitch(&self, sound: &Sound, pitch: f32) {
unsafe {
ffi::SetSoundPitch(sound.0, pitch);
}
}
#[inline]
pub fn wave_format(&self, wave: &mut Wave, sample_rate: i32, sample_size: i32, channels: i32) {
unsafe {
ffi::WaveFormat(&mut wave.0, sample_rate, sample_size, channels);
}
}
#[inline]
pub fn wave_copy(&self, wave: &Wave) -> Wave {
unsafe {
Wave(ffi::WaveCopy(wave.0))
}
}
#[inline]
pub fn wave_crop(&self, wave: &mut Wave, init_sample: i32, final_sample: i32) {
unsafe {
ffi::WaveCrop(&mut wave.0, init_sample, final_sample);
}
}
#[inline]
pub fn get_wave_data(&self, wave: &Wave) -> Vec<f32> {
unsafe {
let data = ffi::GetWaveData(wave.0);
let data_size = (wave.sampleCount * wave.channels) as usize;
let mut samples = Vec::with_capacity(data_size);
samples.set_len(data_size);
std::ptr::copy(data, samples.as_mut_ptr(), data_size);
libc::free(data as *mut libc::c_void);
samples
}
}
#[inline]
pub fn load_music_stream(&self, filename: &str) -> Music {
let c_filename = CString::new(filename).unwrap();
unsafe {
Music(ffi::LoadMusicStream(c_filename.as_ptr()))
}
}
#[inline]
pub fn play_music_stream(&self, music: &mut Music) {
unsafe {
ffi::PlayMusicStream(music.0);
}
}
#[inline]
pub fn update_music_stream(&self, music: &mut Music) {
unsafe {
ffi::UpdateMusicStream(music.0);
}
}
#[inline]
pub fn stop_music_stream(&self, music: &mut Music) {
unsafe {
ffi::StopMusicStream(music.0);
}
}
#[inline]
pub fn pause_music_stream(&self, music: &mut Music) {
unsafe {
ffi::PauseMusicStream(music.0);
}
}
#[inline]
pub fn resume_music_stream(&self, music: &mut Music) {
unsafe {
ffi::ResumeMusicStream(music.0);
}
}
#[inline]
pub fn is_music_playing(&self, music: &Music) -> bool {
unsafe {
ffi::IsMusicPlaying(music.0)
}
}
#[inline]
pub fn set_music_volume(&self, music: &mut Music, volume: f32) {
unsafe {
ffi::SetMusicVolume(music.0, volume);
}
}
#[inline]
pub fn set_music_pitch(&self, music: &mut Music, pitch: f32) {
unsafe {
ffi::SetMusicPitch(music.0, pitch);
}
}
#[inline]
pub fn set_music_loop_count(&self, music: &mut Music, count: i32) {
unsafe {
ffi::SetMusicLoopCount(music.0, count);
}
}
#[inline]
pub fn get_music_time_length(&self, music: &Music) -> f32 {
unsafe {
ffi::GetMusicTimeLength(music.0)
}
}
#[inline]
pub fn get_music_time_played(&self, music: &Music) -> f32 {
unsafe {
ffi::GetMusicTimePlayed(music.0)
}
}
#[inline]
pub fn init_audio_stream(&self, sample_rate: u32, sample_size: u32, channels: u32) -> AudioStream {
unsafe {
AudioStream(ffi::InitAudioStream(sample_rate, sample_size, channels))
}
}
#[inline]
pub fn update_audio_stream(&self, stream: &mut AudioStream, data: &[impl AudioSample]) {
unsafe {
ffi::UpdateAudioStream(stream.0, data.as_ptr() as *const std::os::raw::c_void, data.len() as i32);
}
}
#[inline]
pub fn is_audio_buffer_processed(&self, stream: &AudioStream) -> bool {
unsafe {
ffi::IsAudioBufferProcessed(stream.0)
}
}
#[inline]
pub fn play_audio_stream(&self, stream: &mut AudioStream) {
unsafe {
ffi::PlayAudioStream(stream.0);
}
}
#[inline]
pub fn pause_audio_stream(&self, stream: &mut AudioStream) {
unsafe {
ffi::PauseAudioStream(stream.0);
}
}
#[inline]
pub fn resume_audio_stream(&self, stream: &mut AudioStream) {
unsafe {
ffi::ResumeAudioStream(stream.0);
}
}
#[inline]
pub fn is_audio_stream_playing(&self, stream: &AudioStream) -> bool {
unsafe {
ffi::IsAudioStreamPlaying(stream.0)
}
}
#[inline]
pub fn stop_audio_stream(&self, stream: &mut AudioStream) {
unsafe {
ffi::StopAudioStream(stream.0);
}
}
#[inline]
pub fn set_audio_stream_volume(&self, stream: &mut AudioStream, volume: f32) {
unsafe {
ffi::SetAudioStreamVolume(stream.0, volume);
}
}
#[inline]
pub fn set_audio_stream_pitch(&self, stream: &mut AudioStream, pitch: f32) {
unsafe {
ffi::SetAudioStreamPitch(stream.0, pitch);
}
}
}