chore: renamed the resources directory to res
2
.gitignore
vendored
|
@ -1,2 +1,4 @@
|
|||
/Cargo.lock
|
||||
/target
|
||||
/build.rs
|
||||
/src/main.rs
|
||||
|
|
34
README.md
|
@ -20,7 +20,7 @@ project
|
|||
│ build.rs
|
||||
│ crates
|
||||
│ └── comet
|
||||
│ resources
|
||||
│ res
|
||||
│ └── shaders
|
||||
│ └── textures
|
||||
│ └── sounds
|
||||
|
@ -57,7 +57,7 @@ fn main() {
|
|||
App::new() // Generate a basic 2D app
|
||||
.with_preset(App2D) // Pre-registers the `Transform2D` component in the scene
|
||||
.with_title("Comet App") // Sets the window title
|
||||
.with_icon(r"resources/textures/comet_icon.png") // Sets the window icon
|
||||
.with_icon(r"res/textures/comet_icon.png") // Sets the window icon
|
||||
.with_size(1920, 1080) // Sets the window size
|
||||
.with_game_state(GameState::new()) // Adds a custom game state struct
|
||||
.run::<Renderer2D>(setup, update) // Starts app with the given
|
||||
|
@ -75,19 +75,19 @@ use std::path::PathBuf;
|
|||
|
||||
fn main() -> Result<()> {
|
||||
// Watch resource directories for changes
|
||||
println!("cargo:rerun-if-changed=resources/materials/*");
|
||||
println!("cargo:rerun-if-changed=resources/objects/*");
|
||||
println!("cargo:rerun-if-changed=resources/textures/*");
|
||||
println!("cargo:rerun-if-changed=resources/shaders/*");
|
||||
println!("cargo:rerun-if-changed=resources/data/*");
|
||||
println!("cargo:rerun-if-changed=resources/sounds/*");
|
||||
println!("cargo:rerun-if-changed=resources/fonts/*");
|
||||
println!("cargo:rerun-if-changed=res/materials/*");
|
||||
println!("cargo:rerun-if-changed=res/objects/*");
|
||||
println!("cargo:rerun-if-changed=res/textures/*");
|
||||
println!("cargo:rerun-if-changed=res/shaders/*");
|
||||
println!("cargo:rerun-if-changed=res/data/*");
|
||||
println!("cargo:rerun-if-changed=res/sounds/*");
|
||||
println!("cargo:rerun-if-changed=res/fonts/*");
|
||||
|
||||
let profile = env::var("PROFILE")?;
|
||||
let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR")?);
|
||||
let target_dir = manifest_dir.join("target").join(&profile);
|
||||
|
||||
let dest_resources_dir = target_dir.join("resources");
|
||||
let dest_resources_dir = target_dir.join("res");
|
||||
|
||||
std::fs::create_dir_all(&dest_resources_dir)?;
|
||||
|
||||
|
@ -96,13 +96,13 @@ fn main() -> Result<()> {
|
|||
copy_options.copy_inside = true;
|
||||
|
||||
let resource_folders = vec![
|
||||
"resources/materials/",
|
||||
"resources/objects/",
|
||||
"resources/textures/",
|
||||
"resources/shaders/",
|
||||
"resources/data/",
|
||||
"resources/sounds/",
|
||||
"resources/fonts/",
|
||||
"res/materials/",
|
||||
"res/objects/",
|
||||
"res/textures/",
|
||||
"res/shaders/",
|
||||
"res/data/",
|
||||
"res/sounds/",
|
||||
"res/fonts/",
|
||||
];
|
||||
|
||||
let resource_paths: Vec<PathBuf> = resource_folders
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
use crate::camera::{CameraUniform, RenderCamera};
|
||||
use crate::draw_info::DrawInfo;
|
||||
use crate::render_pass::{RenderPassInfo, RenderPassType};
|
||||
use crate::renderer::Renderer;
|
||||
use comet_colors::Color;
|
||||
use comet_ecs::{Camera2D, Component, Position2D, Render, Render2D, Scene, Text, Transform2D};
|
||||
use comet_log::*;
|
||||
use comet_math::{p2, p3, v2, v3};
|
||||
use comet_resources::texture_atlas::TextureRegion;
|
||||
use comet_resources::{graphic_resource_manager::GraphicResourceManager, Texture, Vertex};
|
||||
use comet_structs::ComponentSet;
|
||||
use std::iter;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use std::time::Instant;
|
||||
use wgpu::BufferUsages;
|
||||
use wgpu::core::command::DrawKind::Draw;
|
||||
use wgpu::naga::ShaderStage;
|
||||
use wgpu::util::DeviceExt;
|
||||
use wgpu::BufferUsages;
|
||||
use winit::dpi::PhysicalSize;
|
||||
use winit::window::Window;
|
||||
use comet_colors::Color;
|
||||
use comet_ecs::{Camera2D, Component, Position2D, Render, Render2D, Transform2D, Scene, Text};
|
||||
use comet_log::*;
|
||||
use comet_math::{p2, p3, v2, v3};
|
||||
use comet_resources::{graphic_resource_manager::GraphicResourceManager, Texture, Vertex};
|
||||
use comet_resources::texture_atlas::TextureRegion;
|
||||
use comet_structs::ComponentSet;
|
||||
use crate::camera::{RenderCamera, CameraUniform};
|
||||
use crate::draw_info::DrawInfo;
|
||||
use crate::render_pass::{RenderPassInfo, RenderPassType};
|
||||
use crate::renderer::Renderer;
|
||||
|
||||
pub struct Renderer2D<'a> {
|
||||
surface: wgpu::Surface<'a>,
|
||||
|
@ -54,16 +54,14 @@ impl<'a> Renderer2D<'a> {
|
|||
|
||||
let surface = instance.create_surface(window).unwrap();
|
||||
|
||||
let adapter = pollster::block_on(instance
|
||||
.request_adapter(&wgpu::RequestAdapterOptions {
|
||||
let adapter = pollster::block_on(instance.request_adapter(&wgpu::RequestAdapterOptions {
|
||||
power_preference: wgpu::PowerPreference::default(),
|
||||
compatible_surface: Some(&surface),
|
||||
force_fallback_adapter: false,
|
||||
}))
|
||||
.unwrap();
|
||||
|
||||
let (device, queue) = pollster::block_on(adapter
|
||||
.request_device(
|
||||
let (device, queue) = pollster::block_on(adapter.request_device(
|
||||
&wgpu::DeviceDescriptor {
|
||||
label: None,
|
||||
required_features: wgpu::Features::empty(),
|
||||
|
@ -99,7 +97,7 @@ impl<'a> Renderer2D<'a> {
|
|||
|
||||
let graphic_resource_manager = GraphicResourceManager::new();
|
||||
|
||||
let diffuse_bytes = include_bytes!(r"../../../resources/textures/comet_icon.png");
|
||||
let diffuse_bytes = include_bytes!(r"../../../res/textures/comet_icon.png");
|
||||
let diffuse_texture =
|
||||
Texture::from_bytes(&device, &queue, diffuse_bytes, "comet_icon.png", false).unwrap();
|
||||
|
||||
|
@ -164,14 +162,12 @@ impl<'a> Renderer2D<'a> {
|
|||
let render_pipeline_layout =
|
||||
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
label: Some("Render Pipeline Layout"),
|
||||
bind_group_layouts: &[
|
||||
&texture_bind_group_layout,
|
||||
&camera_bind_group_layout,
|
||||
],
|
||||
bind_group_layouts: &[&texture_bind_group_layout, &camera_bind_group_layout],
|
||||
push_constant_ranges: &[],
|
||||
});
|
||||
|
||||
let universal_render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||
let universal_render_pipeline =
|
||||
device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||
label: Some("Render Pipeline"),
|
||||
layout: Some(&render_pipeline_layout),
|
||||
vertex: wgpu::VertexState {
|
||||
|
@ -237,7 +233,7 @@ impl<'a> Renderer2D<'a> {
|
|||
g: 0.0,
|
||||
b: 0.0,
|
||||
a: 1.0,
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
let texture_sampler = device.create_sampler(&wgpu::SamplerDescriptor {
|
||||
|
@ -266,7 +262,9 @@ impl<'a> Renderer2D<'a> {
|
|||
sample_count: 1,
|
||||
dimension: wgpu::TextureDimension::D2,
|
||||
format: wgpu::TextureFormat::Bgra8UnormSrgb,
|
||||
usage: wgpu::TextureUsages::COPY_SRC | wgpu::TextureUsages::COPY_DST | wgpu::TextureUsages::TEXTURE_BINDING,
|
||||
usage: wgpu::TextureUsages::COPY_SRC
|
||||
| wgpu::TextureUsages::COPY_DST
|
||||
| wgpu::TextureUsages::TEXTURE_BINDING,
|
||||
view_formats: &[wgpu::TextureFormat::Bgra8UnormSrgb],
|
||||
});
|
||||
|
||||
|
@ -275,7 +273,9 @@ impl<'a> Renderer2D<'a> {
|
|||
entries: &[
|
||||
wgpu::BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: wgpu::BindingResource::TextureView(&empty_texture.create_view(&wgpu::TextureViewDescriptor::default())),
|
||||
resource: wgpu::BindingResource::TextureView(
|
||||
&empty_texture.create_view(&wgpu::TextureViewDescriptor::default()),
|
||||
),
|
||||
},
|
||||
wgpu::BindGroupEntry {
|
||||
binding: 1,
|
||||
|
|
|
@ -1,20 +1,24 @@
|
|||
use crate::{
|
||||
camera::{CameraUniform, RenderCamera},
|
||||
draw_info::DrawInfo,
|
||||
renderer::Renderer,
|
||||
};
|
||||
use comet_colors::Color;
|
||||
use comet_ecs::{Camera2D, Component, Position2D, Render, Render2D, Scene, Text, Transform2D};
|
||||
use comet_log::*;
|
||||
use comet_math::{p2, v2, v3};
|
||||
use comet_resources::texture_atlas::TextureRegion;
|
||||
use comet_resources::{graphic_resource_manager::GraphicResourceManager, Texture, Vertex};
|
||||
use comet_structs::ComponentSet;
|
||||
use std::iter;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use std::time::Instant;
|
||||
use wgpu::BufferUsages;
|
||||
use wgpu::naga::ShaderStage;
|
||||
use wgpu::util::DeviceExt;
|
||||
use wgpu::BufferUsages;
|
||||
use winit::dpi::PhysicalSize;
|
||||
use winit::window::Window;
|
||||
use comet_colors::Color;
|
||||
use comet_ecs::{Camera2D, Component, Position2D, Render, Render2D, Transform2D, Scene, Text};
|
||||
use comet_log::*;
|
||||
use comet_math::{p2, v2, v3};
|
||||
use comet_resources::{graphic_resource_manager::GraphicResourceManager, Texture, Vertex};
|
||||
use comet_resources::texture_atlas::TextureRegion;
|
||||
use comet_structs::ComponentSet;
|
||||
use crate::{renderer::Renderer, draw_info::DrawInfo, camera::{RenderCamera, CameraUniform}};
|
||||
|
||||
pub struct Renderer2D<'a> {
|
||||
surface: wgpu::Surface<'a>,
|
||||
|
@ -38,7 +42,7 @@ pub struct Renderer2D<'a> {
|
|||
|
||||
impl<'a> Renderer2D<'a> {
|
||||
pub fn new(window: Arc<Window>, clear_color: Option<impl Color>) -> Renderer2D<'a> {
|
||||
let size = window.inner_size();//PhysicalSize::<u32>::new(1920, 1080);
|
||||
let size = window.inner_size(); //PhysicalSize::<u32>::new(1920, 1080);
|
||||
|
||||
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
|
||||
backends: wgpu::Backends::PRIMARY,
|
||||
|
@ -47,16 +51,14 @@ impl<'a> Renderer2D<'a> {
|
|||
|
||||
let surface = instance.create_surface(window).unwrap();
|
||||
|
||||
let adapter = pollster::block_on(instance
|
||||
.request_adapter(&wgpu::RequestAdapterOptions {
|
||||
let adapter = pollster::block_on(instance.request_adapter(&wgpu::RequestAdapterOptions {
|
||||
power_preference: wgpu::PowerPreference::default(),
|
||||
compatible_surface: Some(&surface),
|
||||
force_fallback_adapter: false,
|
||||
}))
|
||||
.unwrap();
|
||||
|
||||
let (device, queue) = pollster::block_on(adapter
|
||||
.request_device(
|
||||
let (device, queue) = pollster::block_on(adapter.request_device(
|
||||
&wgpu::DeviceDescriptor {
|
||||
label: None,
|
||||
required_features: wgpu::Features::empty(),
|
||||
|
@ -153,14 +155,12 @@ impl<'a> Renderer2D<'a> {
|
|||
let render_pipeline_layout =
|
||||
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
label: Some("Universal Render Pipeline Layout"),
|
||||
bind_group_layouts: &[
|
||||
&texture_bind_group_layout,
|
||||
&camera_bind_group_layout,
|
||||
],
|
||||
bind_group_layouts: &[&texture_bind_group_layout, &camera_bind_group_layout],
|
||||
push_constant_ranges: &[],
|
||||
});
|
||||
|
||||
let universal_render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||
let universal_render_pipeline =
|
||||
device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||
label: Some("Universal Render Pipeline"),
|
||||
layout: Some(&render_pipeline_layout),
|
||||
vertex: wgpu::VertexState {
|
||||
|
@ -216,7 +216,7 @@ impl<'a> Renderer2D<'a> {
|
|||
g: 0.0,
|
||||
b: 0.0,
|
||||
a: 1.0,
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
let texture_sampler = device.create_sampler(&wgpu::SamplerDescriptor {
|
||||
|
@ -235,17 +235,22 @@ impl<'a> Renderer2D<'a> {
|
|||
});
|
||||
|
||||
let mut draw_info: Vec<DrawInfo> = Vec::new();
|
||||
draw_info.push(
|
||||
DrawInfo::new(
|
||||
draw_info.push(DrawInfo::new(
|
||||
"Universal Draw".to_string(),
|
||||
&device,
|
||||
&Texture::from_image(&device, &queue, &image::DynamicImage::new(1, 1, image::ColorType::Rgba8), None, false).unwrap(),
|
||||
&Texture::from_image(
|
||||
&device,
|
||||
&queue,
|
||||
&image::DynamicImage::new(1, 1, image::ColorType::Rgba8),
|
||||
None,
|
||||
false,
|
||||
)
|
||||
.unwrap(),
|
||||
&texture_bind_group_layout,
|
||||
&texture_sampler,
|
||||
vec![],
|
||||
vec![],
|
||||
)
|
||||
);
|
||||
));
|
||||
|
||||
Self {
|
||||
surface,
|
||||
|
@ -304,7 +309,23 @@ impl<'a> Renderer2D<'a> {
|
|||
|
||||
/// A function that loads a shader from the resources/shaders dir given the full name of the shader file.
|
||||
pub fn load_shader(&mut self, file_name: &str, shader_stage: Option<ShaderStage>) {
|
||||
self.graphic_resource_manager.load_shader(shader_stage, ((Self::get_project_root().unwrap().as_os_str().to_str().unwrap().to_string() + "/resources/shaders/").as_str().to_string() + file_name).as_str(), &self.device).unwrap();
|
||||
self.graphic_resource_manager
|
||||
.load_shader(
|
||||
shader_stage,
|
||||
((Self::get_project_root()
|
||||
.unwrap()
|
||||
.as_os_str()
|
||||
.to_str()
|
||||
.unwrap()
|
||||
.to_string()
|
||||
+ "/res/shaders/")
|
||||
.as_str()
|
||||
.to_string()
|
||||
+ file_name)
|
||||
.as_str(),
|
||||
&self.device,
|
||||
)
|
||||
.unwrap();
|
||||
info!("Shader ({}) loaded successfully", file_name);
|
||||
}
|
||||
|
||||
|
@ -335,7 +356,14 @@ impl<'a> Renderer2D<'a> {
|
|||
/// A function to load a TTF font from the specified path
|
||||
pub fn load_font(&mut self, path: &str, size: f32) {
|
||||
self.graphic_resource_manager.load_font(path, size);
|
||||
let atlas = self.graphic_resource_manager.fonts().iter().find(|f| f.name() == path).unwrap().glyphs().atlas();
|
||||
let atlas = self
|
||||
.graphic_resource_manager
|
||||
.fonts()
|
||||
.iter()
|
||||
.find(|f| f.name() == path)
|
||||
.unwrap()
|
||||
.glyphs()
|
||||
.atlas();
|
||||
let font_info = DrawInfo::new(
|
||||
format!("{}", path),
|
||||
&self.device,
|
||||
|
@ -351,15 +379,28 @@ impl<'a> Renderer2D<'a> {
|
|||
|
||||
/// An interface for getting the location of the texture in the texture atlas.
|
||||
pub fn get_texture_region(&self, texture_path: String) -> Option<&TextureRegion> {
|
||||
if !self.graphic_resource_manager.texture_atlas().textures().contains_key(&texture_path) {
|
||||
if !self
|
||||
.graphic_resource_manager
|
||||
.texture_atlas()
|
||||
.textures()
|
||||
.contains_key(&texture_path)
|
||||
{
|
||||
error!("Texture {} not found in atlas", &texture_path);
|
||||
}
|
||||
self.graphic_resource_manager.texture_atlas().textures().get(&texture_path)
|
||||
self.graphic_resource_manager
|
||||
.texture_atlas()
|
||||
.textures()
|
||||
.get(&texture_path)
|
||||
}
|
||||
|
||||
/// A function to get the `TextureRegion` of a specified glyph
|
||||
pub fn get_glyph_region(&self, glyph: char, font: String) -> &TextureRegion {
|
||||
let font_atlas = self.graphic_resource_manager.fonts().iter().find(|f| f.name() == font).unwrap();
|
||||
let font_atlas = self
|
||||
.graphic_resource_manager
|
||||
.fonts()
|
||||
.iter()
|
||||
.find(|f| f.name() == font)
|
||||
.unwrap();
|
||||
font_atlas.get_glyph(glyph).unwrap()
|
||||
}
|
||||
|
||||
|
@ -367,7 +408,18 @@ impl<'a> Renderer2D<'a> {
|
|||
/// The old texture atlas will be replaced with the new one.
|
||||
pub fn set_texture_atlas_by_paths(&mut self, paths: Vec<String>) {
|
||||
self.graphic_resource_manager.create_texture_atlas(paths);
|
||||
self.draw_info[0].set_texture(&self.device, &self.texture_bind_group_layout, &Texture::from_image(&self.device, &self.queue, self.graphic_resource_manager.texture_atlas().atlas(), None, false).unwrap());
|
||||
self.draw_info[0].set_texture(
|
||||
&self.device,
|
||||
&self.texture_bind_group_layout,
|
||||
&Texture::from_image(
|
||||
&self.device,
|
||||
&self.queue,
|
||||
self.graphic_resource_manager.texture_atlas().atlas(),
|
||||
None,
|
||||
false,
|
||||
)
|
||||
.unwrap(),
|
||||
);
|
||||
}
|
||||
|
||||
fn set_texture_atlas(&mut self, texture_atlas: Texture) {
|
||||
|
@ -383,23 +435,35 @@ impl<'a> Renderer2D<'a> {
|
|||
let mut path_ancestors = path.as_path().ancestors();
|
||||
|
||||
while let Some(p) = path_ancestors.next() {
|
||||
let has_cargo =
|
||||
std::fs::read_dir(p)?
|
||||
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))
|
||||
return Ok(PathBuf::from(p));
|
||||
}
|
||||
}
|
||||
Err(std::io::Error::new(std::io::ErrorKind::NotFound, "Ran out of places to find Cargo.toml"))
|
||||
Err(std::io::Error::new(
|
||||
std::io::ErrorKind::NotFound,
|
||||
"Ran out of places to find Cargo.toml",
|
||||
))
|
||||
}
|
||||
|
||||
/// A function that takes all the textures inside the resources/textures folder and creates a texture atlas from them.
|
||||
pub fn initialize_atlas(&mut self) {
|
||||
let texture_path = "resources/textures/".to_string();
|
||||
let texture_path = "res/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() {
|
||||
for path in std::fs::read_dir(
|
||||
Self::get_project_root()
|
||||
.unwrap()
|
||||
.as_os_str()
|
||||
.to_str()
|
||||
.unwrap()
|
||||
.to_string()
|
||||
+ "/res/textures",
|
||||
)
|
||||
.unwrap()
|
||||
{
|
||||
paths.push(texture_path.clone() + path.unwrap().file_name().to_str().unwrap());
|
||||
}
|
||||
|
||||
|
@ -412,24 +476,52 @@ impl<'a> Renderer2D<'a> {
|
|||
self.draw_info[0].update_index_buffer(&self.device, &self.queue, new_index_buffer);
|
||||
}
|
||||
|
||||
fn add_text_to_buffers(&self, text: String, font: String, size: f32, position: p2, color: wgpu::Color) -> (Vec<Vertex>, Vec<u16>) {
|
||||
let vert_color = [color.r as f32, color.g as f32, color.b as f32, color.a as f32];
|
||||
fn add_text_to_buffers(
|
||||
&self,
|
||||
text: String,
|
||||
font: String,
|
||||
size: f32,
|
||||
position: p2,
|
||||
color: wgpu::Color,
|
||||
) -> (Vec<Vertex>, Vec<u16>) {
|
||||
let vert_color = [
|
||||
color.r as f32,
|
||||
color.g as f32,
|
||||
color.b as f32,
|
||||
color.a as f32,
|
||||
];
|
||||
|
||||
let screen_position = p2::new(position.x()/self.config.width as f32, position.y()/self.config.height as f32);
|
||||
let scale_factor = size / self.graphic_resource_manager.fonts().iter().find(|f| f.name() == font).unwrap().size();
|
||||
let screen_position = p2::new(
|
||||
position.x() / self.config.width as f32,
|
||||
position.y() / self.config.height as f32,
|
||||
);
|
||||
let scale_factor = size
|
||||
/ self
|
||||
.graphic_resource_manager
|
||||
.fonts()
|
||||
.iter()
|
||||
.find(|f| f.name() == font)
|
||||
.unwrap()
|
||||
.size();
|
||||
|
||||
let line_height = (self.graphic_resource_manager.fonts().iter().find(|f| f.name() == font).unwrap().line_height() / self.config.height as f32) * scale_factor;
|
||||
let line_height = (self
|
||||
.graphic_resource_manager
|
||||
.fonts()
|
||||
.iter()
|
||||
.find(|f| f.name() == font)
|
||||
.unwrap()
|
||||
.line_height()
|
||||
/ self.config.height as f32)
|
||||
* scale_factor;
|
||||
let lines = text
|
||||
.split("\n")
|
||||
.map(|s| {
|
||||
s.split("").map(|escape| {
|
||||
match escape {
|
||||
_ if escape == "\t" => {
|
||||
" "
|
||||
}
|
||||
_ => escape
|
||||
}
|
||||
}).collect::<String>()
|
||||
s.split("")
|
||||
.map(|escape| match escape {
|
||||
_ if escape == "\t" => " ",
|
||||
_ => escape,
|
||||
})
|
||||
.collect::<String>()
|
||||
})
|
||||
.collect::<Vec<String>>();
|
||||
|
||||
|
@ -456,16 +548,36 @@ impl<'a> Renderer2D<'a> {
|
|||
let glyph_bottom = glyph_top - h;
|
||||
|
||||
let vertices: &mut Vec<Vertex> = &mut vec![
|
||||
Vertex::new([ glyph_left, glyph_top, 0.0 ], [region.u0(), region.v0()], vert_color),
|
||||
Vertex::new([ glyph_left, glyph_bottom, 0.0 ], [region.u0(), region.v1()], vert_color),
|
||||
Vertex::new([ glyph_right, glyph_bottom, 0.0 ], [region.u1(), region.v1()], vert_color),
|
||||
Vertex::new([ glyph_right, glyph_top, 0.0 ], [region.u1(), region.v0()], vert_color),
|
||||
Vertex::new(
|
||||
[glyph_left, glyph_top, 0.0],
|
||||
[region.u0(), region.v0()],
|
||||
vert_color,
|
||||
),
|
||||
Vertex::new(
|
||||
[glyph_left, glyph_bottom, 0.0],
|
||||
[region.u0(), region.v1()],
|
||||
vert_color,
|
||||
),
|
||||
Vertex::new(
|
||||
[glyph_right, glyph_bottom, 0.0],
|
||||
[region.u1(), region.v1()],
|
||||
vert_color,
|
||||
),
|
||||
Vertex::new(
|
||||
[glyph_right, glyph_top, 0.0],
|
||||
[region.u1(), region.v0()],
|
||||
vert_color,
|
||||
),
|
||||
];
|
||||
|
||||
let buffer_size = vertex_data.len() as u16;
|
||||
let indices: &mut Vec<u16> = &mut vec![
|
||||
buffer_size, buffer_size + 1, buffer_size + 3,
|
||||
buffer_size + 1, buffer_size + 2, buffer_size + 3,
|
||||
buffer_size,
|
||||
buffer_size + 1,
|
||||
buffer_size + 3,
|
||||
buffer_size + 1,
|
||||
buffer_size + 2,
|
||||
buffer_size + 3,
|
||||
];
|
||||
|
||||
x_offset += (region.advance() / self.config.width as f32) * scale_factor;
|
||||
|
@ -493,12 +605,21 @@ impl<'a> Renderer2D<'a> {
|
|||
position
|
||||
}
|
||||
|
||||
fn setup_camera<'b>(&mut self, cameras: Vec<usize>, scene: &'b Scene) -> (&'b Position2D, &'b Camera2D){
|
||||
let cam = cameras.get(
|
||||
fn setup_camera<'b>(
|
||||
&mut self,
|
||||
cameras: Vec<usize>,
|
||||
scene: &'b Scene,
|
||||
) -> (&'b Position2D, &'b Camera2D) {
|
||||
let cam = cameras
|
||||
.get(
|
||||
self.find_priority_camera(
|
||||
cameras.iter().map(|e| *scene.get_component::<Camera2D>(*e).unwrap()
|
||||
).collect::<Vec<Camera2D>>())
|
||||
).unwrap();
|
||||
cameras
|
||||
.iter()
|
||||
.map(|e| *scene.get_component::<Camera2D>(*e).unwrap())
|
||||
.collect::<Vec<Camera2D>>(),
|
||||
),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let camera_component = scene.get_component::<Camera2D>(*cam).unwrap();
|
||||
let camera_position = scene.get_component::<Transform2D>(*cam).unwrap().position();
|
||||
|
@ -506,20 +627,26 @@ impl<'a> Renderer2D<'a> {
|
|||
let camera = RenderCamera::new(
|
||||
camera_component.zoom(),
|
||||
camera_component.dimensions(),
|
||||
v3::new(camera_position.as_vec().x(),
|
||||
v3::new(
|
||||
camera_position.as_vec().x(),
|
||||
camera_position.as_vec().y(),
|
||||
0.0));
|
||||
0.0,
|
||||
),
|
||||
);
|
||||
let mut camera_uniform = CameraUniform::new();
|
||||
camera_uniform.update_view_proj(&camera);
|
||||
|
||||
let camera_buffer = self.device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
let camera_buffer = self
|
||||
.device
|
||||
.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("Universal Camera Buffer"),
|
||||
contents: bytemuck::cast_slice(&[camera_uniform]),
|
||||
usage: BufferUsages::UNIFORM | BufferUsages::COPY_DST,
|
||||
});
|
||||
|
||||
let camera_bind_group_layout =
|
||||
self.device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
self.device
|
||||
.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
entries: &[wgpu::BindGroupLayoutEntry {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStages::VERTEX,
|
||||
|
@ -560,7 +687,8 @@ impl<'a> Renderer2D<'a> {
|
|||
}
|
||||
|
||||
let entities = scene.get_entities_with(vec![Transform2D::type_id(), Render2D::type_id()]);
|
||||
let texts = scene.get_entities_with(vec![Transform2D::type_id(), comet_ecs::Text::type_id()]);
|
||||
let texts =
|
||||
scene.get_entities_with(vec![Transform2D::type_id(), comet_ecs::Text::type_id()]);
|
||||
|
||||
self.setup_camera(cameras, scene);
|
||||
|
||||
|
@ -579,7 +707,7 @@ impl<'a> Renderer2D<'a> {
|
|||
match self.get_texture_region(renderer_component.get_texture().to_string()) {
|
||||
Some(texture_region) => {
|
||||
t_region = Some(texture_region);
|
||||
},
|
||||
}
|
||||
None => continue,
|
||||
}
|
||||
let region = t_region.unwrap();
|
||||
|
@ -605,7 +733,7 @@ impl<'a> Renderer2D<'a> {
|
|||
let (x, y) = world_corners[i];
|
||||
rotated_world_corners[i] = (
|
||||
x * cos_angle - y * sin_angle + world_position.x(),
|
||||
x * sin_angle + y * cos_angle + world_position.y()
|
||||
x * sin_angle + y * cos_angle + world_position.y(),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -613,20 +741,40 @@ impl<'a> Renderer2D<'a> {
|
|||
for i in 0..4 {
|
||||
screen_corners[i] = (
|
||||
rotated_world_corners[i].0 / self.config().width as f32,
|
||||
rotated_world_corners[i].1 / self.config().height as f32
|
||||
rotated_world_corners[i].1 / self.config().height as f32,
|
||||
);
|
||||
}
|
||||
|
||||
vertex_buffer.append(&mut vec![
|
||||
Vertex :: new ( [screen_corners[0].0, screen_corners[0].1, 0.0], [region.u0(), region.v0()], [1.0, 1.0, 1.0, 1.0] ),
|
||||
Vertex :: new ( [screen_corners[1].0, screen_corners[1].1, 0.0], [region.u0(), region.v1()], [1.0, 1.0, 1.0, 1.0] ),
|
||||
Vertex :: new ( [screen_corners[2].0, screen_corners[2].1, 0.0], [region.u1(), region.v1()], [1.0, 1.0, 1.0, 1.0] ) ,
|
||||
Vertex :: new ( [screen_corners[3].0, screen_corners[3].1, 0.0], [region.u1(), region.v0()], [1.0, 1.0, 1.0, 1.0] )
|
||||
Vertex::new(
|
||||
[screen_corners[0].0, screen_corners[0].1, 0.0],
|
||||
[region.u0(), region.v0()],
|
||||
[1.0, 1.0, 1.0, 1.0],
|
||||
),
|
||||
Vertex::new(
|
||||
[screen_corners[1].0, screen_corners[1].1, 0.0],
|
||||
[region.u0(), region.v1()],
|
||||
[1.0, 1.0, 1.0, 1.0],
|
||||
),
|
||||
Vertex::new(
|
||||
[screen_corners[2].0, screen_corners[2].1, 0.0],
|
||||
[region.u1(), region.v1()],
|
||||
[1.0, 1.0, 1.0, 1.0],
|
||||
),
|
||||
Vertex::new(
|
||||
[screen_corners[3].0, screen_corners[3].1, 0.0],
|
||||
[region.u1(), region.v0()],
|
||||
[1.0, 1.0, 1.0, 1.0],
|
||||
),
|
||||
]);
|
||||
|
||||
index_buffer.append(&mut vec![
|
||||
0 + buffer_size, 1 + buffer_size, 3 + buffer_size,
|
||||
1 + buffer_size, 2 + buffer_size, 3 + buffer_size
|
||||
0 + buffer_size,
|
||||
1 + buffer_size,
|
||||
3 + buffer_size,
|
||||
1 + buffer_size,
|
||||
2 + buffer_size,
|
||||
3 + buffer_size,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -636,8 +784,18 @@ impl<'a> Renderer2D<'a> {
|
|||
let transform = scene.get_component::<Transform2D>(text).unwrap();
|
||||
|
||||
if component.is_visible() {
|
||||
let (vertices, indices) = self.add_text_to_buffers(component.content().to_string(), component.font().to_string(), component.font_size(), p2::from_vec(transform.position().as_vec()), component.color().to_wgpu());
|
||||
let draw = self.draw_info.iter_mut().find(|d| d.name() == &format!("{}", component.font())).unwrap();
|
||||
let (vertices, indices) = self.add_text_to_buffers(
|
||||
component.content().to_string(),
|
||||
component.font().to_string(),
|
||||
component.font_size(),
|
||||
p2::from_vec(transform.position().as_vec()),
|
||||
component.color().to_wgpu(),
|
||||
);
|
||||
let draw = self
|
||||
.draw_info
|
||||
.iter_mut()
|
||||
.find(|d| d.name() == &format!("{}", component.font()))
|
||||
.unwrap();
|
||||
draw.update_vertex_buffer(&self.device, &self.queue, vertices);
|
||||
draw.update_index_buffer(&self.device, &self.queue, indices);
|
||||
}
|
||||
|
@ -668,7 +826,9 @@ impl<'a> Renderer2D<'a> {
|
|||
|
||||
pub fn render(&mut self) -> Result<(), wgpu::SurfaceError> {
|
||||
let output = self.surface.get_current_texture()?;
|
||||
let output_view = output.texture.create_view(&wgpu::TextureViewDescriptor::default());
|
||||
let output_view = output
|
||||
.texture
|
||||
.create_view(&wgpu::TextureViewDescriptor::default());
|
||||
|
||||
let mut encoder = self
|
||||
.device
|
||||
|
@ -698,7 +858,10 @@ impl<'a> Renderer2D<'a> {
|
|||
render_pass.set_bind_group(0, self.draw_info[i].texture(), &[]);
|
||||
render_pass.set_bind_group(1, &self.camera_bind_group, &[]);
|
||||
render_pass.set_vertex_buffer(0, self.draw_info[i].vertex_buffer().slice(..));
|
||||
render_pass.set_index_buffer(self.draw_info[i].index_buffer().slice(..), wgpu::IndexFormat::Uint16);
|
||||
render_pass.set_index_buffer(
|
||||
self.draw_info[i].index_buffer().slice(..),
|
||||
wgpu::IndexFormat::Uint16,
|
||||
);
|
||||
render_pass.draw_indexed(0..self.draw_info[i].num_indices(), 0, 0..1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use comet::prelude::*;
|
||||
use winit_input_helper::WinitInputHelper;
|
||||
use comet_input::keyboard::Key;
|
||||
use winit_input_helper::WinitInputHelper;
|
||||
|
||||
fn setup(app: &mut App, renderer: &mut Renderer2D) {
|
||||
// Takes all the textures from resources/textures and puts them into a texture atlas
|
||||
// Takes all the textures from res/textures and puts them into a texture atlas
|
||||
renderer.initialize_atlas();
|
||||
|
||||
let camera = app.new_entity();
|
||||
|
@ -15,7 +15,7 @@ fn setup(app: &mut App, renderer: &mut Renderer2D) {
|
|||
app.add_component(e1, Transform2D::new());
|
||||
|
||||
let mut renderer2d = Render2D::new();
|
||||
renderer2d.set_texture(r"resources/textures/comet_icon.png");
|
||||
renderer2d.set_texture(r"res/textures/comet_icon.png");
|
||||
renderer2d.set_visibility(true);
|
||||
|
||||
app.add_component(e1, renderer2d);
|
||||
|
@ -36,7 +36,7 @@ fn handle_input(app: &mut App, dt: f32) {
|
|||
update_position(
|
||||
app.input_manager().clone(),
|
||||
app.get_component_mut::<Transform2D>(1).unwrap(),
|
||||
dt
|
||||
dt,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use comet::prelude::*;
|
||||
|
||||
fn setup(app: &mut App, renderer: &mut Renderer2D) {
|
||||
// Loading the font from the resources/fonts directory with a rendered size of 77px
|
||||
renderer.load_font("./resources/fonts/PressStart2P-Regular.ttf", 77.0);
|
||||
// Loading the font from the res/fonts directory with a rendered size of 77px
|
||||
renderer.load_font("./res/fonts/PressStart2P-Regular.ttf", 77.0);
|
||||
|
||||
// Setting up camera
|
||||
let camera = app.new_entity();
|
||||
|
@ -13,13 +13,16 @@ fn setup(app: &mut App, renderer: &mut Renderer2D) {
|
|||
// Creating the text entity
|
||||
let text = app.new_entity();
|
||||
app.add_component(text, Transform2D::new());
|
||||
app.add_component(text, Text::new(
|
||||
app.add_component(
|
||||
text,
|
||||
Text::new(
|
||||
"comet", // The content of the text
|
||||
"./resources/fonts/PressStart2P-Regular.ttf", // The used font (right now exact to the font path)
|
||||
"./res/fonts/PressStart2P-Regular.ttf", // The used font (right now exact to the font path)
|
||||
77.0, // Pixel size at which the font will be drawn
|
||||
true, // Should the text be visible
|
||||
sRgba::<f32>::from_hex("#abb2bfff") // Color of the text
|
||||
));
|
||||
sRgba::<f32>::from_hex("#abb2bfff"), // Color of the text
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
fn update(app: &mut App, renderer: &mut Renderer2D, dt: f32) {
|
||||
|
@ -28,8 +31,8 @@ fn update(app: &mut App, renderer: &mut Renderer2D, dt: f32) {
|
|||
|
||||
// Recalculating the position of the text every frame to ensure the same relative position
|
||||
let transform = app.get_component_mut::<Transform2D>(1).unwrap();
|
||||
transform.position_mut().set_x(-((size.width-50) as f32));
|
||||
transform.position_mut().set_y((size.height-100) as f32);
|
||||
transform.position_mut().set_x(-((size.width - 50) as f32));
|
||||
transform.position_mut().set_y((size.height - 100) as f32);
|
||||
|
||||
renderer.render_scene_2d(app.scene());
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ use comet::prelude::*;
|
|||
|
||||
fn setup(app: &mut App, renderer: &mut Renderer2D) {
|
||||
// Creating a texture atlas from the provided textures in the vector
|
||||
renderer.set_texture_atlas_by_paths(vec!["./resources/textures/comet_icon.png".to_string()]);
|
||||
renderer.set_texture_atlas_by_paths(vec!["./res/textures/comet_icon.png".to_string()]);
|
||||
|
||||
// Creating a camera entity
|
||||
let cam = app.new_entity();
|
||||
|
@ -15,7 +15,7 @@ fn setup(app: &mut App, renderer: &mut Renderer2D) {
|
|||
|
||||
let mut render = Render2D::new();
|
||||
render.set_visibility(true);
|
||||
render.set_texture("./resources/textures/comet_icon.png");
|
||||
render.set_texture("./res/textures/comet_icon.png");
|
||||
|
||||
app.add_component(e0, render);
|
||||
}
|
||||
|
|
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 9.9 KiB |
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 320 B After Width: | Height: | Size: 320 B |
Before Width: | Height: | Size: 5 KiB After Width: | Height: | Size: 5 KiB |
Before Width: | Height: | Size: 425 B After Width: | Height: | Size: 425 B |
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.1 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 736 B After Width: | Height: | Size: 736 B |
Before Width: | Height: | Size: 788 B After Width: | Height: | Size: 788 B |
Before Width: | Height: | Size: 878 B After Width: | Height: | Size: 878 B |
Before Width: | Height: | Size: 5 KiB After Width: | Height: | Size: 5 KiB |