mirror of
https://github.com/lisk77/comet.git
synced 2025-10-24 05:48:50 +00:00
feat: added 2D scene rendering and initialization of the texture atlas
This commit is contained in:
parent
878e220249
commit
780365aeb8
12 changed files with 280 additions and 122 deletions
|
|
@ -8,6 +8,7 @@ comet_ecs = { path = "../comet_ecs" }
|
||||||
comet_renderer = { path = "../comet_renderer" }
|
comet_renderer = { path = "../comet_renderer" }
|
||||||
comet_resources = { path = "../comet_resources" }
|
comet_resources = { path = "../comet_resources" }
|
||||||
comet_colors = { path = "../comet_colors" }
|
comet_colors = { path = "../comet_colors" }
|
||||||
|
comet_log = { path = "../comet_log" }
|
||||||
|
|
||||||
winit = { version = "0.29", features = ["rwh_05"] }
|
winit = { version = "0.29", features = ["rwh_05"] }
|
||||||
env_logger = "0.10"
|
env_logger = "0.10"
|
||||||
|
|
@ -16,6 +17,7 @@ wgpu = { version = "22.0"}
|
||||||
log = "0.4.22"
|
log = "0.4.22"
|
||||||
anyhow = "1.0.89"
|
anyhow = "1.0.89"
|
||||||
bytemuck = "1.18.0"
|
bytemuck = "1.18.0"
|
||||||
|
chrono = "0.4.0"
|
||||||
|
|
||||||
[dependencies.image]
|
[dependencies.image]
|
||||||
version = "0.24"
|
version = "0.24"
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use comet_ecs::World;
|
use comet_ecs::{Component, ComponentSet, Render, Renderer2D, Transform2D, World};
|
||||||
use comet_resources::ResourceManager;
|
use comet_resources::{ResourceManager, Vertex};
|
||||||
use comet_renderer::{Renderer};
|
use comet_renderer::{Renderer};
|
||||||
|
|
||||||
use winit::{
|
use winit::{
|
||||||
|
|
@ -11,7 +11,7 @@ use winit::{
|
||||||
};
|
};
|
||||||
use comet_colors::LinearRgba;
|
use comet_colors::LinearRgba;
|
||||||
use comet_ecs::math::Point3;
|
use comet_ecs::math::Point3;
|
||||||
use log::warn;
|
use comet_log::*;
|
||||||
use winit::dpi::{LogicalSize, PhysicalSize};
|
use winit::dpi::{LogicalSize, PhysicalSize};
|
||||||
|
|
||||||
pub enum ApplicationType {
|
pub enum ApplicationType {
|
||||||
|
|
@ -74,6 +74,51 @@ impl<'a> App<'a> {
|
||||||
Some(Icon::from_rgba(rgba_image.into_raw(), width, height).unwrap())
|
Some(Icon::from_rgba(rgba_image.into_raw(), width, height).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn render_scene_2d(&self, renderer: &mut Renderer) {
|
||||||
|
let entities = self.world.get_entities_with(ComponentSet::from_ids(vec![Renderer2D::type_id()]));
|
||||||
|
let mut vertex_buffer: Vec<Vertex> = Vec::new();
|
||||||
|
let mut index_buffer: Vec<u16> = Vec::new();
|
||||||
|
|
||||||
|
for entity in entities {
|
||||||
|
let renderer_component = self.world().get_component::<Renderer2D>(entity as usize);
|
||||||
|
let transform_component = self.world().get_component::<Transform2D>(entity as usize);
|
||||||
|
|
||||||
|
if renderer_component.is_visible() {
|
||||||
|
//renderer.draw_texture_at(renderer_component.get_texture(), Point3::new(transform_component.position().x(), transform_component.position().y(), 0.0));
|
||||||
|
let position = transform_component.position();
|
||||||
|
let region = renderer.get_texture(renderer_component.get_texture().to_string());
|
||||||
|
let (dim_x, dim_y) = region.dimensions();
|
||||||
|
|
||||||
|
let (bound_x, bound_y) =
|
||||||
|
((dim_x as f32/ renderer.config().width as f32) * 0.5, (dim_y as f32/ renderer.config().height as f32) * 0.5);
|
||||||
|
|
||||||
|
let buffer_size = vertex_buffer.len() as u16;
|
||||||
|
|
||||||
|
vertex_buffer.append(&mut vec![
|
||||||
|
Vertex :: new ( [-bound_x + position.x(), bound_y + position.y(), 0.0], [region.x0(), region.y0()] ),
|
||||||
|
Vertex :: new ( [-bound_x + position.x(), -bound_y + position.y(), 0.0], [region.x0(), region.y1()] ),
|
||||||
|
Vertex :: new ( [ bound_x + position.x(), -bound_y + position.y(), 0.0], [region.x1(), region.y1()] ) ,
|
||||||
|
Vertex :: new ( [ bound_x + position.x(), bound_y + position.y(), 0.0], [region.x1(), region.y0()] )
|
||||||
|
]);
|
||||||
|
|
||||||
|
index_buffer.append(&mut vec![
|
||||||
|
0 + buffer_size, 1 + buffer_size, 3 + buffer_size,
|
||||||
|
1 + buffer_size, 2 + buffer_size, 3 + buffer_size
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
renderer.set_buffers(vertex_buffer, index_buffer);
|
||||||
|
|
||||||
|
/*for entity in entities {
|
||||||
|
let renderer_component = self.world.get_component::<Renderer2D>(entity as usize);
|
||||||
|
let position_component = self.world.get_component::<Transform2D>(entity as usize);
|
||||||
|
if renderer_component.is_visible() {
|
||||||
|
renderer.draw_texture_at(renderer_component.get_texture(), Point3::new(position_component.position().x(), position_component.position().y(), 0.0));
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
pub fn world(&self) -> &World {
|
pub fn world(&self) -> &World {
|
||||||
&self.world
|
&self.world
|
||||||
}
|
}
|
||||||
|
|
@ -116,12 +161,14 @@ impl<'a> App<'a> {
|
||||||
|
|
||||||
window.set_maximized(true);
|
window.set_maximized(true);
|
||||||
|
|
||||||
|
renderer.initialize_atlas();
|
||||||
|
|
||||||
event_loop.run(|event, control_flow| {
|
event_loop.run(|event, control_flow| {
|
||||||
if self.should_quit {
|
if self.should_quit {
|
||||||
control_flow.exit()
|
control_flow.exit()
|
||||||
}
|
}
|
||||||
|
|
||||||
game_manager(&mut self.world, &mut renderer);
|
game_manager(&mut self.world, &mut renderer);
|
||||||
|
self.render_scene_2d(&mut renderer);
|
||||||
|
|
||||||
match event {
|
match event {
|
||||||
Event::WindowEvent {
|
Event::WindowEvent {
|
||||||
|
|
@ -161,7 +208,9 @@ impl<'a> App<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => { input_manager(event, &mut self, &mut renderer) }
|
_ => {
|
||||||
|
input_manager(event, &mut self, &mut renderer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "comet_ecs"
|
name = "comet_ecs"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ pub fn my_trait_derive(input: TokenStream) -> TokenStream {
|
||||||
|
|
||||||
// Get the name of the struct
|
// Get the name of the struct
|
||||||
let name = &input.ident;
|
let name = &input.ident;
|
||||||
|
let name = &input.ident;
|
||||||
|
|
||||||
let fields = if let Data::Struct(data) = &input.data {
|
let fields = if let Data::Struct(data) = &input.data {
|
||||||
match &data.fields {
|
match &data.fields {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use std::path::Path;
|
//use comet_resources::Vertex;
|
||||||
use crate::math::{
|
use crate::math::{
|
||||||
Vec2,
|
Vec2,
|
||||||
Vec3
|
Vec3
|
||||||
|
|
@ -23,15 +23,12 @@ pub trait Component: Send + Sync + PartialEq + Default + 'static {
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct Position2D {
|
pub struct Position2D {
|
||||||
x: f32,
|
position: Vec2
|
||||||
y: f32
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct Position3D {
|
pub struct Position3D {
|
||||||
x: f32,
|
position: Vec3
|
||||||
y: f32,
|
|
||||||
z: f32
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
|
|
@ -50,83 +47,111 @@ pub struct Rotation3D {
|
||||||
pub struct Renderer2D {
|
pub struct Renderer2D {
|
||||||
is_visible: bool,
|
is_visible: bool,
|
||||||
texture: &'static str,
|
texture: &'static str,
|
||||||
scale: f32
|
scale: Vec2
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Position2D {
|
impl Position2D {
|
||||||
pub fn from_vec(vec: Vec2) -> Self {
|
pub fn from_vec(vec: Vec2) -> Self {
|
||||||
Self {
|
Self {
|
||||||
x: vec.x(),
|
position: vec
|
||||||
y: vec.y()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_vec(&self) -> Vec2 {
|
pub fn as_vec(&self) -> Vec2 {
|
||||||
Vec2::new(
|
self.position
|
||||||
self.x,
|
|
||||||
self.y
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn x(&self) -> &f32 {
|
pub fn x(&self) -> f32 {
|
||||||
&self.x
|
self.position.x()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn y(&self) -> &f32 {
|
pub fn y(&self) -> f32 {
|
||||||
&self.y
|
self.position.y()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_x(&mut self, new_x: f32) {
|
pub fn set_x(&mut self, new_x: f32) {
|
||||||
self.x = new_x;
|
self.position.set_x(new_x);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_y(&mut self, new_y: f32) {
|
pub fn set_y(&mut self, new_y: f32) {
|
||||||
self.y = new_y;
|
self.position.set_y(new_y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Position3D {
|
impl Position3D {
|
||||||
pub fn from_vec(vec: Vec3) -> Self {
|
pub fn from_vec(vec: Vec3) -> Self {
|
||||||
Self {
|
Self {
|
||||||
x: vec.x(),
|
position: vec
|
||||||
y: vec.y(),
|
|
||||||
z: vec.z()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_vec(&self) -> Vec3 {
|
pub fn as_vec(&self) -> Vec3 {
|
||||||
Vec3::new(
|
self.position
|
||||||
self.x,
|
|
||||||
self.y,
|
|
||||||
self.z
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn x(&self) -> &f32 {
|
pub fn x(&self) -> f32 {
|
||||||
&self.x
|
self.position.x()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn y(&self) -> &f32 {
|
pub fn y(&self) -> f32 {
|
||||||
&self.y
|
self.position.y()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn z(&self) -> &f32 {
|
pub fn z(&self) -> f32 {
|
||||||
&self.z
|
self.position.z()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_x(&mut self, new_x: f32) {
|
pub fn set_x(&mut self, new_x: f32) {
|
||||||
self.x = new_x;
|
self.position.set_x(new_x);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_y(&mut self, new_y: f32) {
|
pub fn set_y(&mut self, new_y: f32) {
|
||||||
self.y = new_y;
|
self.position.set_y(new_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_z(&mut self, new_z: f32) {
|
pub fn set_z(&mut self, new_z: f32) {
|
||||||
self.z = new_z
|
self.position.set_z(new_z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait Render {
|
||||||
|
fn is_visible(&self) -> bool;
|
||||||
|
fn set_visibility(&mut self, is_visible: bool);
|
||||||
|
fn get_texture(&self) -> String;
|
||||||
|
fn set_texture(&mut self, texture: &'static str);
|
||||||
|
//fn get_vertex_data(&self) -> Vec<Vertex>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Render for Renderer2D {
|
||||||
|
fn is_visible(&self) -> bool {
|
||||||
|
self.is_visible
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_visibility(&mut self, is_visible: bool) {
|
||||||
|
self.is_visible = is_visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_texture(&self) -> String {
|
||||||
|
self.texture.clone().parse().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Use the actual file name of the texture instead of the path
|
||||||
|
/// e.g. "comet_icon.png" instead of "resources/textures/comet_icon.png"
|
||||||
|
/// The resource manager will already look in the resources/textures folder
|
||||||
|
fn set_texture(&mut self, texture: &'static str) {
|
||||||
|
self.texture = texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*fn get_vertex_data(&self) -> Vec<Vertex> {
|
||||||
|
vec![
|
||||||
|
Vertex::new([0.0, 0.0, 0.0], [0.0, 0.0]),
|
||||||
|
Vertex::new([1.0, 0.0, 0.0], [1.0, 0.0]),
|
||||||
|
Vertex::new([1.0, 1.0, 0.0], [1.0, 1.0]),
|
||||||
|
Vertex::new([0.0, 1.0, 0.0], [0.0, 1.0])
|
||||||
|
]
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
// ##################################################
|
// ##################################################
|
||||||
// # BUNDLES #
|
// # BUNDLES #
|
||||||
// ##################################################
|
// ##################################################
|
||||||
|
|
|
||||||
|
|
@ -411,6 +411,17 @@ impl ComponentStorage {
|
||||||
self.keys.contains(type_id)
|
self.keys.contains(type_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn contains_components(&self, component_set: ComponentSet) -> bool {
|
||||||
|
let mut contains = true;
|
||||||
|
for type_id in component_set.set.iter() {
|
||||||
|
if !self.keys.contains(type_id) {
|
||||||
|
contains = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
contains
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get<T: Component + 'static>(&self) -> Option<&SparseSet> {
|
pub fn get<T: Component + 'static>(&self) -> Option<&SparseSet> {
|
||||||
self.components.get(*self.index_map.get(&T::type_id()).unwrap())
|
self.components.get(*self.index_map.get(&T::type_id()).unwrap())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -125,6 +125,25 @@ impl World {
|
||||||
self.archetypes.create_archetype(components);
|
self.archetypes.create_archetype(components);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn remove_archetype(&mut self, components: ComponentSet) {
|
||||||
|
self.archetypes.remove_archetype(&components);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_archetype_subsets(&mut self, components: ComponentSet) {
|
||||||
|
let component_sets = self.archetypes.component_sets();
|
||||||
|
let keys: Vec<ComponentSet> = component_sets.iter()
|
||||||
|
.enumerate()
|
||||||
|
.filter_map(|(i, &ref elem)| if elem.is_subset(&components) { Some(i) } else { None })
|
||||||
|
.collect::<Vec<usize>>()
|
||||||
|
.iter()
|
||||||
|
.map(|index| component_sets[*index].clone())
|
||||||
|
.collect::<Vec<ComponentSet>>();
|
||||||
|
|
||||||
|
for key in keys {
|
||||||
|
self.remove_archetype(key.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn add_entity_to_archetype(&mut self, entity_id: u32, components: ComponentSet) {
|
fn add_entity_to_archetype(&mut self, entity_id: u32, components: ComponentSet) {
|
||||||
self.archetypes.add_entity_to_archetype(&components, entity_id);
|
self.archetypes.add_entity_to_archetype(&components, entity_id);
|
||||||
}
|
}
|
||||||
|
|
@ -159,6 +178,7 @@ impl World {
|
||||||
|
|
||||||
pub fn register_component<T: Component + 'static>(&mut self) {
|
pub fn register_component<T: Component + 'static>(&mut self) {
|
||||||
self.components.register_component::<T>(self.entities.len());
|
self.components.register_component::<T>(self.entities.len());
|
||||||
|
self.create_archetype(ComponentSet::from_ids(vec![T::type_id()]));
|
||||||
info!(format!("Registered component: {}", T::type_name()));
|
info!(format!("Registered component: {}", T::type_name()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -177,8 +197,10 @@ impl World {
|
||||||
if !self.archetypes.contains_archetype(&self.get_component_set(entity_id)) {
|
if !self.archetypes.contains_archetype(&self.get_component_set(entity_id)) {
|
||||||
self.create_archetype(self.get_component_set(entity_id));
|
self.create_archetype(self.get_component_set(entity_id));
|
||||||
}
|
}
|
||||||
|
self.add_entity_to_archetype(entity_id as u32, ComponentSet::from_ids(vec![T::type_id()]));
|
||||||
|
if self.get_component_set(entity_id) != ComponentSet::from_ids(vec![T::type_id()]) {
|
||||||
self.add_entity_to_archetype(entity_id as u32, self.get_component_set(entity_id));
|
self.add_entity_to_archetype(entity_id as u32, self.get_component_set(entity_id));
|
||||||
|
}
|
||||||
info!(format!("Added component {} to entity {}", T::type_name(), entity_id));
|
info!(format!("Added component {} to entity {}", T::type_name(), entity_id));
|
||||||
debug!(format!("{:?}", self.archetypes));
|
debug!(format!("{:?}", self.archetypes));
|
||||||
}
|
}
|
||||||
|
|
@ -191,7 +213,7 @@ impl World {
|
||||||
|
|
||||||
pub fn get_component<T: Component + 'static>(&self, entity_id: usize) -> &T {
|
pub fn get_component<T: Component + 'static>(&self, entity_id: usize) -> &T {
|
||||||
assert_ne!(self.entities.get(entity_id), None, "There is no entity with this ID ({}) in the world!", entity_id);
|
assert_ne!(self.entities.get(entity_id), None, "There is no entity with this ID ({}) in the world!", entity_id);
|
||||||
assert!(self.components.get_component::<T>(entity_id) != None, "There is no component {} bound to the entity {} in the world!", T::type_name(), entity_id);
|
//assert_ne!(self.components.get_component::<T>(entity_id), None, "There is no component {} bound to the entity {} in the world!", T::type_name(), entity_id);
|
||||||
self.components.get_component::<T>(entity_id).unwrap()
|
self.components.get_component::<T>(entity_id).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -203,7 +225,7 @@ impl World {
|
||||||
|
|
||||||
pub fn get_entities_with(&self, components: ComponentSet) -> Vec<u32> {
|
pub fn get_entities_with(&self, components: ComponentSet) -> Vec<u32> {
|
||||||
assert!(self.archetypes.contains_archetype(&components), "The given components {:?} are not registered in the world!", components);
|
assert!(self.archetypes.contains_archetype(&components), "The given components {:?} are not registered in the world!", components);
|
||||||
info!(format!("Querying entities with components: {:?}", components));
|
//debug!(format!("Querying entities with components: {:?}", components));
|
||||||
self.archetypes.get_archetype(&components).unwrap().clone()
|
self.archetypes.get_archetype(&components).unwrap().clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ pub trait InnerSpace {
|
||||||
|
|
||||||
/// Representation of a 2D Vector
|
/// Representation of a 2D Vector
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Default)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
pub struct Vec2 {
|
pub struct Vec2 {
|
||||||
x: f32,
|
x: f32,
|
||||||
|
|
@ -43,6 +43,14 @@ impl Vec2 {
|
||||||
self.y
|
self.y
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_x(&mut self, new_x: f32) {
|
||||||
|
self.x = new_x;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_y(&mut self, new_y: f32) {
|
||||||
|
self.y = new_y;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn length(&self) -> f32 {
|
pub fn length(&self) -> f32 {
|
||||||
(self.x * self.x + self.y * self.y).sqrt()
|
(self.x * self.x + self.y * self.y).sqrt()
|
||||||
}
|
}
|
||||||
|
|
@ -123,7 +131,7 @@ impl Mul<f32> for Vec2 {
|
||||||
|
|
||||||
/// Representation of a 3D Vector
|
/// Representation of a 3D Vector
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Default)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
pub struct Vec3 {
|
pub struct Vec3 {
|
||||||
pub x: f32,
|
pub x: f32,
|
||||||
|
|
@ -161,6 +169,18 @@ impl Vec3 {
|
||||||
self.z
|
self.z
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_x(&mut self, new_x: f32) {
|
||||||
|
self.x = new_x;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_y(&mut self, new_y: f32) {
|
||||||
|
self.y = new_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_z(&mut self, new_z: f32) {
|
||||||
|
self.z = new_z;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn into_quaternion(&self) -> Quat {
|
pub fn into_quaternion(&self) -> Quat {
|
||||||
Quat {
|
Quat {
|
||||||
s: 0.0,
|
s: 0.0,
|
||||||
|
|
@ -418,7 +438,7 @@ impl Mul<f32> for Vec3 {
|
||||||
|
|
||||||
/// Representation of a 4D Vector
|
/// Representation of a 4D Vector
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Default)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
pub struct Vec4 {
|
pub struct Vec4 {
|
||||||
x: f32,
|
x: f32,
|
||||||
|
|
@ -469,6 +489,22 @@ impl Vec4 {
|
||||||
self.w
|
self.w
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_x(&mut self, new_x: f32) {
|
||||||
|
self.x = new_x;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_y(&mut self, new_y: f32) {
|
||||||
|
self.y = new_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_z(&mut self, new_z: f32) {
|
||||||
|
self.z = new_z;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_w(&mut self, new_w: f32) {
|
||||||
|
self.w = new_w;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn xxxx(&self) -> Vec4 {
|
pub fn xxxx(&self) -> Vec4 {
|
||||||
Vec4 {
|
Vec4 {
|
||||||
x: self.x,
|
x: self.x,
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ tobj = { version = "3.2", default-features = false, features = ["async"]}
|
||||||
wgpu = { version = "22.0"}
|
wgpu = { version = "22.0"}
|
||||||
winit = { version = "0.29", features = ["rwh_05"] }
|
winit = { version = "0.29", features = ["rwh_05"] }
|
||||||
instant = "0.1"
|
instant = "0.1"
|
||||||
|
chrono = "0.4.0"
|
||||||
|
|
||||||
[dependencies.image]
|
[dependencies.image]
|
||||||
version = "0.24"
|
version = "0.24"
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ mod camera;
|
||||||
|
|
||||||
use core::default::Default;
|
use core::default::Default;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
use std::path::PathBuf;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use cgmath::num_traits::FloatConst;
|
use cgmath::num_traits::FloatConst;
|
||||||
|
|
@ -13,67 +14,14 @@ use winit::{
|
||||||
dpi::PhysicalSize,
|
dpi::PhysicalSize,
|
||||||
window::Window
|
window::Window
|
||||||
};
|
};
|
||||||
|
use winit::dpi::Position;
|
||||||
use comet_colors::LinearRgba;
|
use comet_colors::LinearRgba;
|
||||||
|
use comet_log::error;
|
||||||
use comet_math;
|
use comet_math;
|
||||||
use comet_math::{Mat4, Point3, Vec3};
|
use comet_math::{Mat4, Point3, Vec3};
|
||||||
use comet_resources::{ResourceManager, texture, Vertex, Texture};
|
use comet_resources::{ResourceManager, texture, Vertex, Texture};
|
||||||
|
use comet_resources::texture_atlas::TextureRegion;
|
||||||
use crate::camera::{Camera, CameraUniform};
|
use crate::camera::{Camera, CameraUniform};
|
||||||
// RAINBOW TRIANGLE
|
|
||||||
/*const VERTICES: &[Vertex] = &[
|
|
||||||
Vertex :: new ( [0.0, 0.5, 0.0], [1.0, 0.0, 0.0] ),
|
|
||||||
Vertex :: new ( [-0.5, -0.5, 0.0], [0.0, 1.0, 0.0] ),
|
|
||||||
Vertex :: new ( [0.5, -0.5, 0.0], [0.0, 0.0, 1.0] ),
|
|
||||||
];*/
|
|
||||||
|
|
||||||
// RAW PENTAGON
|
|
||||||
/*const VERTICES: &[Vertex] = &[
|
|
||||||
Vertex :: new ( [-0.0868241, 0.49240386, 0.0], [0.5, 0.0, 0.5] ), // A
|
|
||||||
Vertex :: new ( [-0.49513406, 0.06958647, 0.0], [0.5, 0.0, 0.5] ), // B
|
|
||||||
Vertex :: new ( [-0.21918549, -0.44939706, 0.0], [0.5, 0.0, 0.5] ), // C
|
|
||||||
Vertex :: new ( [0.35966998, -0.3473291, 0.0], [0.5, 0.0, 0.5] ), // D
|
|
||||||
Vertex :: new ( [0.44147372, 0.2347359, 0.0], [0.5, 0.0, 0.5] ), // E
|
|
||||||
];*/
|
|
||||||
|
|
||||||
// RAINBOW PENTAGON
|
|
||||||
/*const VERTICES: &[Vertex] = &[
|
|
||||||
Vertex :: new ( [-0.0868241, 0.49240386, 0.0], [1.0, 0.0, 0.0] ), // A
|
|
||||||
Vertex :: new ( [-0.49513406, 0.06958647, 0.0], [0.0, 0.35, 1.0] ), // B
|
|
||||||
Vertex :: new ( [-0.21918549, -0.44939706, 0.0], [0.2, 1.0, 0.2] ), // C
|
|
||||||
Vertex :: new ( [0.35966998, -0.3473291, 0.0], [1.0, 0.85, 0.2] ), // D
|
|
||||||
Vertex :: new ( [0.44147372, 0.2347359, 0.0], [1.0, 0.2, 0.6] ), // E
|
|
||||||
];
|
|
||||||
|
|
||||||
const INDICES: &[u16] = &[
|
|
||||||
0, 1, 4,
|
|
||||||
1, 2, 4,
|
|
||||||
2, 3, 4,
|
|
||||||
];*/
|
|
||||||
|
|
||||||
// RAW QUAD
|
|
||||||
/*const VERTICES: &[Vertex] = &[
|
|
||||||
Vertex :: new ( [-0.5, 0.5, 0.0], [0.0, 0.0, 1.0] ),
|
|
||||||
Vertex :: new ( [-0.5, -0.5, 0.0], [0.0, 1.0, 0.0] ),
|
|
||||||
Vertex :: new ( [0.5, -0.5, 0.0], [1.0, 0.0, 0.0] ),
|
|
||||||
Vertex :: new ( [0.5, 0.5, 0.0], [1.0, 0.0, 1.0] )
|
|
||||||
];
|
|
||||||
|
|
||||||
const INDICES: &[u16] = &[
|
|
||||||
0, 1, 3,
|
|
||||||
1, 2, 3
|
|
||||||
];*/
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
vec![
|
|
||||||
Vertex :: new ( [-0.1, 0.1, 0.0], [0.0, 0.0] ),
|
|
||||||
Vertex :: new ( [-0.1, -0.1, 0.0], [0.0, 1.0] ),
|
|
||||||
Vertex :: new ( [0.1, -0.1, 0.0], [1.0, 1.0] ),
|
|
||||||
Vertex :: new ( [0.1, 0.1, 0.0], [1.0, 0.0] ),
|
|
||||||
], vec![
|
|
||||||
0, 1, 3,
|
|
||||||
1, 2, 3
|
|
||||||
]
|
|
||||||
*/
|
|
||||||
|
|
||||||
pub struct Projection {
|
pub struct Projection {
|
||||||
aspect: f32,
|
aspect: f32,
|
||||||
|
|
@ -410,6 +358,10 @@ impl<'a> Renderer<'a> {
|
||||||
self.deltatime
|
self.deltatime
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn config(&self) -> &wgpu::SurfaceConfiguration {
|
||||||
|
&self.config
|
||||||
|
}
|
||||||
|
|
||||||
fn vertex_data_mut(&mut self) -> &mut Vec<Vertex> {
|
fn vertex_data_mut(&mut self) -> &mut Vec<Vertex> {
|
||||||
&mut self.vertex_data
|
&mut self.vertex_data
|
||||||
}
|
}
|
||||||
|
|
@ -418,6 +370,11 @@ impl<'a> Renderer<'a> {
|
||||||
&mut self.index_data
|
&mut self.index_data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_texture(&self, texture_path: String) -> &TextureRegion {
|
||||||
|
assert!(self.resource_manager.texture_atlas().textures().contains_key(&texture_path), "Texture not found in atlas");
|
||||||
|
self.resource_manager.texture_atlas().textures().get(&texture_path).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
fn create_rectangle(&self, width: f32, height: f32) -> Vec<Vertex> {
|
fn create_rectangle(&self, width: f32, height: f32) -> Vec<Vertex> {
|
||||||
let (bound_x, bound_y) =
|
let (bound_x, bound_y) =
|
||||||
((width/ self.config.width as f32) * 0.5, (height/ self.config.height as f32) * 0.5);
|
((width/ self.config.width as f32) * 0.5, (height/ self.config.height as f32) * 0.5);
|
||||||
|
|
@ -512,7 +469,37 @@ impl<'a> Renderer<'a> {
|
||||||
self.diffuse_bind_group = diffuse_bind_group;
|
self.diffuse_bind_group = diffuse_bind_group;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn set_buffers(&mut self, new_vertex_buffer: Vec<Vertex>, new_index_buffer: Vec<u16>) {
|
pub fn get_project_root() -> std::io::Result<PathBuf> {
|
||||||
|
let path = std::env::current_dir()?;
|
||||||
|
let mut path_ancestors = path.as_path().ancestors();
|
||||||
|
|
||||||
|
while let Some(p) = path_ancestors.next() {
|
||||||
|
let has_cargo =
|
||||||
|
std::fs::read_dir(p)?
|
||||||
|
.into_iter()
|
||||||
|
.any(|p| p.unwrap().file_name() == std::ffi::OsString::from("Cargo.lock"));
|
||||||
|
if has_cargo {
|
||||||
|
return Ok(PathBuf::from(p))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(std::io::Error::new(std::io::ErrorKind::NotFound, "Ran out of places to find Cargo.toml"))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn initialize_atlas(&mut self) {
|
||||||
|
let texture_path = "resources/textures/".to_string();
|
||||||
|
let mut paths: Vec<String> = Vec::new();
|
||||||
|
|
||||||
|
for path in std::fs::read_dir(Self::get_project_root().unwrap().as_os_str().to_str().unwrap().to_string() + "\\resources\\textures").unwrap() {
|
||||||
|
paths.push(texture_path.clone() + path.unwrap().file_name().to_str().unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
error!(format!("{:?}", paths));
|
||||||
|
|
||||||
|
self.set_texture_atlas(paths);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_buffers(&mut self, new_vertex_buffer: Vec<Vertex>, new_index_buffer: Vec<u16>) {
|
||||||
match new_vertex_buffer == self.vertex_data {
|
match new_vertex_buffer == self.vertex_data {
|
||||||
true => return,
|
true => return,
|
||||||
false => {
|
false => {
|
||||||
|
|
@ -539,7 +526,7 @@ impl<'a> Renderer<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn push_to_buffers(&mut self, new_vertex_buffer: &mut Vec<Vertex>, new_index_buffer: &mut Vec<u16>) {
|
pub fn push_to_buffers(&mut self, new_vertex_buffer: &mut Vec<Vertex>, new_index_buffer: &mut Vec<u16>) {
|
||||||
self.vertex_data.append(new_vertex_buffer);
|
self.vertex_data.append(new_vertex_buffer);
|
||||||
self.index_data.append(new_index_buffer);
|
self.index_data.append(new_index_buffer);
|
||||||
|
|
||||||
|
|
@ -577,14 +564,12 @@ impl<'a> Renderer<'a> {
|
||||||
self.num_indices = self.index_data.len() as u32;
|
self.num_indices = self.index_data.len() as u32;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_texture_at(&mut self, texture_path: &str, position: Point3) {
|
pub fn draw_texture_at(&mut self, texture_path: String, position: Point3) {
|
||||||
let region = self.resource_manager.texture_locations().get(texture_path).unwrap();
|
let region = self.resource_manager.texture_locations().get(&texture_path).unwrap();
|
||||||
let (dim_x, dim_y) = region.dimensions();
|
let (dim_x, dim_y) = region.dimensions();
|
||||||
|
|
||||||
let (bound_x, bound_y) =
|
let (bound_x, bound_y) =
|
||||||
((dim_x as f32/ self.config.width as f32) * 0.5, (dim_y as f32/ self.config.height as f32) * 0.5);
|
((dim_x as f32/ self.config.width as f32) * 0.5, (dim_y as f32/ self.config.height as f32) * 0.5);
|
||||||
/*let bound_x = dim_x as f32/ self.config.width as f32 * 0.5;
|
|
||||||
let bound_y = bound_x;*/
|
|
||||||
|
|
||||||
let vertices: &mut Vec<Vertex> = &mut vec![
|
let vertices: &mut Vec<Vertex> = &mut vec![
|
||||||
Vertex :: new ( [-bound_x + position.x(), bound_y + position.y(), 0.0 + position.z()], [region.x0(), region.y0()] ),
|
Vertex :: new ( [-bound_x + position.x(), bound_y + position.y(), 0.0 + position.z()], [region.x0(), region.y0()] ),
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ use std::path::Path;
|
||||||
use chrono::Local;
|
use chrono::Local;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use image::{DynamicImage, GenericImage, GenericImageView, ImageFormat};
|
use image::{DynamicImage, GenericImage, GenericImageView, ImageFormat};
|
||||||
use comet_log::info;
|
use comet_log::*;
|
||||||
use wgpu::{Device, FilterMode, TextureFormat, TextureUsages};
|
use wgpu::{Device, FilterMode, TextureFormat, TextureUsages};
|
||||||
use crate::Texture;
|
use crate::Texture;
|
||||||
|
|
||||||
|
|
@ -165,6 +165,7 @@ impl TextureAtlas {
|
||||||
//base.save_with_format(output_path, ImageFormat::Png).expect("Failed to save texture atlas");
|
//base.save_with_format(output_path, ImageFormat::Png).expect("Failed to save texture atlas");
|
||||||
|
|
||||||
info!("Texture atlas created!");
|
info!("Texture atlas created!");
|
||||||
|
debug!(format!("{:?}", regions));
|
||||||
|
|
||||||
/*let t1 = Instant::now();
|
/*let t1 = Instant::now();
|
||||||
let delta = t1.duration_since(t0);
|
let delta = t1.duration_since(t0);
|
||||||
|
|
|
||||||
45
src/main.rs
45
src/main.rs
|
|
@ -10,30 +10,55 @@ use comet::{
|
||||||
log::*
|
log::*
|
||||||
};
|
};
|
||||||
use winit::event::{WindowEvent};
|
use winit::event::{WindowEvent};
|
||||||
use comet_ecs::{Component, ComponentSet, Transform2D};
|
use comet_ecs::{Component, ComponentSet, Render, Renderer2D, Transform2D};
|
||||||
use comet_input::mouse::{mouse_entered, mouse_pressed, Button};
|
use comet_input::mouse::{mouse_entered, mouse_pressed, Button};
|
||||||
|
|
||||||
#[derive(Component)]
|
|
||||||
struct TestComponent {
|
|
||||||
position: f32
|
|
||||||
}
|
|
||||||
|
|
||||||
fn input(event: &WindowEvent, app: &mut App, renderer: &mut Renderer) {
|
fn input(event: &WindowEvent, app: &mut App, renderer: &mut Renderer) {
|
||||||
match event {
|
match event {
|
||||||
_ if key_pressed(event, Key::KeyI) => app.world_mut().register_component::<TestComponent>(),
|
|
||||||
_ if key_pressed(event, Key::Escape) => app.quit(),
|
_ if key_pressed(event, Key::Escape) => app.quit(),
|
||||||
|
_ if key_pressed(event, Key::KeyC) => { renderer.clear_buffers() }
|
||||||
_ if key_pressed(event, Key::KeyE) => {
|
_ if key_pressed(event, Key::KeyE) => {
|
||||||
|
let mut renderer2d = Renderer2D::new();
|
||||||
|
renderer2d.set_texture(r"resources/textures/comet_icon.png");
|
||||||
|
renderer2d.set_visibility(true);
|
||||||
|
|
||||||
let id = app.world_mut().new_entity();
|
let id = app.world_mut().new_entity();
|
||||||
app.world_mut().add_component::<TestComponent>(id as usize, TestComponent::new())
|
app.world_mut().add_component(id as usize, renderer2d.clone());
|
||||||
|
app.world_mut().add_component(0, renderer2d);
|
||||||
|
|
||||||
|
let transform = app.world_mut().get_component_mut::<Transform2D>(id as usize);
|
||||||
|
transform.position_mut().set_x(0.5);
|
||||||
|
|
||||||
|
debug!(format!("{:?}", app.world().components().get_component::<Renderer2D>(0)));
|
||||||
},
|
},
|
||||||
_ if key_pressed(event, Key::KeyR) => {
|
_ if key_pressed(event, Key::KeyW) => {
|
||||||
debug!(format!("{:?}", app.world().get_entities_with(ComponentSet::from_ids(vec![Transform2D::type_id(), TestComponent::type_id()]))));
|
let transform = app.world_mut().get_component_mut::<Transform2D>(0);
|
||||||
|
let y = transform.position().y();
|
||||||
|
transform.position_mut().set_y(y + 0.1);
|
||||||
},
|
},
|
||||||
|
_ if key_pressed(event, Key::KeyA) => {
|
||||||
|
let transform = app.world_mut().get_component_mut::<Transform2D>(0);
|
||||||
|
let x = transform.position().x();
|
||||||
|
transform.position_mut().set_x(x - 0.1);
|
||||||
|
},
|
||||||
|
_ if key_pressed(event, Key::KeyS) => {
|
||||||
|
let transform = app.world_mut().get_component_mut::<Transform2D>(0);
|
||||||
|
let y = transform.position().y();
|
||||||
|
transform.position_mut().set_y(y - 0.1);
|
||||||
|
},
|
||||||
|
_ if key_pressed(event, Key::KeyD) => {
|
||||||
|
let transform = app.world_mut().get_component_mut::<Transform2D>(0);
|
||||||
|
let x = transform.position().x();
|
||||||
|
transform.position_mut().set_x(x + 0.1);
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(world: &mut World, renderer: &mut Renderer) {
|
fn update(world: &mut World, renderer: &mut Renderer) {
|
||||||
|
if !world.components().contains_components(ComponentSet::from_ids(vec![Transform2D::type_id(), Renderer2D::type_id()])) {
|
||||||
|
world.register_component::<Renderer2D>();
|
||||||
|
}
|
||||||
if world.entities().len() == 0 {
|
if world.entities().len() == 0 {
|
||||||
let id = world.new_entity();
|
let id = world.new_entity();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue