[oden] Graphics module can create textures directly

This commit is contained in:
John Doty 2023-06-30 06:28:57 -07:00
parent 4959adc7e6
commit d2dfa7c401
5 changed files with 69 additions and 6 deletions

View file

@ -52,6 +52,19 @@ export function spr(
core.spr(x, y, w, h, sx, sy, sw, sh); 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(). * Set the specified texture as the current texture for calls to e.g. spr().
* *

View file

@ -339,7 +339,10 @@ impl State {
&self.device, &self.device,
&self.queue, &self.queue,
&ct.image, &ct.image,
Some(&ct.label), match &ct.label {
Some(l) => Some(&l),
None => None,
},
); );
let sprite_bind_group = let sprite_bind_group =
self.device.create_bind_group(&wgpu::BindGroupDescriptor { self.device.create_bind_group(&wgpu::BindGroupDescriptor {
@ -354,7 +357,10 @@ impl State {
resource: wgpu::BindingResource::Sampler(&texture.sampler), 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); self.sprite_textures.insert(ct.id, sprite_bind_group);

View file

@ -30,7 +30,7 @@ impl AssetsImpl {
.send(GraphicsCommand::CreateTexture(CreateTextureCommand { .send(GraphicsCommand::CreateTexture(CreateTextureCommand {
id, id,
image, image,
label: path.into(), label: Some(path.into()),
})); }));
Ok(id) Ok(id)

View file

@ -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::mpsc::Sender;
use std::sync::Arc; use std::sync::Arc;
@ -28,7 +29,7 @@ pub struct SpriteCommand {
pub struct CreateTextureCommand { pub struct CreateTextureCommand {
pub id: u32, pub id: u32,
pub image: image::DynamicImage, pub image: image::DynamicImage,
pub label: String, pub label: Option<String>,
} }
#[derive(Debug)] #[derive(Debug)]
@ -42,12 +43,16 @@ pub enum GraphicsCommand {
} }
struct GraphicsImpl { struct GraphicsImpl {
next_texture_id: AtomicU32,
sender: Sender<GraphicsCommand>, sender: Sender<GraphicsCommand>,
} }
impl GraphicsImpl { impl GraphicsImpl {
pub fn new(sender: Sender<GraphicsCommand>) -> Self { pub fn new(sender: Sender<GraphicsCommand>) -> Self {
GraphicsImpl { sender } GraphicsImpl {
sender,
next_texture_id: AtomicU32::new(0),
}
} }
fn print(&self, text: String) -> () { fn print(&self, text: String) -> () {
@ -75,6 +80,30 @@ impl GraphicsImpl {
})); }));
} }
fn create_texture(
&self,
context: &ContextRef,
buffer: Value,
label: Option<String>,
) -> Result<u32> {
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) { fn use_texture(&self, id: u32) {
let _ = self.sender.send(GraphicsCommand::UseTexture(id)); let _ = self.sender.send(GraphicsCommand::UseTexture(id));
} }
@ -126,6 +155,17 @@ impl GraphicsAPI {
ctx.new_fn(move |_: &ContextRef, id: u32| gfx.use_texture(id))?, 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<String>| {
gfx.create_texture(c, buffer, label)
},
)?,
)?;
}
builder.build("graphics-core")?; builder.build("graphics-core")?;
Ok(GraphicsAPI { gfx }) Ok(GraphicsAPI { gfx })
} }

View file

@ -12,4 +12,8 @@ export function spr(
sw: number, sw: number,
sh: number sh: number
); );
export function create_texture(
buffer: ArrayBuffer,
label: string | undefined
): number;
export function use_texture(id: number); export function use_texture(id: number);