diff --git a/src/lib.rs b/src/lib.rs index a21e5470..562f9e35 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,7 +8,8 @@ use winit::{ }; mod script; -use script::graphics::{ClearCommand, GraphicsCommand, PrintCommand}; +// use script::ScriptContext; + mod texture; #[repr(C)] @@ -297,7 +298,7 @@ impl State { fn update(&mut self) {} - fn render(&mut self, commands: Vec) -> Result<(), wgpu::SurfaceError> { + fn render(&mut self) -> Result<(), wgpu::SurfaceError> { let output = self.surface.get_current_texture()?; let view = output .texture @@ -308,95 +309,37 @@ impl State { label: Some("Render Encoder"), }); - // Group the commands into passes. - struct Pass { - color: Option<[f64; 4]>, - commands: Vec, - } - let mut passes = Vec::new(); - for command in commands { - match command { - GraphicsCommand::Clear(ClearCommand { color }) => passes.push(Pass { - color: Some(color), - commands: Vec::new(), - }), - GraphicsCommand::EndFrame => (), - other => match passes.last_mut() { - Some(pass) => pass.commands.push(other), - None => passes.push(Pass { - color: None, - commands: vec![other], - }), - }, - } - } + { + // BEGIN GARBAGE + let r: f64 = (self.mouse_x / f64::from(self.size.width)).clamp(0.0, 1.0) * 0.1; + let g: f64 = (self.mouse_y / f64::from(self.size.height)).clamp(0.0, 1.0) * 0.2; + // END GARBAGE - for pass in passes { let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { label: Some("Render Pass"), color_attachments: &[Some(wgpu::RenderPassColorAttachment { view: &view, resolve_target: None, ops: wgpu::Operations { - load: if let Some([r, g, b, a]) = pass.color { - wgpu::LoadOp::Clear(wgpu::Color { - r, //0.1, - g, //0.2, - b, - a, - }) - } else { - wgpu::LoadOp::Load - }, + load: wgpu::LoadOp::Clear(wgpu::Color { + r, //0.1, + g, //0.2, + b: 0.3, + a: 1.0, + }), store: true, }, })], depth_stencil_attachment: None, }); - for command in pass.commands { - match command { - GraphicsCommand::Print(PrintCommand { text }) => { - println!("{}", text); - } - - GraphicsCommand::Clear(_) => (), // Already handled - GraphicsCommand::EndFrame => (), // Should never appear - } - } + render_pass.set_pipeline(&self.render_pipeline); + render_pass.set_bind_group(0, &self.diffuse_bind_group, &[]); + render_pass.set_vertex_buffer(0, self.vertex_buffer.slice(..)); + render_pass.set_index_buffer(self.index_buffer.slice(..), wgpu::IndexFormat::Uint16); + render_pass.draw_indexed(0..self.num_indices, 0, 0..1); } - // { - // // BEGIN GARBAGE - // let r: f64 = (self.mouse_x / f64::from(self.size.width)).clamp(0.0, 1.0) * 0.1; - // let g: f64 = (self.mouse_y / f64::from(self.size.height)).clamp(0.0, 1.0) * 0.2; - // // END GARBAGE - - // let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { - // label: Some("Render Pass"), - // color_attachments: &[Some(wgpu::RenderPassColorAttachment { - // view: &view, - // resolve_target: None, - // ops: wgpu::Operations { - // load: wgpu::LoadOp::Clear(wgpu::Color { - // r, //0.1, - // g, //0.2, - // b: 0.3, - // a: 1.0, - // }), - // store: true, - // }, - // })], - // depth_stencil_attachment: None, - // }); - - // render_pass.set_pipeline(&self.render_pipeline); - // render_pass.set_bind_group(0, &self.diffuse_bind_group, &[]); - // render_pass.set_vertex_buffer(0, self.vertex_buffer.slice(..)); - // render_pass.set_index_buffer(self.index_buffer.slice(..), wgpu::IndexFormat::Uint16); - // render_pass.draw_indexed(0..self.num_indices, 0, 0..1); - // } - // Submit will accept anything that implements IntoIter self.queue.submit(std::iter::once(encoder.finish())); output.present(); @@ -460,7 +403,8 @@ pub async fn run() { context.update(); state.update(); - match state.render(context.render()) { + context.render(); + match state.render() { Ok(_) => {} // Reconfigure the surface if lost Err(wgpu::SurfaceError::Lost) => state.resize(state.size), diff --git a/src/main.js b/src/main.js index 7bc0a8ba..b20da253 100644 --- a/src/main.js +++ b/src/main.js @@ -1,11 +1,11 @@ -import { cls, print } from "graphics"; +import * as graphics from 'graphics'; -export function init() { - print("Hello world!"); +function init() { + graphics.print("Hello world!"); } -export function update() {} +function update() {} -export function draw() { - cls(0.1, 0.2, 0.3); -} +function draw() {} + +export { init, update, draw } diff --git a/src/script.rs b/src/script.rs index a34d149d..12113a3a 100644 --- a/src/script.rs +++ b/src/script.rs @@ -1,17 +1,28 @@ -use oden_js::{Context, Runtime, Value}; -use std::sync::mpsc::{channel, Receiver}; +use oden_js::{module, Context, ContextRef, Runtime, Value, ValueRef, ValueResult}; -pub mod graphics; -use graphics::GraphicsCommand; +pub struct GraphicsAPI {} + +impl GraphicsAPI { + fn define(ctx: &ContextRef) -> oden_js::Result<()> { + module::NativeModuleBuilder::new(ctx) + .export("print", ctx.new_dynamic_fn(Self::print_fn)?)? + .build("graphics") + } + + fn print_fn(ctx: &ContextRef, _this: &ValueRef, args: &[&ValueRef]) -> ValueResult { + for arg in args { + print!("{}", arg.to_string(ctx)?); + } + println!(); + Ok(Value::undefined(ctx)) + } +} pub struct ScriptContext { context: Context, init: Value, update: Value, draw: Value, - - gfx: graphics::GraphicsAPI, - gfx_receive: Receiver, } impl ScriptContext { @@ -23,10 +34,7 @@ impl ScriptContext { context.add_intrinsic_bigdecimal(); context.add_intrinsic_operators(); - let (gfx_send, gfx_receive) = channel(); - - let gfx = graphics::GraphicsAPI::define(&context, gfx_send) - .expect("Graphics module should load without error"); + GraphicsAPI::define(&context).expect("Graphics module should load without error"); let js = include_str!("main.js"); let module = context @@ -45,20 +53,12 @@ impl ScriptContext { ScriptContext { context, - init, update, draw, - - gfx, - gfx_receive, } } - // TODO: The script could really be on a background thread you know. - // We would want a bi-directional gate for frames to not let the - // game thread go to fast probably? And to discard whole frames &c. - pub fn init(&self) { self.init.call(&self.context).expect("Exception in init"); } @@ -69,17 +69,7 @@ impl ScriptContext { .expect("Exception in update"); } - pub fn render(&self) -> Vec { + pub fn render(&self) { self.draw.call(&self.context).expect("Exception in draw"); - self.gfx.end_frame(); - - let mut commands = Vec::new(); - loop { - match self.gfx_receive.recv().unwrap() { - GraphicsCommand::EndFrame => break, - other => commands.push(other), - } - } - commands } } diff --git a/src/script/graphics.rs b/src/script/graphics.rs deleted file mode 100644 index 6223ed0b..00000000 --- a/src/script/graphics.rs +++ /dev/null @@ -1,93 +0,0 @@ -use oden_js::{module, ContextRef, Error, Value, ValueRef, ValueResult}; -use std::sync::mpsc::Sender; -use std::sync::Arc; - -pub struct PrintCommand { - pub text: String, -} - -pub struct ClearCommand { - pub color: [f64; 4], -} - -pub enum GraphicsCommand { - Clear(ClearCommand), - Print(PrintCommand), - EndFrame, -} - -const MAGIC_VALUE: u64 = 0xABCDB00BABCDBEEB; - -struct GraphicsImpl { - magic: u64, - sender: Sender, -} - -impl GraphicsImpl { - pub fn new(sender: Sender) -> Self { - GraphicsImpl { - magic: MAGIC_VALUE, - sender, - } - } - - fn print_fn(&self, ctx: &ContextRef, args: &[&ValueRef]) -> ValueResult { - assert_eq!(self.magic, MAGIC_VALUE); - let mut text = String::with_capacity(128); - for arg in args { - let v = arg.to_string(ctx)?; - text.push_str(&v); - } - - let _ = self - .sender - .send(GraphicsCommand::Print(PrintCommand { text })); - - Ok(Value::undefined(ctx)) - } - - fn cls_fn(&self, ctx: &ContextRef, args: &[&ValueRef]) -> ValueResult { - assert_eq!(self.magic, MAGIC_VALUE); - if args.len() != 3 { - return Err(Error::ArgumentCountMismatch { - expected: 3, - received: args.len(), - }); - } - let r = args[0].to_float64(&ctx)?; - let g = args[1].to_float64(&ctx)?; - let b = args[1].to_float64(&ctx)?; - - let _ = self.sender.send(GraphicsCommand::Clear(ClearCommand { - color: [r, g, b, 1.0], - })); - Ok(Value::undefined(ctx)) - } -} - -pub struct GraphicsAPI { - gfx: Arc, -} - -impl GraphicsAPI { - pub fn define(ctx: &ContextRef, sender: Sender) -> oden_js::Result { - let gfx = Arc::new(GraphicsImpl::new(sender)); - let gfx_a = gfx.clone(); - let gfx_b = gfx.clone(); - module::NativeModuleBuilder::new(ctx) - .export( - "print", - ctx.new_dynamic_fn(move |ctx, _, args| gfx_a.print_fn(ctx, args))?, - )? - .export( - "cls", - ctx.new_dynamic_fn(move |ctx, _, args| gfx_b.cls_fn(ctx, args))?, - )? - .build("graphics")?; - Ok(GraphicsAPI { gfx }) - } - - pub fn end_frame(&self) { - let _ = self.gfx.sender.send(GraphicsCommand::EndFrame); - } -}