mirror of
https://github.com/lisk77/comet.git
synced 2025-10-23 21:38:50 +00:00
feat: Added swappability of the renderer and added a Renderer trait to make custom renderers if needed. Also renamed Renderer2D component to Render2D because it is a "render component" and not a renderer (but also name to avoid name clashes)
This commit is contained in:
parent
29355335e6
commit
a3df3f4f17
5 changed files with 133 additions and 129 deletions
|
|
@ -1,8 +1,8 @@
|
||||||
use std::sync::Arc;
|
use std::sync::{Arc, Mutex};
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
use comet_ecs::{Component, ComponentSet, Render, Renderer2D, Transform2D, World};
|
use comet_ecs::{Component, ComponentSet, Render, Transform2D, World};
|
||||||
use comet_resources::{ResourceManager, Vertex};
|
use comet_resources::{ResourceManager, Vertex};
|
||||||
use comet_renderer::{Renderer};
|
use comet_renderer::{Renderer2D};
|
||||||
|
|
||||||
use winit::{
|
use winit::{
|
||||||
event::{self, *},
|
event::{self, *},
|
||||||
|
|
@ -19,6 +19,7 @@ use winit::platform::windows::WindowBuilderExtWindows;
|
||||||
use winit_input_helper::WinitInputHelper;
|
use winit_input_helper::WinitInputHelper;
|
||||||
use comet_input::input_handler::InputHandler;
|
use comet_input::input_handler::InputHandler;
|
||||||
use comet_input::keyboard::Key;
|
use comet_input::keyboard::Key;
|
||||||
|
use comet_renderer::renderer::Renderer;
|
||||||
|
|
||||||
pub enum ApplicationType {
|
pub enum ApplicationType {
|
||||||
App2D,
|
App2D,
|
||||||
|
|
@ -30,7 +31,6 @@ pub struct App<'a> {
|
||||||
icon: Option<Icon>,
|
icon: Option<Icon>,
|
||||||
size: Option<LogicalSize<u32>>,
|
size: Option<LogicalSize<u32>>,
|
||||||
clear_color: Option<LinearRgba>,
|
clear_color: Option<LinearRgba>,
|
||||||
setup: Option<fn(&mut World)>,
|
|
||||||
input_manager: WinitInputHelper,
|
input_manager: WinitInputHelper,
|
||||||
delta_time: f32,
|
delta_time: f32,
|
||||||
update_timer: f32,
|
update_timer: f32,
|
||||||
|
|
@ -51,7 +51,6 @@ impl<'a> App<'a> {
|
||||||
icon: None,
|
icon: None,
|
||||||
size: None,
|
size: None,
|
||||||
clear_color: None,
|
clear_color: None,
|
||||||
setup: None,
|
|
||||||
input_manager: WinitInputHelper::new(),
|
input_manager: WinitInputHelper::new(),
|
||||||
delta_time: 0.0,
|
delta_time: 0.0,
|
||||||
update_timer: 0.0166667,
|
update_timer: 0.0166667,
|
||||||
|
|
@ -81,11 +80,6 @@ impl<'a> App<'a> {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_setup(mut self, setup: fn(&mut World)) -> Self {
|
|
||||||
self.setup = Some(setup);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
fn load_icon(path: &std::path::Path) -> Option<Icon> {
|
fn load_icon(path: &std::path::Path) -> Option<Icon> {
|
||||||
let image = image::open(path).expect("Failed to open icon image");
|
let image = image::open(path).expect("Failed to open icon image");
|
||||||
let rgba_image = image.to_rgba8();
|
let rgba_image = image.to_rgba8();
|
||||||
|
|
@ -117,114 +111,97 @@ impl<'a> App<'a> {
|
||||||
self.input_manager.key_released(key)
|
self.input_manager.key_released(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dt(&self) -> f32 {
|
|
||||||
self.delta_time
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn quit(&mut self) {
|
pub fn quit(&mut self) {
|
||||||
self.should_quit = true;
|
self.should_quit = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_time_step(&self) -> f32 {
|
pub fn dt(&self) -> f32 {
|
||||||
self.update_timer
|
self.update_timer
|
||||||
}
|
}
|
||||||
pub fn set_time_step(&mut self, time_step: f32) {
|
pub fn set_update_rate(&mut self, update_rate: u32) {
|
||||||
self.update_timer = time_step;
|
if update_rate == 0 {
|
||||||
|
self.update_timer = f32::INFINITY;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.update_timer = 1.0/update_rate as f32;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_window(app_title: &str, app_icon: &Option<Icon>, window_size: &Option<LogicalSize<u32>>, event_loop: &EventLoop<()>) -> winit::window::Window {
|
fn create_window(app_title: &str, app_icon: &Option<Icon>, window_size: &Option<LogicalSize<u32>>, event_loop: &EventLoop<()>) -> Window {
|
||||||
let winit_window = winit::window::WindowBuilder::new()
|
let winit_window = winit::window::WindowBuilder::new()
|
||||||
.with_title(app_title);
|
.with_title(app_title);
|
||||||
|
|
||||||
let winit_window = if let Some(icon) = app_icon.clone() {
|
let winit_window = if let Some(icon) = app_icon.clone() {
|
||||||
winit_window.with_window_icon(Some(icon))
|
winit_window.with_window_icon(Some(icon))
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
winit_window
|
|
||||||
};
|
|
||||||
let winit_window = if let Some(icon) = app_icon.clone() {
|
|
||||||
winit_window.with_taskbar_icon(Some(icon))
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
winit_window
|
winit_window
|
||||||
};
|
};
|
||||||
|
|
||||||
let winit_window = if let Some(size) = window_size.clone() {
|
let winit_window = if let Some(size) = window_size.clone() {
|
||||||
winit_window.with_inner_size(size)
|
winit_window.with_inner_size(size)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
winit_window
|
winit_window
|
||||||
};
|
};
|
||||||
|
|
||||||
winit_window.build(event_loop).unwrap()
|
winit_window.build(event_loop).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run_app<U: Fn(&mut App, &mut Renderer, f32)>(mut self, update: U) {
|
pub fn run<R: Renderer>(mut self, setup: fn(&mut App, &mut R), update: fn(&mut App, &mut R, f32)) {
|
||||||
let event_loop = EventLoop::new().unwrap();
|
pollster::block_on(async {
|
||||||
let window = Self::create_window(self.title, &self.icon, &self.size ,&event_loop);
|
let event_loop = EventLoop::new().unwrap();
|
||||||
let mut renderer = Renderer::new(&window, self.clear_color.clone()).await.unwrap();
|
let window = Arc::new(Self::create_window(self.title, &self.icon, &self.size ,&event_loop));
|
||||||
window.set_maximized(true);
|
let mut renderer = R::new(window.clone(), self.clear_color.clone()).await; // Pass Arc<Mutex<Window>> to renderer
|
||||||
|
window.set_maximized(true); // Lock window to set maximized
|
||||||
|
|
||||||
if let Some(setup) = self.setup {
|
setup(&mut self, &mut renderer);
|
||||||
setup(&mut self.world);
|
|
||||||
}
|
|
||||||
|
|
||||||
renderer.initialize_atlas();
|
let mut time_stack = 0.0;
|
||||||
|
|
||||||
let mut time_stack = 0.0;
|
event_loop.run(|event, elwt| {
|
||||||
|
self.delta_time = renderer.update();
|
||||||
|
|
||||||
event_loop.run(|event, elwt| {
|
if self.should_quit {
|
||||||
self.delta_time = renderer.update();
|
elwt.exit()
|
||||||
|
}
|
||||||
|
|
||||||
if self.should_quit {
|
self.input_manager.update(&event);
|
||||||
elwt.exit()
|
|
||||||
}
|
|
||||||
|
|
||||||
self.input_manager.update(&event);
|
if self.dt() != f32::INFINITY {
|
||||||
|
time_stack += self.delta_time;
|
||||||
time_stack += self.delta_time;
|
while time_stack > self.update_timer {
|
||||||
while time_stack > self.update_timer {
|
let time = self.dt();
|
||||||
let time = self.get_time_step();
|
update(&mut self, &mut renderer, time);
|
||||||
update(&mut self, &mut renderer, time);
|
time_stack -= self.update_timer;
|
||||||
time_stack -= self.update_timer;
|
|
||||||
}
|
|
||||||
|
|
||||||
renderer.render_scene_2d(self.world());
|
|
||||||
|
|
||||||
match event {
|
|
||||||
Event::WindowEvent { ref event, window_id, }
|
|
||||||
if window_id == renderer.window().id() => {
|
|
||||||
match event {
|
|
||||||
WindowEvent::CloseRequested {} => elwt.exit(),
|
|
||||||
WindowEvent::Resized(physical_size) => {
|
|
||||||
renderer.resize(*physical_size);
|
|
||||||
}
|
|
||||||
WindowEvent::RedrawRequested => {
|
|
||||||
renderer.window().request_redraw();
|
|
||||||
|
|
||||||
match renderer.render() {
|
|
||||||
Ok(_) => {}
|
|
||||||
Err(
|
|
||||||
wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated,
|
|
||||||
) => renderer.resize(renderer.size()),
|
|
||||||
Err(wgpu::SurfaceError::OutOfMemory) => {
|
|
||||||
error!("OutOfMemory");
|
|
||||||
elwt.exit();
|
|
||||||
}
|
|
||||||
Err(wgpu::SurfaceError::Timeout) => {
|
|
||||||
warn!("Surface timeout")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn run<U: Fn(&mut App, &mut Renderer, f32)>(mut self, update: U) {
|
match event {
|
||||||
pollster::block_on(self.run_app(update));
|
Event::WindowEvent { ref event, window_id, } =>
|
||||||
|
match event {
|
||||||
|
WindowEvent::CloseRequested {} => elwt.exit(),
|
||||||
|
WindowEvent::Resized(physical_size) => {
|
||||||
|
renderer.resize(*physical_size);
|
||||||
|
}
|
||||||
|
WindowEvent::RedrawRequested => {
|
||||||
|
window.request_redraw();
|
||||||
|
|
||||||
|
match renderer.render() {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => renderer.resize(renderer.size()),
|
||||||
|
Err(wgpu::SurfaceError::OutOfMemory) => {
|
||||||
|
error!("OutOfMemory");
|
||||||
|
elwt.exit();
|
||||||
|
}
|
||||||
|
Err(wgpu::SurfaceError::Timeout) => {
|
||||||
|
warn!("Surface timeout")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}).unwrap()
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -39,7 +39,7 @@ pub struct Rectangle2D{
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct Renderer2D {
|
pub struct Render2D {
|
||||||
is_visible: bool,
|
is_visible: bool,
|
||||||
texture: &'static str,
|
texture: &'static str,
|
||||||
scale: Vec2
|
scale: Vec2
|
||||||
|
|
@ -196,7 +196,7 @@ impl Collider for Rectangle2D {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Render for Renderer2D {
|
impl Render for Render2D {
|
||||||
fn is_visible(&self) -> bool {
|
fn is_visible(&self) -> bool {
|
||||||
self.is_visible
|
self.is_visible
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
mod camera;
|
mod camera;
|
||||||
|
pub mod renderer;
|
||||||
|
|
||||||
use core::default::Default;
|
use core::default::Default;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::Arc;
|
use std::sync::{Arc, Mutex};
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use cgmath::num_traits::FloatConst;
|
use cgmath::num_traits::FloatConst;
|
||||||
use image::GenericImageView;
|
use image::GenericImageView;
|
||||||
|
|
@ -15,13 +16,14 @@ use winit::{
|
||||||
};
|
};
|
||||||
use winit::dpi::Position;
|
use winit::dpi::Position;
|
||||||
use comet_colors::LinearRgba;
|
use comet_colors::LinearRgba;
|
||||||
use comet_ecs::{Component, ComponentSet, Render, Renderer2D, Transform2D, World};
|
use comet_ecs::{Component, ComponentSet, Render, Renderer2D as R2D, Transform2D, World};
|
||||||
use comet_log::*;
|
use comet_log::*;
|
||||||
use comet_math;
|
use comet_math;
|
||||||
use comet_math::{Mat4, Point3, Vec2, Vec3};
|
use comet_math::{Mat4, Point3, Vec2, Vec3};
|
||||||
use comet_resources::{ResourceManager, texture, Vertex, Texture};
|
use comet_resources::{ResourceManager, texture, Vertex, Texture};
|
||||||
use comet_resources::texture_atlas::TextureRegion;
|
use comet_resources::texture_atlas::TextureRegion;
|
||||||
use crate::camera::{Camera, CameraUniform};
|
use crate::camera::{Camera, CameraUniform};
|
||||||
|
use crate::renderer::Renderer;
|
||||||
|
|
||||||
pub struct Projection {
|
pub struct Projection {
|
||||||
aspect: f32,
|
aspect: f32,
|
||||||
|
|
@ -47,8 +49,7 @@ impl Projection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Renderer<'a> {
|
pub struct Renderer2D<'a> {
|
||||||
window: &'a Window,
|
|
||||||
surface: wgpu::Surface<'a>,
|
surface: wgpu::Surface<'a>,
|
||||||
device: wgpu::Device,
|
device: wgpu::Device,
|
||||||
queue: wgpu::Queue,
|
queue: wgpu::Queue,
|
||||||
|
|
@ -73,15 +74,13 @@ pub struct Renderer<'a> {
|
||||||
camera_bind_group: wgpu::BindGroup,
|
camera_bind_group: wgpu::BindGroup,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Renderer<'a> {
|
impl<'a> Renderer2D<'a> {
|
||||||
pub async fn new(window: &'a Window, clear_color: Option<LinearRgba>) -> anyhow::Result<Renderer<'a>> {
|
pub async fn new(window: Arc<Window>, clear_color: Option<LinearRgba>) -> Renderer2D<'a> {
|
||||||
let vertex_data: Vec<Vertex> = vec![];
|
let vertex_data: Vec<Vertex> = vec![];
|
||||||
let index_data: Vec<u16> = vec![];
|
let index_data: Vec<u16> = vec![];
|
||||||
|
|
||||||
let size = PhysicalSize::<u32>::new(1920, 1080); //window.inner_size();
|
let size = PhysicalSize::<u32>::new(1920, 1080);
|
||||||
|
|
||||||
// The instance is a handle to our GPU
|
|
||||||
// BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU
|
|
||||||
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
|
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
|
||||||
backends: wgpu::Backends::PRIMARY,
|
backends: wgpu::Backends::PRIMARY,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
|
@ -103,8 +102,6 @@ impl<'a> Renderer<'a> {
|
||||||
&wgpu::DeviceDescriptor {
|
&wgpu::DeviceDescriptor {
|
||||||
label: None,
|
label: None,
|
||||||
required_features: wgpu::Features::empty(),
|
required_features: wgpu::Features::empty(),
|
||||||
// WebGL doesn't support all of wgpu's features, so if
|
|
||||||
// we're building for the web we'll have to disable some.
|
|
||||||
required_limits: wgpu::Limits::default(),
|
required_limits: wgpu::Limits::default(),
|
||||||
memory_hints: Default::default(),
|
memory_hints: Default::default(),
|
||||||
},
|
},
|
||||||
|
|
@ -114,9 +111,6 @@ impl<'a> Renderer<'a> {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let surface_caps = surface.get_capabilities(&adapter);
|
let surface_caps = surface.get_capabilities(&adapter);
|
||||||
// Shader code in this tutorial assumes an Srgb surface texture. Using a different
|
|
||||||
// one will result all the colors comming out darker. If you want to support non
|
|
||||||
// Srgb surfaces, you'll need to account for that when drawing to the frame.
|
|
||||||
let surface_format = surface_caps
|
let surface_format = surface_caps
|
||||||
.formats
|
.formats
|
||||||
.iter()
|
.iter()
|
||||||
|
|
@ -279,12 +273,8 @@ impl<'a> Renderer<'a> {
|
||||||
strip_index_format: None,
|
strip_index_format: None,
|
||||||
front_face: wgpu::FrontFace::Ccw,
|
front_face: wgpu::FrontFace::Ccw,
|
||||||
cull_mode: Some(wgpu::Face::Back),
|
cull_mode: Some(wgpu::Face::Back),
|
||||||
// Setting this to anything other than Fill requires Features::POLYGON_MODE_LINE
|
|
||||||
// or Features::POLYGON_MODE_POINT
|
|
||||||
polygon_mode: wgpu::PolygonMode::Fill,
|
polygon_mode: wgpu::PolygonMode::Fill,
|
||||||
// Requires Features::DEPTH_CLIP_CONTROL
|
|
||||||
unclipped_depth: false,
|
unclipped_depth: false,
|
||||||
// Requires Features::CONSERVATIVE_RASTERIZATION
|
|
||||||
conservative: false,
|
conservative: false,
|
||||||
},
|
},
|
||||||
depth_stencil: None,
|
depth_stencil: None,
|
||||||
|
|
@ -293,10 +283,7 @@ impl<'a> Renderer<'a> {
|
||||||
mask: !0,
|
mask: !0,
|
||||||
alpha_to_coverage_enabled: false,
|
alpha_to_coverage_enabled: false,
|
||||||
},
|
},
|
||||||
// If the pipeline will be used with a multiview render pass, this
|
|
||||||
// indicates how many array layers the attachments will have.
|
|
||||||
multiview: None,
|
multiview: None,
|
||||||
// Useful for optimizing shader compilation on Android
|
|
||||||
cache: None,
|
cache: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -310,8 +297,7 @@ impl<'a> Renderer<'a> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Self {
|
Self {
|
||||||
window,
|
|
||||||
surface,
|
surface,
|
||||||
device,
|
device,
|
||||||
queue,
|
queue,
|
||||||
|
|
@ -334,7 +320,7 @@ impl<'a> Renderer<'a> {
|
||||||
camera_uniform,
|
camera_uniform,
|
||||||
camera_buffer,
|
camera_buffer,
|
||||||
camera_bind_group,
|
camera_bind_group,
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dt(&self) -> f32 {
|
pub fn dt(&self) -> f32 {
|
||||||
|
|
@ -570,12 +556,12 @@ impl<'a> Renderer<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_scene_2d(&mut self, world: &World) {
|
pub fn render_scene_2d(&mut self, world: &World) {
|
||||||
let entities = world.get_entities_with(ComponentSet::from_ids(vec![Renderer2D::type_id()]));
|
let entities = world.get_entities_with(ComponentSet::from_ids(vec![R2D::type_id()]));
|
||||||
let mut vertex_buffer: Vec<Vertex> = Vec::new();
|
let mut vertex_buffer: Vec<Vertex> = Vec::new();
|
||||||
let mut index_buffer: Vec<u16> = Vec::new();
|
let mut index_buffer: Vec<u16> = Vec::new();
|
||||||
|
|
||||||
for entity in entities {
|
for entity in entities {
|
||||||
let renderer_component = world.get_component::<Renderer2D>(entity as usize);
|
let renderer_component = world.get_component::<R2D>(entity as usize);
|
||||||
let transform_component = world.get_component::<Transform2D>(entity as usize);
|
let transform_component = world.get_component::<Transform2D>(entity as usize);
|
||||||
|
|
||||||
if renderer_component.is_visible() {
|
if renderer_component.is_visible() {
|
||||||
|
|
@ -608,10 +594,6 @@ impl<'a> Renderer<'a> {
|
||||||
self.set_buffers(vertex_buffer, index_buffer);
|
self.set_buffers(vertex_buffer, index_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn window(&self) -> &Window {
|
|
||||||
&self.window
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn size(&self) -> PhysicalSize<u32> {
|
pub fn size(&self) -> PhysicalSize<u32> {
|
||||||
self.size
|
self.size
|
||||||
}
|
}
|
||||||
|
|
@ -674,4 +656,26 @@ impl<'a> Renderer<'a> {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Renderer for Renderer2D<'a> {
|
||||||
|
async fn new(window: Arc<Window>, clear_color: Option<LinearRgba>) -> Renderer2D<'a> {
|
||||||
|
Self::new(window.clone(), clear_color).await
|
||||||
|
}
|
||||||
|
|
||||||
|
fn size(&self) -> PhysicalSize<u32> {
|
||||||
|
self.size()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn resize(&mut self, new_size: winit::dpi::PhysicalSize<u32>) {
|
||||||
|
self.resize(new_size)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(&mut self) -> f32 {
|
||||||
|
self.update()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&mut self) -> Result<(), wgpu::SurfaceError> {
|
||||||
|
self.render()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
12
crates/comet_renderer/src/renderer.rs
Normal file
12
crates/comet_renderer/src/renderer.rs
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
use std::sync::Arc;
|
||||||
|
use winit::dpi::PhysicalSize;
|
||||||
|
use winit::window::Window;
|
||||||
|
use comet_colors::LinearRgba;
|
||||||
|
|
||||||
|
pub trait Renderer: Sized {
|
||||||
|
async fn new(window: Arc<Window>, clear_color: Option<LinearRgba>) -> Self;
|
||||||
|
fn size(&self) -> PhysicalSize<u32>;
|
||||||
|
fn resize(&mut self, new_size: winit::dpi::PhysicalSize<u32>);
|
||||||
|
fn update(&mut self) -> f32;
|
||||||
|
fn render(&mut self) -> Result<(), wgpu::SurfaceError>;
|
||||||
|
}
|
||||||
33
src/main.rs
33
src/main.rs
|
|
@ -3,8 +3,13 @@ use comet::{
|
||||||
App,
|
App,
|
||||||
ApplicationType::*
|
ApplicationType::*
|
||||||
},
|
},
|
||||||
renderer::Renderer,
|
renderer::Renderer2D,
|
||||||
ecs::*,
|
ecs::{
|
||||||
|
Render2D,
|
||||||
|
Transform2D,
|
||||||
|
Component,
|
||||||
|
Render
|
||||||
|
},
|
||||||
math::*,
|
math::*,
|
||||||
input::keyboard::*,
|
input::keyboard::*,
|
||||||
log::*
|
log::*
|
||||||
|
|
@ -44,11 +49,14 @@ fn update_position(input: WinitInputHelper, transform: &mut Transform2D, dt: f32
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup(world: &mut World) {
|
fn setup(app: &mut App, renderer: &mut Renderer2D) {
|
||||||
world.register_component::<Renderer2D>();
|
renderer.initialize_atlas();
|
||||||
|
|
||||||
|
let world = app.world_mut();
|
||||||
|
world.register_component::<Render2D>();
|
||||||
//world.register_component::<Rectangle2D>();
|
//world.register_component::<Rectangle2D>();
|
||||||
|
|
||||||
let mut renderer2d = Renderer2D::new();
|
let mut renderer2d = Render2D::new();
|
||||||
renderer2d.set_texture(r"resources/textures/comet_icon.png");
|
renderer2d.set_texture(r"resources/textures/comet_icon.png");
|
||||||
renderer2d.set_visibility(true);
|
renderer2d.set_visibility(true);
|
||||||
|
|
||||||
|
|
@ -71,10 +79,14 @@ fn setup(world: &mut World) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(app: &mut App, renderer: &mut Renderer, dt: f32) {
|
fn update(app: &mut App, renderer: &mut Renderer2D, dt: f32) {
|
||||||
if app.key_pressed(Key::Escape) { app.quit() }
|
if app.key_pressed(Key::Escape) { app.quit() }
|
||||||
if app.key_pressed(Key::KeyC) { app.set_time_step(0.0016667) }
|
if app.key_pressed(Key::KeyP) {
|
||||||
if app.key_pressed(Key::KeyV) { app.set_time_step(0.0166667) }
|
if app.dt() == f32::INFINITY { app.set_update_rate(60) }
|
||||||
|
else {
|
||||||
|
app.set_update_rate(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
if app.key_pressed(Key::KeyE) { app.world_mut().get_component_mut::<Transform2D>(0).translate([0f32,0f32].into()) }
|
if app.key_pressed(Key::KeyE) { app.world_mut().get_component_mut::<Transform2D>(0).translate([0f32,0f32].into()) }
|
||||||
if app.key_held(Key::KeyW)
|
if app.key_held(Key::KeyW)
|
||||||
|| app.key_held(Key::KeyA)
|
|| app.key_held(Key::KeyA)
|
||||||
|
|
@ -86,7 +98,7 @@ fn update(app: &mut App, renderer: &mut Renderer, dt: f32) {
|
||||||
|
|
||||||
let mut transform = app.world_mut().get_component_mut::<Transform2D>(0);
|
let mut transform = app.world_mut().get_component_mut::<Transform2D>(0);
|
||||||
|
|
||||||
|
renderer.render_scene_2d(app.world());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
@ -94,7 +106,6 @@ fn main() {
|
||||||
.with_title("Comet App")
|
.with_title("Comet App")
|
||||||
.with_icon(r"resources/textures/comet_icon.png")
|
.with_icon(r"resources/textures/comet_icon.png")
|
||||||
.with_size(1920, 1080)
|
.with_size(1920, 1080)
|
||||||
.with_setup(setup)
|
.run::<Renderer2D>(setup, update)
|
||||||
.run(update)
|
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue