use raylib_sys::Rectangle;
use crate::core::camera::Camera3D;
use crate::core::math::Ray;
use crate::core::math::{Vector2, Vector3};
use crate::core::texture::Texture2D;
use crate::core::vr::VrStereoConfig;
use crate::core::{RaylibHandle, RaylibThread};
use crate::ffi;
use crate::math::Matrix;
use crate::models::{Mesh, WeakMaterial};
use crate::text::Codepoints;
use std::convert::AsRef;
use std::ffi::CString;
use super::camera::Camera2D;
use super::shaders::{Shader, ShaderV};
impl RaylibHandle {
#[must_use]
pub fn begin_drawing(&mut self, _: &RaylibThread) -> RaylibDrawHandle {
unsafe {
ffi::BeginDrawing();
};
let d = RaylibDrawHandle(self);
d
}
pub fn draw(&mut self, _: &RaylibThread, mut func: impl FnMut(RaylibDrawHandle)) {
unsafe {
ffi::BeginDrawing();
};
func(RaylibDrawHandle(self));
unsafe {
ffi::EndDrawing();
};
}
}
pub struct RaylibDrawHandle<'a>(&'a mut RaylibHandle);
impl<'a> RaylibDrawHandle<'a> {
#[deprecated = "Calling begin_drawing within RaylibDrawHandle will result in a runtime error."]
#[doc(hidden)]
pub fn begin_drawing(&mut self, _: &RaylibThread) -> RaylibDrawHandle {
panic!("Nested begin_drawing call")
}
#[deprecated = "Calling draw within RaylibDrawHandle will result in a runtime error."]
#[doc(hidden)]
pub fn draw(&mut self, _: &RaylibThread, mut _func: impl FnMut(RaylibDrawHandle)) {
panic!("Nested draw call")
}
}
impl<'a> Drop for RaylibDrawHandle<'a> {
fn drop(&mut self) {
unsafe {
ffi::EndDrawing();
}
}
}
impl<'a> std::ops::Deref for RaylibDrawHandle<'a> {
type Target = RaylibHandle;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<'a> std::ops::DerefMut for RaylibDrawHandle<'a> {
fn deref_mut(&mut self) -> &mut RaylibHandle {
self.0
}
}
impl<'a> RaylibDraw for RaylibDrawHandle<'a> {}
pub struct RaylibTextureMode<'a, T>(&'a mut T, &'a mut ffi::RenderTexture2D);
impl<'a, T> Drop for RaylibTextureMode<'a, T> {
fn drop(&mut self) {
unsafe { ffi::EndTextureMode() }
}
}
impl<'a, T> std::ops::Deref for RaylibTextureMode<'a, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<'a, T> std::ops::DerefMut for RaylibTextureMode<'a, T> {
fn deref_mut(&mut self) -> &mut T {
self.0
}
}
pub trait RaylibTextureModeExt
where
Self: Sized,
{
#[must_use]
fn begin_texture_mode<'a>(
&'a mut self,
_: &RaylibThread,
framebuffer: &'a mut ffi::RenderTexture2D,
) -> RaylibTextureMode<Self> {
unsafe { ffi::BeginTextureMode(*framebuffer) }
RaylibTextureMode(self, framebuffer)
}
fn draw_texture_mode<'a>(
&'a mut self,
_: &RaylibThread,
framebuffer: &'a mut ffi::RenderTexture2D,
mut func: impl FnMut(RaylibTextureMode<Self>),
) {
unsafe { ffi::BeginTextureMode(*framebuffer) }
func(RaylibTextureMode(self, framebuffer));
}
}
impl<'a> RaylibTextureModeExt for RaylibDrawHandle<'a> {}
impl RaylibTextureModeExt for RaylibHandle {}
impl<'a, T> RaylibDraw for RaylibTextureMode<'a, T> {}
pub struct RaylibVRMode<'a, T>(&'a T, &'a mut VrStereoConfig);
impl<'a, T> Drop for RaylibVRMode<'a, T> {
fn drop(&mut self) {
unsafe { ffi::EndVrStereoMode() }
}
}
impl<'a, T> std::ops::Deref for RaylibVRMode<'a, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
pub trait RaylibVRModeExt
where
Self: Sized,
{
#[must_use]
fn begin_vr_stereo_mode<'a>(
&'a mut self,
_: &RaylibThread,
vr_config: &'a mut VrStereoConfig,
) -> RaylibVRMode<Self> {
unsafe { ffi::BeginVrStereoMode(*vr_config.as_ref()) }
RaylibVRMode(self, vr_config)
}
fn draw_vr_stereo_mode<'a>(
&'a mut self,
vr_config: &'a mut VrStereoConfig,
mut func: impl FnMut(RaylibVRMode<Self>),
) {
unsafe { ffi::BeginVrStereoMode(*vr_config.as_ref()) }
func(RaylibVRMode(&self, vr_config));
}
}
impl<D: RaylibDraw> RaylibVRModeExt for D {}
impl<'a, T> RaylibDraw for RaylibVRMode<'a, T> {}
pub struct RaylibMode2D<'a, T>(&'a mut T);
impl<'a, T> Drop for RaylibMode2D<'a, T> {
fn drop(&mut self) {
unsafe { ffi::EndMode2D() }
}
}
impl<'a, T> std::ops::Deref for RaylibMode2D<'a, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<'a, T> std::ops::DerefMut for RaylibMode2D<'a, T> {
fn deref_mut(&mut self) -> &mut T {
self.0
}
}
pub trait RaylibMode2DExt
where
Self: Sized,
{
#[allow(non_snake_case)]
#[must_use]
fn begin_mode2D(&mut self, camera: impl Into<ffi::Camera2D>) -> RaylibMode2D<Self> {
unsafe {
ffi::BeginMode2D(camera.into());
}
RaylibMode2D(self)
}
#[allow(non_snake_case)]
fn draw_mode2D(
&mut self,
camera: Camera2D,
mut func: impl FnMut(RaylibMode2D<Self>, Camera2D),
) {
unsafe {
ffi::BeginMode2D(camera.into());
}
func(RaylibMode2D(self), camera);
unsafe {
ffi::EndMode2D();
}
}
}
impl<D: RaylibDraw> RaylibMode2DExt for D {}
impl<'a, T> RaylibDraw for RaylibMode2D<'a, T> {}
pub struct RaylibMode3D<'a, T>(&'a mut T);
impl<'a, T> Drop for RaylibMode3D<'a, T> {
fn drop(&mut self) {
unsafe { ffi::EndMode3D() }
}
}
impl<'a, T> std::ops::Deref for RaylibMode3D<'a, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<'a, T> std::ops::DerefMut for RaylibMode3D<'a, T> {
fn deref_mut(&mut self) -> &mut T {
self.0
}
}
pub trait RaylibMode3DExt
where
Self: Sized,
{
#[allow(non_snake_case)]
#[must_use]
fn begin_mode3D(&mut self, camera: impl Into<ffi::Camera3D>) -> RaylibMode3D<Self> {
unsafe {
ffi::BeginMode3D(camera.into());
}
RaylibMode3D(self)
}
#[allow(non_snake_case)]
fn draw_mode3D(
&mut self,
camera: Camera3D,
mut func: impl FnMut(RaylibMode3D<Self>, Camera3D),
) {
unsafe {
ffi::BeginMode3D(camera.into());
}
func(RaylibMode3D(self), camera);
unsafe {
ffi::EndMode3D();
}
}
}
impl<D: RaylibDraw> RaylibMode3DExt for D {}
impl<'a, T> RaylibDraw for RaylibMode3D<'a, T> {}
impl<'a, T> RaylibDraw3D for RaylibMode3D<'a, T> {}
pub struct RaylibShaderMode<'a, T>(&'a mut T, &'a mut Shader);
impl<'a, T> Drop for RaylibShaderMode<'a, T> {
fn drop(&mut self) {
unsafe { ffi::EndShaderMode() }
}
}
impl<'a, T> std::ops::Deref for RaylibShaderMode<'a, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<'a, T> std::ops::DerefMut for RaylibShaderMode<'a, T> {
fn deref_mut(&mut self) -> &mut T {
self.0
}
}
pub trait RaylibShaderModeExt
where
Self: Sized,
{
#[must_use]
fn begin_shader_mode<'a>(&'a mut self, shader: &'a mut Shader) -> RaylibShaderMode<Self> {
unsafe { ffi::BeginShaderMode(*shader.as_ref()) }
RaylibShaderMode(self, shader)
}
fn draw_shader_mode<'a>(
&'a mut self,
shader: &'a mut Shader,
mut func: impl FnMut(RaylibShaderMode<Self>),
) {
unsafe { ffi::BeginShaderMode(*shader.as_ref()) }
func(RaylibShaderMode(self, shader));
}
}
impl<D: RaylibDraw> RaylibShaderModeExt for D {}
impl<'a, T> RaylibDraw for RaylibShaderMode<'a, T> {}
impl<'a, T> RaylibDraw3D for RaylibShaderMode<'a, T> {}
pub struct RaylibBlendMode<'a, T>(&'a mut T);
impl<'a, T> Drop for RaylibBlendMode<'a, T> {
fn drop(&mut self) {
unsafe { ffi::EndBlendMode() }
}
}
impl<'a, T> std::ops::Deref for RaylibBlendMode<'a, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<'a, T> std::ops::DerefMut for RaylibBlendMode<'a, T> {
fn deref_mut(&mut self) -> &mut T {
self.0
}
}
pub trait RaylibBlendModeExt
where
Self: Sized,
{
#[must_use]
fn begin_blend_mode(&mut self, blend_mode: crate::consts::BlendMode) -> RaylibBlendMode<Self> {
unsafe { ffi::BeginBlendMode((blend_mode as u32) as i32) }
RaylibBlendMode(self)
}
fn draw_blend_mode(
&mut self,
blend_mode: crate::consts::BlendMode,
mut func: impl FnMut(RaylibBlendMode<Self>),
) {
unsafe { ffi::BeginBlendMode((blend_mode as u32) as i32) }
func(RaylibBlendMode(self));
}
}
impl<D: RaylibDraw> RaylibBlendModeExt for D {}
impl<'a, T> RaylibDraw for RaylibBlendMode<'a, T> {}
impl<'a, T> RaylibDraw3D for RaylibBlendMode<'a, T> {}
pub struct RaylibScissorMode<'a, T>(&'a mut T);
impl<'a, T> Drop for RaylibScissorMode<'a, T> {
fn drop(&mut self) {
unsafe { ffi::EndScissorMode() }
}
}
impl<'a, T> std::ops::Deref for RaylibScissorMode<'a, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<'a, T> std::ops::DerefMut for RaylibScissorMode<'a, T> {
fn deref_mut(&mut self) -> &mut T {
self.0
}
}
pub trait RaylibScissorModeExt
where
Self: Sized,
{
#[must_use]
fn begin_scissor_mode(
&mut self,
x: i32,
y: i32,
width: i32,
height: i32,
) -> RaylibScissorMode<Self> {
unsafe { ffi::BeginScissorMode(x, y, width, height) }
RaylibScissorMode(self)
}
fn draw_scissor_mode(
&mut self,
x: i32,
y: i32,
width: i32,
height: i32,
mut func: impl FnMut(RaylibScissorMode<Self>),
) {
unsafe { ffi::BeginScissorMode(x, y, width, height) }
func(RaylibScissorMode(self));
}
}
impl<D: RaylibDraw> RaylibScissorModeExt for D {}
impl<'a, T> RaylibDraw for RaylibScissorMode<'a, T> {}
impl<'a, T: RaylibDraw3D> RaylibDraw3D for RaylibScissorMode<'a, T> {}
pub trait RaylibDraw {
#[inline]
fn clear_background(&mut self, color: impl Into<ffi::Color>) {
unsafe {
ffi::ClearBackground(color.into());
}
}
fn get_shapes_texture(&self) -> Texture2D {
Texture2D(unsafe { ffi::GetShapesTexture() })
}
fn get_shapes_texture_rectangle(&self) -> Rectangle {
unsafe { ffi::GetShapesTextureRectangle() }
}
fn set_shapes_texture(
&mut self,
texture: impl AsRef<ffi::Texture2D>,
source: impl Into<ffi::Rectangle>,
) {
unsafe { ffi::SetShapesTexture(*texture.as_ref(), source.into()) }
}
#[inline]
fn draw_pixel(&mut self, x: i32, y: i32, color: impl Into<ffi::Color>) {
unsafe {
ffi::DrawPixel(x, y, color.into());
}
}
#[inline]
fn draw_pixel_v(&mut self, position: impl Into<ffi::Vector2>, color: impl Into<ffi::Color>) {
unsafe {
ffi::DrawPixelV(position.into(), color.into());
}
}
#[inline]
fn draw_line(
&mut self,
start_pos_x: i32,
start_pos_y: i32,
end_pos_x: i32,
end_pos_y: i32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawLine(start_pos_x, start_pos_y, end_pos_x, end_pos_y, color.into());
}
}
#[inline]
fn draw_line_v(
&mut self,
start_pos: impl Into<ffi::Vector2>,
end_pos: impl Into<ffi::Vector2>,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawLineV(start_pos.into(), end_pos.into(), color.into());
}
}
#[inline]
fn draw_line_ex(
&mut self,
start_pos: impl Into<ffi::Vector2>,
end_pos: impl Into<ffi::Vector2>,
thick: f32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawLineEx(start_pos.into(), end_pos.into(), thick, color.into());
}
}
#[inline]
fn draw_line_bezier(
&mut self,
start_pos: impl Into<ffi::Vector2>,
end_pos: impl Into<ffi::Vector2>,
thick: f32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawLineBezier(start_pos.into(), end_pos.into(), thick, color.into());
}
}
fn draw_line_strip(&mut self, points: &[Vector2], color: impl Into<ffi::Color>) {
unsafe {
ffi::DrawLineStrip(
points.as_ptr() as *mut ffi::Vector2,
points.len() as i32,
color.into(),
);
}
}
#[inline]
fn draw_circle(
&mut self,
center_x: i32,
center_y: i32,
radius: f32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawCircle(center_x, center_y, radius, color.into());
}
}
#[inline]
fn draw_circle_sector(
&mut self,
center: impl Into<ffi::Vector2>,
radius: f32,
start_angle: f32,
end_angle: f32,
segments: i32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawCircleSector(
center.into(),
radius,
start_angle,
end_angle,
segments,
color.into(),
);
}
}
#[inline]
fn draw_circle_sector_lines(
&mut self,
center: impl Into<ffi::Vector2>,
radius: f32,
start_angle: f32,
end_angle: f32,
segments: i32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawCircleSectorLines(
center.into(),
radius,
start_angle,
end_angle,
segments,
color.into(),
);
}
}
#[inline]
fn draw_circle_gradient(
&mut self,
center_x: i32,
center_y: i32,
radius: f32,
color1: impl Into<ffi::Color>,
color2: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawCircleGradient(center_x, center_y, radius, color1.into(), color2.into());
}
}
#[inline]
fn draw_circle_v(
&mut self,
center: impl Into<ffi::Vector2>,
radius: f32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawCircleV(center.into(), radius, color.into());
}
}
#[inline]
fn draw_circle_lines(
&mut self,
center_x: i32,
center_y: i32,
radius: f32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawCircleLines(center_x, center_y, radius, color.into());
}
}
#[inline]
fn draw_circle_lines_v(
&mut self,
center: impl Into<ffi::Vector2>,
radius: f32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawCircleLinesV(center.into(), radius, color.into());
}
}
#[inline]
fn draw_ellipse(
&mut self,
center_x: i32,
center_y: i32,
radius_h: f32,
radius_v: f32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawEllipse(center_x, center_y, radius_h, radius_v, color.into());
}
}
#[inline]
fn draw_ellipse_lines(
&mut self,
center_x: i32,
center_y: i32,
radius_h: f32,
radius_v: f32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawEllipseLines(center_x, center_y, radius_h, radius_v, color.into());
}
}
#[inline]
fn draw_ring(
&mut self,
center: impl Into<ffi::Vector2>,
inner_radius: f32,
outer_radius: f32,
start_angle: f32,
end_angle: f32,
segments: i32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawRing(
center.into(),
inner_radius,
outer_radius,
start_angle,
end_angle,
segments,
color.into(),
);
}
}
#[inline]
fn draw_ring_lines(
&mut self,
center: impl Into<ffi::Vector2>,
inner_radius: f32,
outer_radius: f32,
start_angle: f32,
end_angle: f32,
segments: i32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawRingLines(
center.into(),
inner_radius,
outer_radius,
start_angle,
end_angle,
segments,
color.into(),
);
}
}
#[inline]
fn draw_rectangle(
&mut self,
x: i32,
y: i32,
width: i32,
height: i32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawRectangle(x, y, width, height, color.into());
}
}
#[inline]
fn draw_rectangle_v(
&mut self,
position: impl Into<ffi::Vector2>,
size: impl Into<ffi::Vector2>,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawRectangleV(position.into(), size.into(), color.into());
}
}
#[inline]
fn draw_rectangle_rec(&mut self, rec: impl Into<ffi::Rectangle>, color: impl Into<ffi::Color>) {
unsafe {
ffi::DrawRectangleRec(rec.into(), color.into());
}
}
#[inline]
fn draw_rectangle_pro(
&mut self,
rec: impl Into<ffi::Rectangle>,
origin: impl Into<ffi::Vector2>,
rotation: f32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawRectanglePro(rec.into(), origin.into(), rotation, color.into());
}
}
#[inline]
fn draw_rectangle_gradient_v(
&mut self,
x: i32,
y: i32,
width: i32,
height: i32,
color1: impl Into<ffi::Color>,
color2: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawRectangleGradientV(x, y, width, height, color1.into(), color2.into());
}
}
#[inline]
fn draw_rectangle_gradient_h(
&mut self,
x: i32,
y: i32,
width: i32,
height: i32,
color1: impl Into<ffi::Color>,
color2: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawRectangleGradientH(x, y, width, height, color1.into(), color2.into());
}
}
#[inline]
fn draw_rectangle_gradient_ex(
&mut self,
rec: impl Into<ffi::Rectangle>,
col1: impl Into<ffi::Color>,
col2: impl Into<ffi::Color>,
col3: impl Into<ffi::Color>,
col4: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawRectangleGradientEx(
rec.into(),
col1.into(),
col2.into(),
col3.into(),
col4.into(),
);
}
}
#[inline]
fn draw_rectangle_lines(
&mut self,
x: i32,
y: i32,
width: i32,
height: i32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawRectangleLines(x, y, width, height, color.into());
}
}
#[inline]
fn draw_rectangle_lines_ex(
&mut self,
rec: impl Into<ffi::Rectangle>,
line_thick: f32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawRectangleLinesEx(rec.into(), line_thick, color.into());
}
}
#[inline]
fn draw_rectangle_rounded(
&mut self,
rec: impl Into<ffi::Rectangle>,
roundness: f32,
segments: i32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawRectangleRounded(rec.into(), roundness, segments, color.into());
}
}
#[inline]
fn draw_rectangle_rounded_lines(
&mut self,
rec: impl Into<ffi::Rectangle>,
roundness: f32,
segments: i32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawRectangleRoundedLines(rec.into(), roundness, segments, color.into());
}
}
fn draw_rectangle_rounded_lines_ex(
&mut self,
rec: impl Into<ffi::Rectangle>,
roundness: f32,
segments: i32,
line_thickness: f32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawRectangleRoundedLinesEx(
rec.into(),
roundness,
segments,
line_thickness,
color.into(),
)
};
}
#[inline]
fn draw_triangle(
&mut self,
v1: impl Into<ffi::Vector2>,
v2: impl Into<ffi::Vector2>,
v3: impl Into<ffi::Vector2>,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawTriangle(v1.into(), v2.into(), v3.into(), color.into());
}
}
#[inline]
fn draw_triangle_lines(
&mut self,
v1: impl Into<ffi::Vector2>,
v2: impl Into<ffi::Vector2>,
v3: impl Into<ffi::Vector2>,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawTriangleLines(v1.into(), v2.into(), v3.into(), color.into());
}
}
#[inline]
fn draw_triangle_fan(&mut self, points: &[Vector2], color: impl Into<ffi::Color>) {
unsafe {
ffi::DrawTriangleFan(
points.as_ptr() as *mut ffi::Vector2,
points.len() as i32,
color.into(),
);
}
}
#[inline]
fn draw_triangle_strip(&mut self, points: &[Vector2], color: impl Into<ffi::Color>) {
unsafe {
ffi::DrawTriangleStrip(
points.as_ptr() as *mut ffi::Vector2,
points.len() as i32,
color.into(),
);
}
}
#[inline]
fn draw_poly(
&mut self,
center: impl Into<ffi::Vector2>,
sides: i32,
radius: f32,
rotation: f32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawPoly(center.into(), sides, radius, rotation, color.into());
}
}
#[inline]
fn draw_poly_lines(
&mut self,
center: impl Into<ffi::Vector2>,
sides: i32,
radius: f32,
rotation: f32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawPolyLines(center.into(), sides, radius, rotation, color.into());
}
}
#[inline]
fn draw_texture(
&mut self,
texture: impl AsRef<ffi::Texture2D>,
x: i32,
y: i32,
tint: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawTexture(*texture.as_ref(), x, y, tint.into());
}
}
#[inline]
fn draw_texture_v(
&mut self,
texture: impl AsRef<ffi::Texture2D>,
position: impl Into<ffi::Vector2>,
tint: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawTextureV(*texture.as_ref(), position.into(), tint.into());
}
}
#[inline]
fn draw_texture_ex(
&mut self,
texture: impl AsRef<ffi::Texture2D>,
position: impl Into<ffi::Vector2>,
rotation: f32,
scale: f32,
tint: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawTextureEx(
*texture.as_ref(),
position.into(),
rotation,
scale,
tint.into(),
);
}
}
#[inline]
fn draw_texture_rec(
&mut self,
texture: impl AsRef<ffi::Texture2D>,
source_rec: impl Into<ffi::Rectangle>,
position: impl Into<ffi::Vector2>,
tint: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawTextureRec(
*texture.as_ref(),
source_rec.into(),
position.into(),
tint.into(),
);
}
}
#[inline]
fn draw_texture_pro(
&mut self,
texture: impl AsRef<ffi::Texture2D>,
source_rec: impl Into<ffi::Rectangle>,
dest_rec: impl Into<ffi::Rectangle>,
origin: impl Into<ffi::Vector2>,
rotation: f32,
tint: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawTexturePro(
*texture.as_ref(),
source_rec.into(),
dest_rec.into(),
origin.into(),
rotation,
tint.into(),
);
}
}
#[inline]
fn draw_texture_n_patch(
&mut self,
texture: impl AsRef<ffi::Texture2D>,
n_patch_info: impl Into<ffi::NPatchInfo>,
dest_rec: impl Into<ffi::Rectangle>,
origin: impl Into<ffi::Vector2>,
rotation: f32,
tint: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawTextureNPatch(
*texture.as_ref(),
n_patch_info.into(),
dest_rec.into(),
origin.into(),
rotation,
tint.into(),
);
}
}
#[inline]
fn draw_fps(&mut self, x: i32, y: i32) {
unsafe {
ffi::DrawFPS(x, y);
}
}
#[inline]
fn draw_text(
&mut self,
text: &str,
x: i32,
y: i32,
font_size: i32,
color: impl Into<ffi::Color>,
) {
let c_text = CString::new(text).unwrap();
unsafe {
ffi::DrawText(c_text.as_ptr(), x, y, font_size, color.into());
}
}
fn draw_text_codepoints(
&mut self,
font: impl AsRef<ffi::Font>,
text: &str,
position: Vector2,
font_size: f32,
spacing: f32,
tint: impl Into<ffi::Color>,
) {
unsafe {
let c_text = CString::new(text).unwrap();
let mut len = 0;
let u = ffi::LoadCodepoints(c_text.as_ptr(), &mut len);
ffi::DrawTextCodepoints(
*font.as_ref(),
u,
text.len() as i32,
position.into(),
font_size,
spacing,
tint.into(),
)
}
}
#[inline]
fn draw_text_ex(
&mut self,
font: impl AsRef<ffi::Font>,
text: &str,
position: impl Into<ffi::Vector2>,
font_size: f32,
spacing: f32,
tint: impl Into<ffi::Color>,
) {
let c_text = CString::new(text).unwrap();
unsafe {
ffi::DrawTextEx(
*font.as_ref(),
c_text.as_ptr(),
position.into(),
font_size,
spacing,
tint.into(),
);
}
}
fn draw_text_pro(
&mut self,
font: impl AsRef<ffi::Font>,
text: &str,
position: impl Into<ffi::Vector2>,
origin: impl Into<ffi::Vector2>,
rotation: f32,
font_size: f32,
spacing: f32,
tint: impl Into<ffi::Color>,
) {
let c_text = CString::new(text).unwrap();
unsafe {
ffi::DrawTextPro(
*font.as_ref(),
c_text.as_ptr(),
position.into(),
origin.into(),
rotation,
font_size,
spacing,
tint.into(),
);
}
}
#[inline]
fn draw_text_codepoint(
&mut self,
font: impl AsRef<ffi::Font>,
codepoint: i32,
position: impl Into<ffi::Vector2>,
scale: f32,
tint: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawTextCodepoint(
*font.as_ref(),
codepoint,
position.into(),
scale,
tint.into(),
);
}
}
fn enable_event_waiting(&self) {
unsafe { ffi::EnableEventWaiting() }
}
fn disable_event_waiting(&self) {
unsafe { ffi::DisableEventWaiting() }
}
fn draw_poly_lines_ex(
&mut self,
center: Vector2,
sides: i32,
radius: f32,
rotation: f32,
line_thick: f32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawPolyLinesEx(
center.into(),
sides,
radius,
rotation,
line_thick,
color.into(),
);
}
}
fn draw_spline_linear(&mut self, points: &[Vector2], thick: f32, color: impl Into<ffi::Color>) {
unsafe {
ffi::DrawSplineLinear(
points.as_ptr() as *mut ffi::Vector2,
points.len() as i32,
thick,
color.into(),
)
}
}
fn draw_spline_basis(&mut self, points: &[Vector2], thick: f32, color: impl Into<ffi::Color>) {
unsafe {
ffi::DrawSplineBasis(
points.as_ptr() as *mut ffi::Vector2,
points.len() as i32,
thick,
color.into(),
)
}
}
fn draw_spline_catmull_rom(
&mut self,
points: &[Vector2],
thick: f32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawSplineCatmullRom(
points.as_ptr() as *mut ffi::Vector2,
points.len() as i32,
thick,
color.into(),
)
}
}
fn draw_spline_bezier_quadratic(
&mut self,
points: &[Vector2],
thick: f32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawSplineBezierQuadratic(
points.as_ptr() as *mut ffi::Vector2,
points.len() as i32,
thick,
color.into(),
)
}
}
fn draw_spline_bezier_cubic(
&mut self,
points: &[Vector2],
thick: f32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawSplineBezierCubic(
points.as_ptr() as *mut ffi::Vector2,
points.len() as i32,
thick,
color.into(),
)
}
}
fn draw_spline_segment_linear(
&mut self,
p1: Vector2,
p2: Vector2,
thick: f32,
color: impl Into<ffi::Color>,
) {
unsafe { ffi::DrawSplineSegmentLinear(p1.into(), p2.into(), thick, color.into()) }
}
fn draw_spline_segment_basis(
&mut self,
p1: Vector2,
p2: Vector2,
p3: Vector2,
p4: Vector2,
thick: f32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawSplineSegmentBasis(
p1.into(),
p2.into(),
p3.into(),
p4.into(),
thick,
color.into(),
)
}
}
fn draw_spline_segment_catmull_rom(
&mut self,
p1: Vector2,
p2: Vector2,
p3: Vector2,
p4: Vector2,
thick: f32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawSplineSegmentCatmullRom(
p1.into(),
p2.into(),
p3.into(),
p4.into(),
thick,
color.into(),
)
}
}
fn draw_spline_segment_bezier_quadratic(
&mut self,
p1: Vector2,
c2: Vector2,
p3: Vector2,
thick: f32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawSplineSegmentBezierQuadratic(
p1.into(),
c2.into(),
p3.into(),
thick,
color.into(),
)
}
}
fn draw_spline_segment_bezier_cubic(
&mut self,
p1: Vector2,
c2: Vector2,
c3: Vector2,
p4: Vector2,
thick: f32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawSplineSegmentBezierCubic(
p1.into(),
c2.into(),
c3.into(),
p4.into(),
thick,
color.into(),
)
}
}
fn get_spline_point_linear(&mut self, start_pos: Vector2, end_pos: Vector2, t: f32) -> Vector2 {
unsafe { ffi::GetSplinePointLinear(start_pos.into(), end_pos.into(), t).into() }
}
fn get_spline_point_basis(
&mut self,
p1: Vector2,
p2: Vector2,
p3: Vector2,
p4: Vector2,
t: f32,
) -> Vector2 {
unsafe { ffi::GetSplinePointBasis(p1.into(), p2.into(), p3.into(), p4.into(), t).into() }
}
fn get_spline_point_catmull_rom(
&mut self,
p1: Vector2,
p2: Vector2,
p3: Vector2,
p4: Vector2,
t: f32,
) -> Vector2 {
unsafe {
ffi::GetSplinePointCatmullRom(p1.into(), p2.into(), p3.into(), p4.into(), t).into()
}
}
fn get_spline_point_bezier_quad(
&mut self,
p1: Vector2,
c2: Vector2,
p3: Vector2,
t: f32,
) -> Vector2 {
unsafe { ffi::GetSplinePointBezierQuad(p1.into(), c2.into(), p3.into(), t).into() }
}
fn get_spline_point_bezier_cubic(
&mut self,
p1: Vector2,
c2: Vector2,
c3: Vector2,
p4: Vector2,
t: f32,
) -> Vector2 {
unsafe {
ffi::GetSplinePointBezierCubic(p1.into(), c2.into(), c3.into(), p4.into(), t).into()
}
}
}
pub trait RaylibDraw3D {
#[allow(non_snake_case)]
#[inline]
fn draw_point3D(&mut self, position: impl Into<ffi::Vector3>, color: impl Into<ffi::Color>) {
unsafe {
ffi::DrawPoint3D(position.into(), color.into());
}
}
#[allow(non_snake_case)]
#[inline]
fn draw_triangle3D(
&mut self,
v1: impl Into<ffi::Vector3>,
v2: impl Into<ffi::Vector3>,
v3: impl Into<ffi::Vector3>,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawTriangle3D(v1.into(), v2.into(), v3.into(), color.into());
}
}
#[allow(non_snake_case)]
#[inline]
fn draw_triangle_strip3D(&mut self, points: &[Vector3], color: impl Into<ffi::Color>) {
unsafe {
ffi::DrawTriangleStrip3D(points.as_ptr() as *mut _, points.len() as i32, color.into());
}
}
#[inline]
#[allow(non_snake_case)]
fn draw_line_3D(
&mut self,
start_pos: impl Into<ffi::Vector3>,
end_pos: impl Into<ffi::Vector3>,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawLine3D(start_pos.into(), end_pos.into(), color.into());
}
}
#[inline]
#[allow(non_snake_case)]
fn draw_circle_3D(
&mut self,
center: impl Into<ffi::Vector3>,
radius: f32,
rotation_axis: impl Into<ffi::Vector3>,
rotation_angle: f32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawCircle3D(
center.into(),
radius,
rotation_axis.into(),
rotation_angle,
color.into(),
);
}
}
#[inline]
fn draw_cube(
&mut self,
position: impl Into<ffi::Vector3>,
width: f32,
height: f32,
length: f32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawCube(position.into(), width, height, length, color.into());
}
}
#[inline]
fn draw_cube_v(
&mut self,
position: impl Into<ffi::Vector3>,
size: impl Into<ffi::Vector3>,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawCubeV(position.into(), size.into(), color.into());
}
}
#[inline]
fn draw_cube_wires(
&mut self,
position: impl Into<ffi::Vector3>,
width: f32,
height: f32,
length: f32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawCubeWires(position.into(), width, height, length, color.into());
}
}
#[inline]
fn draw_cube_wires_v(
&mut self,
position: impl Into<ffi::Vector3>,
size: impl Into<ffi::Vector3>,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawCubeWiresV(position.into(), size.into(), color.into());
}
}
#[inline]
fn draw_mesh(
&mut self,
mesh: impl AsRef<ffi::Mesh>,
material: WeakMaterial,
transform: Matrix,
) {
unsafe { ffi::DrawMesh(*mesh.as_ref(), material.0, transform.into()) }
}
#[inline]
fn draw_mesh_instanced(
&mut self,
mesh: impl AsRef<ffi::Mesh>,
material: WeakMaterial,
transforms: &[Matrix],
) {
let tr = transforms
.iter()
.map(|f| f.into())
.collect::<Vec<ffi::Matrix>>()
.as_ptr();
unsafe { ffi::DrawMeshInstanced(*mesh.as_ref(), material.0, tr, transforms.len() as i32) }
}
#[inline]
fn draw_sphere(
&mut self,
center_pos: impl Into<ffi::Vector3>,
radius: f32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawSphere(center_pos.into(), radius, color.into());
}
}
#[inline]
fn draw_sphere_ex(
&mut self,
center_pos: impl Into<ffi::Vector3>,
radius: f32,
rings: i32,
slices: i32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawSphereEx(center_pos.into(), radius, rings, slices, color.into());
}
}
#[inline]
fn draw_sphere_wires(
&mut self,
center_pos: impl Into<ffi::Vector3>,
radius: f32,
rings: i32,
slices: i32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawSphereWires(center_pos.into(), radius, rings, slices, color.into());
}
}
#[inline]
fn draw_cylinder(
&mut self,
position: impl Into<ffi::Vector3>,
radius_top: f32,
radius_bottom: f32,
height: f32,
slices: i32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawCylinder(
position.into(),
radius_top,
radius_bottom,
height,
slices,
color.into(),
);
}
}
#[inline]
fn draw_cylinder_ex(
&mut self,
start_position: impl Into<ffi::Vector3>,
end_position: impl Into<ffi::Vector3>,
radius_start: f32,
radius_end: f32,
slices: i32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawCylinderEx(
start_position.into(),
end_position.into(),
radius_start,
radius_end,
slices,
color.into(),
);
}
}
#[inline]
fn draw_cylinder_wires(
&mut self,
position: impl Into<ffi::Vector3>,
radius_top: f32,
radius_bottom: f32,
height: f32,
slices: i32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawCylinderWires(
position.into(),
radius_top,
radius_bottom,
height,
slices,
color.into(),
);
}
}
#[inline]
fn draw_cylinder_wires_ex(
&mut self,
start_position: impl Into<ffi::Vector3>,
end_position: impl Into<ffi::Vector3>,
radius_start: f32,
radius_end: f32,
slices: i32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawCylinderWiresEx(
start_position.into(),
end_position.into(),
radius_start,
radius_end,
slices,
color.into(),
);
}
}
fn draw_capsule(
&mut self,
start_pos: impl Into<ffi::Vector3>,
end_pos: impl Into<ffi::Vector3>,
radius: f32,
slices: i32,
rings: i32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawCapsule(
start_pos.into(),
end_pos.into(),
radius,
slices,
rings,
color.into(),
)
}
}
fn draw_capsule_wires(
&mut self,
start_pos: impl Into<ffi::Vector3>,
end_pos: impl Into<ffi::Vector3>,
radius: f32,
slices: i32,
rings: i32,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawCapsuleWires(
start_pos.into(),
end_pos.into(),
radius,
slices,
rings,
color.into(),
)
}
}
#[inline]
fn draw_plane(
&mut self,
center_pos: impl Into<ffi::Vector3>,
size: impl Into<ffi::Vector2>,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawPlane(center_pos.into(), size.into(), color.into());
}
}
#[inline]
fn draw_ray(&mut self, ray: Ray, color: impl Into<ffi::Color>) {
unsafe {
ffi::DrawRay(ray.into(), color.into());
}
}
#[inline]
fn draw_grid(&mut self, slices: i32, spacing: f32) {
unsafe {
ffi::DrawGrid(slices, spacing);
}
}
#[inline]
fn draw_model(
&mut self,
model: impl AsRef<ffi::Model>,
position: impl Into<ffi::Vector3>,
scale: f32,
tint: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawModel(*model.as_ref(), position.into(), scale, tint.into());
}
}
#[inline]
fn draw_model_ex(
&mut self,
model: impl AsRef<ffi::Model>,
position: impl Into<ffi::Vector3>,
rotation_axis: impl Into<ffi::Vector3>,
rotation_angle: f32,
scale: impl Into<ffi::Vector3>,
tint: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawModelEx(
*model.as_ref(),
position.into(),
rotation_axis.into(),
rotation_angle,
scale.into(),
tint.into(),
);
}
}
#[inline]
fn draw_model_wires(
&mut self,
model: impl AsRef<ffi::Model>,
position: impl Into<ffi::Vector3>,
scale: f32,
tint: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawModelWires(*model.as_ref(), position.into(), scale, tint.into());
}
}
#[inline]
fn draw_model_wires_ex(
&mut self,
model: impl AsRef<ffi::Model>,
position: impl Into<ffi::Vector3>,
rotation_axis: impl Into<ffi::Vector3>,
rotation_angle: f32,
scale: impl Into<ffi::Vector3>,
tint: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawModelWiresEx(
*model.as_ref(),
position.into(),
rotation_axis.into(),
rotation_angle,
scale.into(),
tint.into(),
);
}
}
#[inline]
fn draw_bounding_box(
&mut self,
bbox: impl Into<ffi::BoundingBox>,
color: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawBoundingBox(bbox.into(), color.into());
}
}
#[inline]
fn draw_billboard(
&mut self,
camera: impl Into<ffi::Camera3D>,
texture: &Texture2D,
center: impl Into<ffi::Vector3>,
size: f32,
tint: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawBillboard(camera.into(), texture.0, center.into(), size, tint.into());
}
}
#[inline]
fn draw_billboard_rec(
&mut self,
camera: Camera3D,
texture: &Texture2D,
source_rec: impl Into<ffi::Rectangle>,
center: impl Into<ffi::Vector3>,
size: impl Into<ffi::Vector2>,
tint: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawBillboardRec(
camera.into(),
texture.0,
source_rec.into(),
center.into(),
size.into(),
tint.into(),
);
}
}
fn draw_billboard_pro(
&mut self,
camera: impl Into<ffi::Camera>,
texture: impl Into<ffi::Texture2D>,
source: impl Into<ffi::Rectangle>,
position: impl Into<ffi::Vector3>,
up: impl Into<ffi::Vector3>,
size: impl Into<ffi::Vector2>,
origin: impl Into<ffi::Vector2>,
rotation: f32,
tint: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawBillboardPro(
camera.into(),
texture.into(),
source.into(),
position.into(),
up.into(),
size.into(),
origin.into(),
rotation,
tint.into(),
)
}
}
fn draw_model_points(
&mut self,
model: impl Into<ffi::Model>,
position: impl Into<ffi::Vector3>,
scale: f32,
tint: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawModelPoints(model.into(), position.into(), scale, tint.into());
}
}
fn draw_model_points_ex(
&mut self,
model: impl Into<ffi::Model>,
position: impl Into<ffi::Vector3>,
rotation_axis: impl Into<ffi::Vector3>,
angle: f32,
scale: impl Into<ffi::Vector3>,
tint: impl Into<ffi::Color>,
) {
unsafe {
ffi::DrawModelPointsEx(
model.into(),
position.into(),
rotation_axis.into(),
angle,
scale.into(),
tint.into(),
);
}
}
}