1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
pub use lotus_shared::graphics::*;
pub mod textures {
use lotus_script_sys::FfiObject;
use lotus_shared::{content::ContentId, graphics::Color, math::UVec2};
pub use lotus_shared::graphics::textures::*;
/// A texture that can be manipulated and displayed on script texture slots.
#[derive(Debug)]
pub struct Texture(TextureHandle);
impl Texture {
/// Create a new texture.
#[must_use]
pub fn create<'a>(options: impl Into<TextureCreationOptions<'a>>) -> Self {
let options = options.into();
let options = FfiObject::new(&options);
unsafe {
Self(TextureHandle::new(lotus_script_sys::textures::create(
options.packed(),
)))
}
}
/// Add an action to the texture. You may want to call the helper methods
/// instead of this.
pub fn add_action(&mut self, action: TextureAction) {
let action = FfiObject::new(&action);
unsafe { lotus_script_sys::textures::add_action(self.0.id(), action.packed()) }
}
/// Draw a rectangle on the texture.
pub fn draw_rect(&mut self, start: impl Into<UVec2>, end: impl Into<UVec2>, color: Color) {
self.add_action(TextureAction::DrawRect {
start: start.into(),
end: end.into(),
color,
});
}
/// Clear the texture with a color.
pub fn clear(&mut self, color: Color) {
self.add_action(TextureAction::Clear(color));
}
/// Read the color of a pixel on the texture.
#[inline]
pub fn read_pixel(&self, x: u32, y: u32) -> Color {
let packed = unsafe { lotus_script_sys::textures::get_pixel(self.0.id(), x, y) };
packed.into()
}
/// Draw multiple pixels on the texture.
pub fn draw_pixels<P>(&mut self, pixels: &[P])
where
P: Into<DrawPixel> + Copy,
{
let pixels = pixels.iter().map(|p| (*p).into()).collect();
self.add_action(TextureAction::DrawPixels(pixels));
}
/// Draws another texture on top of this one.
pub fn draw_texture(&mut self, other: &Texture, options: DrawTextureOpts) {
self.add_action(TextureAction::DrawScriptTexture {
handle: other.handle(),
options,
});
}
/// Call this once for every game-texture you want to apply this to. You can define the name in the content tool.
pub fn apply_to(&mut self, name: &str) {
let name = FfiObject::new(&name);
unsafe { lotus_script_sys::textures::apply_to(self.0.id(), name.packed()) }
}
/// Only call this if you need your actions to be applied immediately.
/// Cause of streaming assets, this method will return false if the actions are not yet applied.
/// Just call this method again until it returns true.
pub fn flush(&mut self) -> bool {
unsafe { lotus_script_sys::textures::flush_actions(self.0.id()) == 1 }
}
/// Draws another texture on top of this one.
pub fn draw_script_texture(&mut self, other: &Texture, options: DrawTextureOpts) {
self.add_action(TextureAction::DrawScriptTexture {
handle: other.handle(),
options,
});
}
/// Draws a text on the texture.
pub fn draw_text(
&mut self,
font: ContentId,
text: impl Into<String>,
top_left: impl Into<UVec2>,
letter_spacing: u32,
full_color: impl Into<Option<Color>>,
alpha_mode: AlphaMode,
) {
self.add_action(TextureAction::DrawText {
font,
text: text.into(),
top_left: top_left.into(),
letter_spacing,
full_color: full_color.into(),
alpha_mode,
});
}
/// Get the handle of the texture.
pub fn handle(&self) -> TextureHandle {
self.0
}
/// Forget the texture. This means it will not be disposed when the texture is dropped.
/// Use this only if you want to keep the texture alive without keeping a reference to it.
pub fn forget(mut self) {
self.0 = TextureHandle::new(u32::MAX);
}
}
impl Drop for Texture {
fn drop(&mut self) {
if self.0.id() != u32::MAX {
unsafe { lotus_script_sys::textures::dispose(self.0.id()) }
}
}
}
pub enum DrawableTexture {
// TODO: Support content textures.
// Content(ContentId),
Script(TextureHandle),
}
impl From<&Texture> for DrawableTexture {
fn from(texture: &Texture) -> Self {
Self::Script(texture.handle())
}
}
impl From<TextureHandle> for DrawableTexture {
fn from(handle: TextureHandle) -> Self {
Self::Script(handle)
}
}
}