From 098617fbf1fbb2b0226cc31799c7b6d374a79f9d Mon Sep 17 00:00:00 2001 From: Llywelwyn Date: Wed, 11 Oct 2023 08:48:27 +0100 Subject: [PATCH] log scales - drawn to rendertexture, and then *that* is drawn to draw --- src/gamelog/logstore.rs | 24 +++++++++-------------- src/gamelog/mod.rs | 2 +- src/main.rs | 43 ++++++++++++++++++++++++++++++++++------- 3 files changed, 46 insertions(+), 23 deletions(-) diff --git a/src/gamelog/logstore.rs b/src/gamelog/logstore.rs index ac68695..5047fdc 100644 --- a/src/gamelog/logstore.rs +++ b/src/gamelog/logstore.rs @@ -12,21 +12,15 @@ lazy_static! { pub static ref LOG: Mutex>> = Mutex::new(BTreeMap::new()); } -/// Render with defaults, to avoid having to pass so many args. -pub fn render(draw: bool, gfx: &mut Graphics, font: &Fonts) { - if draw { - render_log( - gfx, - &font, - &(TILESIZE.x, TILESIZE.x * 6.0 + 4.0), - (VIEWPORT_W as f32) * TILESIZE.x, - 5 - ); - } -} - /// Render with specificied params. -pub fn render_log(gfx: &mut Graphics, font: &Fonts, pos: &(f32, f32), width: f32, entries: usize) { +pub fn render_log( + draw: &RenderTexture, + gfx: &mut Graphics, + font: &Fonts, + pos: &(f32, f32), + width: f32, + entries: usize +) { let mut text = gfx.create_text(); let log = LOG.lock().unwrap(); let latest: Vec<_> = log.iter().rev().take(entries).collect(); @@ -55,7 +49,7 @@ pub fn render_log(gfx: &mut Graphics, font: &Fonts, pos: &(f32, f32), width: f32 y = text.last_bounds().min_y(); } } - gfx.render(&text); + gfx.render_to(draw, &text); } pub fn append_entry(turn: i32, fragments: Vec) { diff --git a/src/gamelog/mod.rs b/src/gamelog/mod.rs index 4569ad1..5ae498d 100644 --- a/src/gamelog/mod.rs +++ b/src/gamelog/mod.rs @@ -2,7 +2,7 @@ mod builder; pub use builder::*; mod logstore; use logstore::*; -pub use logstore::{ LOG, clear_log, clone_log, render, render_log, restore_log, setup_log }; +pub use logstore::{ LOG, clear_log, clone_log, render_log, restore_log, setup_log }; mod events; pub use events::*; diff --git a/src/main.rs b/src/main.rs index d3c773c..5a469c1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,7 +20,8 @@ fn main() -> Result<(), String> { let win_config = WindowConfig::new() .set_size(DISPLAYWIDTH * (TILESIZE.x as u32), DISPLAYHEIGHT * (TILESIZE.x as u32)) .set_title("RUST-RL") - .set_resizable(true) + .set_resizable(false) + //.set_fullscreen(true) -- this can be uncommented once the log scales too. Ditto for set_resizable(true). .set_taskbar_icon_data(Some(include_bytes!("../resources/icon.png"))) .set_vsync(true); notan @@ -32,7 +33,7 @@ fn main() -> Result<(), String> { .build() } -fn setup(app: &mut App, gfx: &mut Graphics) -> State { +fn setup(_app: &mut App, gfx: &mut Graphics) -> State { /* let sound = app.audio.create_source(include_bytes!("../resources/sounds/hit.wav")).unwrap(); let sounds: HashMap = vec![("hit".to_string(), sound)] @@ -501,12 +502,8 @@ fn draw_bg(_ecs: &World, draw: &mut Draw, atlas: &HashMap) { } fn draw(app: &mut App, gfx: &mut Graphics, gs: &mut State) { - let (width, height) = gfx.size(); - let win_size = vec2(width as f32, height as f32); - let (projection, _) = calc_projection(win_size, WORK_SIZE); let mut draw = gfx.create_draw(); draw.clear(Color::BLACK); - draw.set_projection(Some(projection)); let mut log = false; let runstate = *gs.ecs.fetch::(); match runstate { @@ -589,8 +586,40 @@ fn draw(app: &mut App, gfx: &mut Graphics, gs: &mut State) { } _ => {} } + // TODO: Once the rest of drawing is finalised, this should be abstracted + // into some functions that make it easier to tell what is going on. But + // for the short-term: + // 1. notan::Text is required for rich text drawing, rather than just the + // basics that are accessible with notan::Draw's .text() method. + // 2. notan::Text cannot be projected, and rendering both Draw and Text + // requires two GPU calls instead of just one. + // 3. To fix this, our log is drawn to notan::Text, then rendered to a + // render texture, and applied as any other image to notan::Draw. + // 4. notan::Draw is projected, and then rendered, and everything works. + // Further stuff: Make the render texture only as large as is required, + // so text cannot escape the bounds of the logbox. + let (width, height) = gfx.size(); + let win_size = vec2(width as f32, height as f32); + let (projection, _) = calc_projection(win_size, WORK_SIZE); + if log { + let buffer = gfx + .create_render_texture(width, height) + .build() + .expect("Failed to create render texture"); + gamelog::render_log( + &buffer, + gfx, + &gs.font, + &(TILESIZE.x, TILESIZE.x * 6.0 + 4.0), + (VIEWPORT_W as f32) * TILESIZE.x, + 5 + ); + draw.image(&buffer) + .position(0.0, 0.0) + .size(width as f32, height as f32); + } + draw.set_projection(Some(projection)); gfx.render(&draw); - gamelog::render(log, gfx, &gs.font); } fn update(ctx: &mut App, state: &mut State) {