diff --git a/src/graphics.ts b/src/graphics.ts index aaa7ad14..185413b2 100644 --- a/src/graphics.ts +++ b/src/graphics.ts @@ -52,6 +52,19 @@ export function spr( core.spr(x, y, w, h, sx, sy, sw, sh); } +/** + * Create a texture based on the loaded buffer. + * + * @param buffer The underlying bytes that make up the texture image. + * @param label The label to put onto the texture (for debugging). + */ +export function create_texture( + buffer: ArrayBuffer, + label: string | undefined = undefined +): number { + return core.create_texture(buffer, label); +} + /** * Set the specified texture as the current texture for calls to e.g. spr(). * diff --git a/src/lib.rs b/src/lib.rs index 8577050a..9a23cacc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -339,7 +339,10 @@ impl State { &self.device, &self.queue, &ct.image, - Some(&ct.label), + match &ct.label { + Some(l) => Some(&l), + None => None, + }, ); let sprite_bind_group = self.device.create_bind_group(&wgpu::BindGroupDescriptor { @@ -354,7 +357,10 @@ impl State { resource: wgpu::BindingResource::Sampler(&texture.sampler), }, ], - label: Some(&ct.label), + label: match &ct.label { + Some(l) => Some(&l), + None => None, + }, }); self.sprite_textures.insert(ct.id, sprite_bind_group); diff --git a/src/script/assets.rs b/src/script/assets.rs index 26e9b42b..f6bcbaec 100644 --- a/src/script/assets.rs +++ b/src/script/assets.rs @@ -30,7 +30,7 @@ impl AssetsImpl { .send(GraphicsCommand::CreateTexture(CreateTextureCommand { id, image, - label: path.into(), + label: Some(path.into()), })); Ok(id) diff --git a/src/script/graphics.rs b/src/script/graphics.rs index 0156b6ee..c27a089a 100644 --- a/src/script/graphics.rs +++ b/src/script/graphics.rs @@ -1,4 +1,5 @@ -use oden_js::{module, ContextRef}; +use oden_js::{module, ContextRef, Error, Result, Value}; +use std::sync::atomic::{AtomicU32, Ordering}; use std::sync::mpsc::Sender; use std::sync::Arc; @@ -28,7 +29,7 @@ pub struct SpriteCommand { pub struct CreateTextureCommand { pub id: u32, pub image: image::DynamicImage, - pub label: String, + pub label: Option, } #[derive(Debug)] @@ -42,12 +43,16 @@ pub enum GraphicsCommand { } struct GraphicsImpl { + next_texture_id: AtomicU32, sender: Sender, } impl GraphicsImpl { pub fn new(sender: Sender) -> Self { - GraphicsImpl { sender } + GraphicsImpl { + sender, + next_texture_id: AtomicU32::new(0), + } } fn print(&self, text: String) -> () { @@ -75,6 +80,30 @@ impl GraphicsImpl { })); } + fn create_texture( + &self, + context: &ContextRef, + buffer: Value, + label: Option, + ) -> Result { + let bytes = buffer.get_array_buffer(context)?; + let image = match image::load_from_memory(&bytes) { + Ok(i) => i, + Err(e) => return Err(Error::RustFunctionError(format!("{e}"))), + }; + + let id = self.next_texture_id.fetch_add(1, Ordering::SeqCst); + let _ = self + .sender + .send(GraphicsCommand::CreateTexture(CreateTextureCommand { + id, + image, + label, + })); + + Ok(id) + } + fn use_texture(&self, id: u32) { let _ = self.sender.send(GraphicsCommand::UseTexture(id)); } @@ -126,6 +155,17 @@ impl GraphicsAPI { ctx.new_fn(move |_: &ContextRef, id: u32| gfx.use_texture(id))?, )?; } + { + let gfx = gfx.clone(); + builder.export( + "create_texture", + ctx.new_fn( + move |c: &ContextRef, buffer: Value, label: Option| { + gfx.create_texture(c, buffer, label) + }, + )?, + )?; + } builder.build("graphics-core")?; Ok(GraphicsAPI { gfx }) } diff --git a/types/graphics-core.d.ts b/types/graphics-core.d.ts index 7f0afd2e..3fde39fd 100644 --- a/types/graphics-core.d.ts +++ b/types/graphics-core.d.ts @@ -12,4 +12,8 @@ export function spr( sw: number, sh: number ); +export function create_texture( + buffer: ArrayBuffer, + label: string | undefined +): number; export function use_texture(id: number);