commit 669849c4547f1fd0950d7f03f56f78d4681db7f1 Author: Carter Anderson Date: Tue Nov 12 19:36:02 2019 -0800 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..693699042b --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/target +**/*.rs.bk +Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000000..eb62a366fe --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "bevy" +version = "0.1.0" +authors = ["Carter Anderson "] +edition = "2018" + +[dependencies] +legion = { git = "https://github.com/TomGillen/legion.git" } +nalgebra = "0.18" +wgpu = "0.4.0" +winit = "0.20.0-alpha4" \ No newline at end of file diff --git a/examples/simple.rs b/examples/simple.rs new file mode 100644 index 0000000000..93ce194016 --- /dev/null +++ b/examples/simple.rs @@ -0,0 +1,18 @@ +use legion::prelude::*; +use bevy::{Application, Transform}; + + +struct SimpleApp; + +impl Application for SimpleApp { + fn update(&self) {} +} + +fn main() { + let app = SimpleApp {}; + // Create a world to store our entities + let universe = Universe::new(); + let mut world = universe.create_world(); + world.insert((), vec![(Transform::new(),)]); + app.start(); +} diff --git a/notes/outline.md b/notes/outline.md new file mode 100644 index 0000000000..73bce93793 --- /dev/null +++ b/notes/outline.md @@ -0,0 +1,90 @@ +# Bevy Outline + +## High Level + +* ECS at its core (but only where needed) +* Simple api backed by flexible systems + * ex: PBR renderer built on a render graph system +* Flexbox ui + * simple, standard, good implementations exist +* 100% rust (except for the few cases where this is impossible) +* Batteries included + * 2d/3d rendering, ui, physics, networking, etc +* Editor: also a "game" + * dogfood components +* Fast app compile times (< 5 seconds) + +## Dependencies + +* Legion ecs +* wgfx-rs +* nalgebra +* nphysics/ncollide + +## Outline + +* Core + * Shared + * Types + * enum PropertyValue + * DATATYPE_WRAPPERS_HERE + * Analog: godot's Variant + * struct Property + * Description: Dynamic data + * Ex: exported to editor, uniforms in shaders + * Tags: ```HashSet``` + * struct Texture + * Components + + * Parent + * Children ```Vec``` + + * Properties + * ```HashMap``` + + * Mesh + * Armature + * Material + * Systems + + * UpdateArmatureTransforms + * SyncPropertiesToMaterialUniforms + * 3d + * Components + + * Transform + * GlobalTransform + + * PhysicsBody + * CollisionShape + * RigidBody + * Systems + + * CalculateGlobalTransform + * Dep: Child, GlobalTransform, Transform + + * UpdateCollisions/NCollide + * Dep: CollisionShape, PhysicsBody, GlobalTransform + * UpdateRigidBodies/NCollide + * Dep: PhysicsBody, RigidBody, GlobalTransform + * 2d + * Components + + * Transform2d + * GlobalTransform2d + + * Element + + * PhysicsBody2d + * CollisionShape2d + * RigidBody2d + * Systems + + * CalculateGlobalTransform2d + * Dep: Child, GlobalTransform2d, Transform2d + + * UpdateCollisions2d/NCollide + * Dep: CollisionShape2d, PhysicsBody2d, GlobalTransform2d + * UpdateRigidBodies2d/NCollide + * Dep: PhysicsBody2d, RigidBody2d, GlobalTransform2d + diff --git a/src/application.rs b/src/application.rs new file mode 100644 index 0000000000..deb84aaf7f --- /dev/null +++ b/src/application.rs @@ -0,0 +1,142 @@ +use winit::{ + event, + event_loop::{ControlFlow, EventLoop}, +}; + +pub trait Application { + fn start(&self) { + let event_loop = EventLoop::new(); + + let (_window, size, surface) = { + let window = winit::window::Window::new(&event_loop).unwrap(); + let size = window.inner_size().to_physical(window.hidpi_factor()); + + let surface = wgpu::Surface::create(&window); + (window, size, surface) + }; + + let adapter = wgpu::Adapter::request(&wgpu::RequestAdapterOptions { + power_preference: wgpu::PowerPreference::Default, + backends: wgpu::BackendBit::PRIMARY, + }) + .unwrap(); + + let (device, mut queue) = adapter.request_device(&wgpu::DeviceDescriptor { + extensions: wgpu::Extensions { + anisotropic_filtering: false, + }, + limits: wgpu::Limits::default(), + }); + + let vs = include_bytes!("shader.vert.spv"); + let vs_module = + device.create_shader_module(&wgpu::read_spirv(std::io::Cursor::new(&vs[..])).unwrap()); + + let fs = include_bytes!("shader.frag.spv"); + let fs_module = + device.create_shader_module(&wgpu::read_spirv(std::io::Cursor::new(&fs[..])).unwrap()); + + let bind_group_layout = + device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { bindings: &[] }); + let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { + layout: &bind_group_layout, + bindings: &[], + }); + let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { + bind_group_layouts: &[&bind_group_layout], + }); + + let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { + layout: &pipeline_layout, + vertex_stage: wgpu::ProgrammableStageDescriptor { + module: &vs_module, + entry_point: "main", + }, + fragment_stage: Some(wgpu::ProgrammableStageDescriptor { + module: &fs_module, + entry_point: "main", + }), + rasterization_state: Some(wgpu::RasterizationStateDescriptor { + front_face: wgpu::FrontFace::Ccw, + cull_mode: wgpu::CullMode::None, + depth_bias: 0, + depth_bias_slope_scale: 0.0, + depth_bias_clamp: 0.0, + }), + primitive_topology: wgpu::PrimitiveTopology::TriangleList, + color_states: &[wgpu::ColorStateDescriptor { + format: wgpu::TextureFormat::Bgra8UnormSrgb, + color_blend: wgpu::BlendDescriptor::REPLACE, + alpha_blend: wgpu::BlendDescriptor::REPLACE, + write_mask: wgpu::ColorWrite::ALL, + }], + depth_stencil_state: None, + index_format: wgpu::IndexFormat::Uint16, + vertex_buffers: &[], + sample_count: 1, + sample_mask: !0, + alpha_to_coverage_enabled: false, + }); + + let mut swap_chain = device.create_swap_chain( + &surface, + &wgpu::SwapChainDescriptor { + usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT, + format: wgpu::TextureFormat::Bgra8UnormSrgb, + width: size.width.round() as u32, + height: size.height.round() as u32, + present_mode: wgpu::PresentMode::Vsync, + }, + ); + + event_loop.run(move |event, _, control_flow| { + *control_flow = if cfg!(feature = "metal-auto-capture") { + ControlFlow::Exit + } else { + ControlFlow::Poll + }; + match event { + event::Event::WindowEvent { event, .. } => match event { + event::WindowEvent::KeyboardInput { + input: + event::KeyboardInput { + virtual_keycode: Some(event::VirtualKeyCode::Escape), + state: event::ElementState::Pressed, + .. + }, + .. + } + | event::WindowEvent::CloseRequested => { + *control_flow = ControlFlow::Exit; + } + _ => {} + }, + event::Event::EventsCleared => { + let frame = swap_chain.get_next_texture(); + let mut encoder = + device.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 }); + { + let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { + color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor { + attachment: &frame.view, + resolve_target: None, + load_op: wgpu::LoadOp::Clear, + store_op: wgpu::StoreOp::Store, + clear_color: wgpu::Color::GREEN, + }], + depth_stencil_attachment: None, + }); + rpass.set_pipeline(&render_pipeline); + rpass.set_bind_group(0, &bind_group, &[]); + rpass.draw(0..3, 0..1); + } + + queue.submit(&[encoder.finish()]); + } + _ => (), + } + }); + } + + fn update(&self); +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000000..1512568422 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,5 @@ +mod transform; +mod application; + +pub use transform::Transform; +pub use application::Application; \ No newline at end of file diff --git a/src/shader.frag b/src/shader.frag new file mode 100644 index 0000000000..74e14f410e --- /dev/null +++ b/src/shader.frag @@ -0,0 +1,7 @@ +#version 450 + +layout(location = 0) out vec4 outColor; + +void main() { + outColor = vec4(1.0, 0.0, 0.0, 1.0); +} diff --git a/src/shader.frag.spv b/src/shader.frag.spv new file mode 100644 index 0000000000..59e491519b Binary files /dev/null and b/src/shader.frag.spv differ diff --git a/src/shader.vert b/src/shader.vert new file mode 100644 index 0000000000..ac6dcc7c32 --- /dev/null +++ b/src/shader.vert @@ -0,0 +1,15 @@ +#version 450 + +out gl_PerVertex { + vec4 gl_Position; +}; + +const vec2 positions[3] = vec2[3]( + vec2(0.0, -0.5), + vec2(0.5, 0.5), + vec2(-0.5, 0.5) +); + +void main() { + gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0); +} diff --git a/src/shader.vert.spv b/src/shader.vert.spv new file mode 100644 index 0000000000..9a3f5994b7 Binary files /dev/null and b/src/shader.vert.spv differ diff --git a/src/transform.rs b/src/transform.rs new file mode 100644 index 0000000000..45bb6d2f59 --- /dev/null +++ b/src/transform.rs @@ -0,0 +1,16 @@ +use nalgebra::Matrix4; + +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct Transform { + pub local: Matrix4, + pub global: Matrix4, +} + +impl Transform { + pub fn new() -> Transform { + Transform { + local: Matrix4::::identity(), + global: Matrix4::::identity(), + } + } +} \ No newline at end of file