log scales - drawn to rendertexture, and then *that* is drawn to draw

This commit is contained in:
Llywelwyn 2023-10-11 08:48:27 +01:00
parent 72a6ff6d14
commit 098617fbf1
3 changed files with 46 additions and 23 deletions

View file

@ -12,21 +12,15 @@ lazy_static! {
pub static ref LOG: Mutex<BTreeMap<i32, Vec<LogFragment>>> = 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<LogFragment>) {

View file

@ -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::*;

View file

@ -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<String, AudioSource> = vec![("hit".to_string(), sound)]
@ -501,12 +502,8 @@ fn draw_bg(_ecs: &World, draw: &mut Draw, atlas: &HashMap<String, Texture>) {
}
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::<RunState>();
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) {