mirror of
https://github.com/lisk77/comet.git
synced 2025-12-12 17:18:50 +00:00
Compare commits
5 commits
9c5a471519
...
a01a52766d
| Author | SHA1 | Date | |
|---|---|---|---|
| a01a52766d | |||
| 1a463770a3 | |||
| 90e514f642 | |||
| 8aec280447 | |||
| 4ed42b3de0 |
4 changed files with 78 additions and 45 deletions
|
|
@ -370,15 +370,9 @@ impl App {
|
||||||
WindowEvent::CloseRequested {} => elwt.exit(),
|
WindowEvent::CloseRequested {} => elwt.exit(),
|
||||||
WindowEvent::Focused(focused) => {
|
WindowEvent::Focused(focused) => {
|
||||||
window_focused = *focused;
|
window_focused = *focused;
|
||||||
if window_focused && !window_occluded {
|
|
||||||
window.request_redraw();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
WindowEvent::Occluded(occluded) => {
|
WindowEvent::Occluded(occluded) => {
|
||||||
window_occluded = *occluded;
|
window_occluded = *occluded;
|
||||||
if window_focused && !window_occluded {
|
|
||||||
window.request_redraw();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
WindowEvent::Resized(physical_size) => {
|
WindowEvent::Resized(physical_size) => {
|
||||||
renderer.resize(*physical_size);
|
renderer.resize(*physical_size);
|
||||||
|
|
@ -410,7 +404,6 @@ impl App {
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
Event::AboutToWait => {
|
Event::AboutToWait => {
|
||||||
elwt.set_control_flow(ControlFlow::Poll);
|
|
||||||
self.delta_time = renderer.update();
|
self.delta_time = renderer.update();
|
||||||
|
|
||||||
if self.dt() != f32::INFINITY {
|
if self.dt() != f32::INFINITY {
|
||||||
|
|
@ -425,6 +418,14 @@ impl App {
|
||||||
if window_focused && !window_occluded {
|
if window_focused && !window_occluded {
|
||||||
window.request_redraw();
|
window.request_redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.dt().is_finite() {
|
||||||
|
let next_frame = std::time::Instant::now()
|
||||||
|
+ std::time::Duration::from_secs_f32(self.update_timer);
|
||||||
|
elwt.set_control_flow(ControlFlow::WaitUntil(next_frame));
|
||||||
|
} else {
|
||||||
|
elwt.set_control_flow(ControlFlow::Wait);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -131,7 +131,7 @@ pub trait Collider {
|
||||||
pub trait Render {
|
pub trait Render {
|
||||||
fn is_visible(&self) -> bool;
|
fn is_visible(&self) -> bool;
|
||||||
fn set_visibility(&mut self, is_visible: bool);
|
fn set_visibility(&mut self, is_visible: bool);
|
||||||
fn get_texture(&self) -> String;
|
fn get_texture(&self) -> &str;
|
||||||
fn set_texture(&mut self, texture: &'static str);
|
fn set_texture(&mut self, texture: &'static str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -320,8 +320,8 @@ impl Render for Render2D {
|
||||||
self.is_visible = is_visible;
|
self.is_visible = is_visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_texture(&self) -> String {
|
fn get_texture(&self) -> &str {
|
||||||
self.texture_name.parse().unwrap()
|
self.texture_name
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Use the actual file name of the texture instead of the path
|
/// Use the actual file name of the texture instead of the path
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ macro_rules! error {
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! fatal {
|
macro_rules! fatal {
|
||||||
($fmt:expr $(, $args:expr)*) => {
|
($fmt:expr $(, $args:expr)*) => {{
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"{} [{}::{}] [{}] : {}",
|
"{} [{}::{}] [{}] : {}",
|
||||||
chrono::Local::now().format("%Y-%m-%d %H:%M:%S"),
|
chrono::Local::now().format("%Y-%m-%d %H:%M:%S"),
|
||||||
|
|
@ -66,7 +66,8 @@ macro_rules! fatal {
|
||||||
"\x1b[41mFATAL\x1b[0m",
|
"\x1b[41mFATAL\x1b[0m",
|
||||||
format!($fmt $(, $args)*)
|
format!($fmt $(, $args)*)
|
||||||
);
|
);
|
||||||
};
|
std::process::exit(1)
|
||||||
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,6 @@ impl<'a> Renderer2D<'a> {
|
||||||
paths.push(texture_path.clone() + path.unwrap().file_name().to_str().unwrap());
|
paths.push(texture_path.clone() + path.unwrap().file_name().to_str().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
self.resource_manager.create_texture_atlas(paths.clone());
|
|
||||||
self.init_atlas_by_paths(paths);
|
self.init_atlas_by_paths(paths);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -556,27 +555,29 @@ impl<'a> Renderer2D<'a> {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_texture_region(&self, texture_path: String) -> Option<&TextureRegion> {
|
fn get_texture_region(&self, texture_path: &str) -> Option<&TextureRegion> {
|
||||||
if !self
|
if !self
|
||||||
.resource_manager
|
.resource_manager
|
||||||
.texture_atlas()
|
.texture_atlas()
|
||||||
.textures()
|
.textures()
|
||||||
.contains_key(&texture_path)
|
.contains_key(texture_path)
|
||||||
{
|
{
|
||||||
error!("Texture {} not found in atlas", &texture_path);
|
#[cfg(comet_debug)]
|
||||||
|
error!("Texture {} not found in atlas", texture_path);
|
||||||
}
|
}
|
||||||
self.resource_manager
|
self.resource_manager
|
||||||
.texture_atlas()
|
.texture_atlas()
|
||||||
.textures()
|
.textures()
|
||||||
.get(&texture_path)
|
.get(texture_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_glyph_region(&self, glyph: char, font: String) -> &TextureRegion {
|
fn get_glyph_region(&self, glyph: char, font: &str) -> &TextureRegion {
|
||||||
let key = format!("{}::{}", font, glyph);
|
let key = format!("{}::{}", font, glyph);
|
||||||
|
|
||||||
match self.resource_manager.font_atlas().textures().get(&key) {
|
match self.resource_manager.font_atlas().textures().get(&key) {
|
||||||
Some(region) => region,
|
Some(region) => region,
|
||||||
None => {
|
None => {
|
||||||
|
#[cfg(comet_debug)]
|
||||||
warn!(
|
warn!(
|
||||||
"Missing glyph for character '{}' in font '{}', using fallback.",
|
"Missing glyph for character '{}' in font '{}', using fallback.",
|
||||||
glyph, font
|
glyph, font
|
||||||
|
|
@ -587,7 +588,7 @@ impl<'a> Renderer2D<'a> {
|
||||||
.textures()
|
.textures()
|
||||||
.get(&fallback_key)
|
.get(&fallback_key)
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
panic!(
|
fatal!(
|
||||||
"No fallback glyph available (space also missing) for font '{}'",
|
"No fallback glyph available (space also missing) for font '{}'",
|
||||||
font
|
font
|
||||||
)
|
)
|
||||||
|
|
@ -596,7 +597,7 @@ impl<'a> Renderer2D<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn precompute_text_bounds(&self, text: String, font: String, size: f32) -> v2 {
|
pub fn precompute_text_bounds(&self, text: &str, font: &str, size: f32) -> v2 {
|
||||||
let mut bounds = v2::ZERO;
|
let mut bounds = v2::ZERO;
|
||||||
|
|
||||||
let _ =
|
let _ =
|
||||||
|
|
@ -607,8 +608,8 @@ impl<'a> Renderer2D<'a> {
|
||||||
|
|
||||||
pub fn add_text_to_buffers(
|
pub fn add_text_to_buffers(
|
||||||
&self,
|
&self,
|
||||||
text: String,
|
text: &str,
|
||||||
font: String,
|
font: &str,
|
||||||
size: f32,
|
size: f32,
|
||||||
position: comet_math::v2,
|
position: comet_math::v2,
|
||||||
color: wgpu::Color,
|
color: wgpu::Color,
|
||||||
|
|
@ -673,7 +674,7 @@ impl<'a> Renderer2D<'a> {
|
||||||
|
|
||||||
for line in lines {
|
for line in lines {
|
||||||
for c in line.chars() {
|
for c in line.chars() {
|
||||||
let region = self.get_glyph_region(c, font.clone());
|
let region = self.get_glyph_region(c, font);
|
||||||
|
|
||||||
let (dim_x, dim_y) = region.dimensions();
|
let (dim_x, dim_y) = region.dimensions();
|
||||||
let w = (dim_x as f32 / config.width as f32) * scale_factor;
|
let w = (dim_x as f32 / config.width as f32) * scale_factor;
|
||||||
|
|
@ -773,7 +774,7 @@ impl<'a> Renderer2D<'a> {
|
||||||
let rotation_angle = transform_component.rotation().to_radians();
|
let rotation_angle = transform_component.rotation().to_radians();
|
||||||
|
|
||||||
let region =
|
let region =
|
||||||
match self.get_texture_region(renderer_component.get_texture().to_string()) {
|
match self.get_texture_region(renderer_component.get_texture()) {
|
||||||
Some(r) => r,
|
Some(r) => r,
|
||||||
None => continue,
|
None => continue,
|
||||||
};
|
};
|
||||||
|
|
@ -795,25 +796,54 @@ impl<'a> Renderer2D<'a> {
|
||||||
let cos_angle = rotation_angle.cos();
|
let cos_angle = rotation_angle.cos();
|
||||||
let sin_angle = rotation_angle.sin();
|
let sin_angle = rotation_angle.sin();
|
||||||
|
|
||||||
let rotated_world_corners: Vec<(f32, f32)> = world_corners
|
let rotated_world_corners = [
|
||||||
.iter()
|
|
||||||
.map(|(x, y)| {
|
|
||||||
(
|
(
|
||||||
x * cos_angle - y * sin_angle + world_position.x(),
|
world_corners[0].0 * cos_angle - world_corners[0].1 * sin_angle
|
||||||
x * sin_angle + y * cos_angle + world_position.y(),
|
+ world_position.x(),
|
||||||
)
|
world_corners[0].0 * sin_angle + world_corners[0].1 * cos_angle
|
||||||
})
|
+ world_position.y(),
|
||||||
.collect();
|
),
|
||||||
|
(
|
||||||
|
world_corners[1].0 * cos_angle - world_corners[1].1 * sin_angle
|
||||||
|
+ world_position.x(),
|
||||||
|
world_corners[1].0 * sin_angle + world_corners[1].1 * cos_angle
|
||||||
|
+ world_position.y(),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
world_corners[2].0 * cos_angle - world_corners[2].1 * sin_angle
|
||||||
|
+ world_position.x(),
|
||||||
|
world_corners[2].0 * sin_angle + world_corners[2].1 * cos_angle
|
||||||
|
+ world_position.y(),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
world_corners[3].0 * cos_angle - world_corners[3].1 * sin_angle
|
||||||
|
+ world_position.x(),
|
||||||
|
world_corners[3].0 * sin_angle + world_corners[3].1 * cos_angle
|
||||||
|
+ world_position.y(),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
let snapped_screen_corners: Vec<(f32, f32)> = rotated_world_corners
|
let inv_width = 1.0 / self.render_context.config().width as f32;
|
||||||
.iter()
|
let inv_height = 1.0 / self.render_context.config().height as f32;
|
||||||
.map(|(x, y)| {
|
|
||||||
|
let snapped_screen_corners = [
|
||||||
(
|
(
|
||||||
x.round() / self.render_context.config().width as f32,
|
rotated_world_corners[0].0.round() * inv_width,
|
||||||
y.round() / self.render_context.config().height as f32,
|
rotated_world_corners[0].1.round() * inv_height,
|
||||||
)
|
),
|
||||||
})
|
(
|
||||||
.collect();
|
rotated_world_corners[1].0.round() * inv_width,
|
||||||
|
rotated_world_corners[1].1.round() * inv_height,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
rotated_world_corners[2].0.round() * inv_width,
|
||||||
|
rotated_world_corners[2].1.round() * inv_height,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
rotated_world_corners[3].0.round() * inv_width,
|
||||||
|
rotated_world_corners[3].1.round() * inv_height,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
vertex_buffer.extend_from_slice(&[
|
vertex_buffer.extend_from_slice(&[
|
||||||
Vertex::new(
|
Vertex::new(
|
||||||
|
|
@ -868,16 +898,16 @@ impl<'a> Renderer2D<'a> {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let font = text_component.font().to_string();
|
let font = text_component.font();
|
||||||
let size = text_component.font_size();
|
let size = text_component.font_size();
|
||||||
let color = text_component.color().to_wgpu();
|
let color = text_component.color().to_wgpu();
|
||||||
let content = text_component.content().to_string();
|
let content = text_component.content();
|
||||||
|
|
||||||
let mut bounds = comet_math::v2::ZERO;
|
let mut bounds = comet_math::v2::ZERO;
|
||||||
|
|
||||||
let (vertices, indices) = self.add_text_to_buffers(
|
let (vertices, indices) = self.add_text_to_buffers(
|
||||||
content,
|
content,
|
||||||
font.clone(),
|
font,
|
||||||
size,
|
size,
|
||||||
position,
|
position,
|
||||||
color,
|
color,
|
||||||
|
|
@ -969,6 +999,7 @@ impl<'a> Renderer2D<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if resources.get_bind_group_layout("Font").is_none() {
|
if resources.get_bind_group_layout("Font").is_none() {
|
||||||
|
#[cfg(comet_debug)]
|
||||||
debug!("Font pass not initialized yet; skipping Font camera bind group setup.");
|
debug!("Font pass not initialized yet; skipping Font camera bind group setup.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue