Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix rendering of event graphics and the tilepicker #36

Merged
merged 6 commits into from
Sep 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 7 additions & 12 deletions src/components/tilepicker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ pub struct Tilepicker {
struct Resources {
tiles: primitives::Tiles,
viewport: primitives::Viewport,
atlas: primitives::Atlas,
}

#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
Expand All @@ -51,8 +50,8 @@ impl Tilepicker {
pub fn new(tileset: &rpg::Tileset) -> Result<Tilepicker, String> {
let atlas = state!().atlas_cache.load_atlas(tileset)?;

let tilepicker_data = [0, 48, 96, 144, 192, 240, 288, 336]
.into_iter()
let tilepicker_data = (0..384)
.step_by(48)
.chain(384..(atlas.tileset_height as i16 / 32 * 8 + 384))
.collect_vec();
let tilepicker_data = Table3::new_data(
Expand All @@ -61,7 +60,6 @@ impl Tilepicker {
1,
tilepicker_data,
);
let tiles = primitives::Tiles::new(atlas.clone(), &tilepicker_data);

let viewport = primitives::Viewport::new(cgmath::ortho(
0.0,
Expand All @@ -72,12 +70,10 @@ impl Tilepicker {
1.0,
));

let tiles = primitives::Tiles::new(atlas, &tilepicker_data);

Ok(Self {
resources: Arc::new(Resources {
tiles,
viewport,
atlas,
}),
resources: Arc::new(Resources { tiles, viewport }),
ani_instant: Instant::now(),
selected_tile: SelectedTile::default(),
})
Expand All @@ -91,7 +87,7 @@ impl Tilepicker {
ui.ctx().request_repaint_after(Duration::from_millis(16));

let (canvas_rect, response) = ui.allocate_exact_size(
egui::vec2(256., self.resources.atlas.tileset_height as f32),
egui::vec2(256., self.resources.tiles.atlas.tileset_height as f32),
egui::Sense::click_and_drag(),
);

Expand All @@ -113,7 +109,6 @@ impl Tilepicker {
vec![]
})
.paint(move |_info, render_pass, paint_callback_resources| {
//
let res_hash: &ResourcesSlab = paint_callback_resources.get().unwrap();
let id = paint_id.get().copied().expect("resources id is unset");
let resources = &res_hash[id];
Expand All @@ -122,7 +117,7 @@ impl Tilepicker {
} = resources.as_ref();

viewport.bind(render_pass);
tiles.draw(render_pass, &[]);
tiles.draw(render_pass, None);
}),
),
});
Expand Down
3 changes: 2 additions & 1 deletion src/graphics/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ impl Event {
};

let (quads, viewport, sprite_size) = if let Some(id) = page.graphic.tile_id {
let quad = atlas.calc_quad(id as i16, event.x as usize, event.y as usize);
// Why does this have to be + 1?
let quad = atlas.calc_quad((id + 1) as i16, event.x as usize, event.y as usize);

let viewport = primitives::Viewport::new(cgmath::ortho(0.0, 32., 32., 0., -1., 1.));

Expand Down
2 changes: 1 addition & 1 deletion src/graphics/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ impl Map {
}
}

tiles.draw(render_pass, &enabled_layers);
tiles.draw(render_pass, Some(&enabled_layers));
if fog_enabled {
if let Some(fog) = fog {
fog.draw(render_pass);
Expand Down
51 changes: 49 additions & 2 deletions src/graphics/primitives/tiles/atlas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,15 @@ pub const TILESET_WIDTH: u32 = TILE_SIZE * TILESET_COLUMNS; // self explanatory
pub const AUTOTILE_ID_AMOUNT: u32 = 48; // there are 48 tile ids per autotile
pub const AUTOTILE_FRAME_COLS: u32 = TILESET_COLUMNS; // this is how many "columns" of autotiles there are per frame
pub const AUTOTILE_AMOUNT: u32 = 7; // There are 7 autotiles per tileset
pub const TOTAL_AUTOTILE_ID_AMOUNT: u32 = AUTOTILE_ID_AMOUNT * (AUTOTILE_AMOUNT + 1); // the first 384 tile ids are for autotiles (including empty tiles)

pub const AUTOTILE_ROWS: u32 = AUTOTILE_ID_AMOUNT / AUTOTILE_FRAME_COLS; // split up the 48 tiles across each tileset row
pub const TOTAL_AUTOTILE_ROWS: u32 = AUTOTILE_ROWS * AUTOTILE_AMOUNT; // total number of rows for all autotiles combined
pub const AUTOTILE_ROW_HEIGHT: u32 = AUTOTILE_ROWS * TILE_SIZE; // This is how high one row of autotiles is
pub const TOTAL_AUTOTILE_HEIGHT: u32 = AUTOTILE_ROW_HEIGHT * AUTOTILE_AMOUNT; // self explanatory
pub const HEIGHT_UNDER_AUTOTILES: u32 = MAX_SIZE - TOTAL_AUTOTILE_HEIGHT; // this is the height under autotiles
pub const ROWS_UNDER_AUTOTILES: u32 = MAX_SIZE / TILE_SIZE - TOTAL_AUTOTILE_ROWS; // number of rows under autotiles
pub const ROWS_UNDER_AUTOTILES_TIMES_COLUMNS: u32 = ROWS_UNDER_AUTOTILES * TILESET_COLUMNS;

pub const AUTOTILE_FRAME_WIDTH: u32 = AUTOTILE_FRAME_COLS * TILE_SIZE; // This is per frame!

Expand Down Expand Up @@ -244,9 +248,52 @@ impl Atlas {
}

pub fn calc_quad(&self, tile: i16, x: usize, y: usize) -> Quad {
let tile_u32 = if tile < 0 { 0 } else { tile as u32 };

let is_autotile = tile_u32 < TOTAL_AUTOTILE_ID_AMOUNT;
let max_frame_count = self.autotile_width / AUTOTILE_FRAME_WIDTH;
let max_tiles_under_autotiles = max_frame_count * ROWS_UNDER_AUTOTILES_TIMES_COLUMNS;
let is_under_autotiles = !is_autotile && tile_u32 - 384 < max_tiles_under_autotiles;

let atlas_tile_position = if tile_u32 < AUTOTILE_ID_AMOUNT {
egui::pos2(0., 0.)
} else if is_autotile {
egui::pos2(
((tile_u32 - AUTOTILE_ID_AMOUNT) % AUTOTILE_FRAME_COLS * TILE_SIZE) as f32,
((tile_u32 - AUTOTILE_ID_AMOUNT) / AUTOTILE_FRAME_COLS * TILE_SIZE) as f32,
)
} else if is_under_autotiles {
egui::pos2(
((tile_u32 % TILESET_COLUMNS
+ (tile_u32 - TOTAL_AUTOTILE_ID_AMOUNT) / ROWS_UNDER_AUTOTILES_TIMES_COLUMNS
* TILESET_COLUMNS)
* TILE_SIZE) as f32,
(((tile_u32 - TOTAL_AUTOTILE_ID_AMOUNT) / TILESET_COLUMNS % ROWS_UNDER_AUTOTILES
+ TOTAL_AUTOTILE_ROWS)
* 32) as f32,
)
} else {
egui::pos2(
((tile_u32 % TILESET_COLUMNS
+ ((tile_u32 - max_tiles_under_autotiles)
/ (MAX_SIZE / TILE_SIZE * TILESET_COLUMNS)
+ max_frame_count)
* TILESET_COLUMNS)
* TILE_SIZE) as f32,
((tile_u32 - max_tiles_under_autotiles) / TILESET_COLUMNS % (MAX_SIZE / TILE_SIZE)
* TILE_SIZE) as f32,
)
};

Quad::new(
egui::Rect::from_min_max(egui::pos2(0., 0.), egui::pos2(32., 32.0)),
egui::Rect::from_min_max(egui::pos2(0., 0.), egui::pos2(32., 32.0)),
egui::Rect::from_min_size(
egui::pos2(0., 0.),
egui::vec2(TILE_SIZE as f32, TILE_SIZE as f32),
),
egui::Rect::from_min_size(
atlas_tile_position,
egui::vec2(TILE_SIZE as f32, TILE_SIZE as f32),
),
0.0,
)
}
Expand Down
9 changes: 7 additions & 2 deletions src/graphics/primitives/tiles/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,18 @@ impl Tiles {
pub fn draw<'rpass>(
&'rpass self,
render_pass: &mut wgpu::RenderPass<'rpass>,
enabled_layers: &[bool],
enabled_layers: Option<&[bool]>,
) {
render_pass.push_debug_group("tilemap tiles renderer");
Shader::bind(render_pass);
self.autotiles.bind(render_pass);
self.atlas.bind(render_pass);
for (layer, enabled) in enabled_layers.iter().copied().enumerate() {
for (layer, enabled) in enabled_layers
.unwrap_or(&[true])
.iter()
.copied()
.enumerate()
{
if enabled {
self.instances.draw(render_pass, layer);
}
Expand Down
30 changes: 25 additions & 5 deletions src/graphics/primitives/tiles/tilemap.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,31 @@ fn vs_main(vertex: VertexInput, instance: InstanceInput) -> VertexOutput {
let position = viewport.proj * vec4<f32>(vertex.position.xy + (instance.tile_position.xy * 32.), 0.0, 1.0);
out.clip_position = vec4<f32>(position.xy, instance.tile_position.z, 1.0);

var atlas_tile_position = vec2<f32>(
f32((instance.tile_id - 48) % 8 * 32),
f32((instance.tile_id - 48) / 8 * 32)
let is_autotile = instance.tile_id < 384;

// 1712 is the number of non-autotile tiles that can fit under the autotiles without wrapping around
let max_tiles_under_autotiles = i32(autotiles.max_frame_count) * 1712;
let is_under_autotiles = !is_autotile && instance.tile_id - 384 < max_tiles_under_autotiles;

var atlas_tile_position = select(
select(
vec2<f32>( // If the tile is not an autotile and is not located underneath the autotiles in the atlas
f32((instance.tile_id % 8 + ((instance.tile_id - max_tiles_under_autotiles) / 2048 + i32(autotiles.max_frame_count)) * 8) * 32),
f32((instance.tile_id - max_tiles_under_autotiles) / 8 % 256 * 32)
),
vec2<f32>( // If the tile is not an autotile but is located underneath the autotiles in the atlas
f32((instance.tile_id % 8 + (instance.tile_id - 384) / 1712 * 8) * 32),
f32(((instance.tile_id - 384) / 8 % 214 + 42) * 32)
),
is_under_autotiles
),
vec2<f32>( // If the tile is an autotile
f32((instance.tile_id - 48) % 8 * 32),
f32((instance.tile_id - 48) / 8 * 32)
),
is_autotile
);
if instance.tile_id < 384 {
if is_autotile {
let frame_count = autotiles.frame_counts[instance.tile_id / 48 - 1];
let frame = autotiles.animation_index % frame_count;
atlas_tile_position.x += f32(frame * 256u);
Expand All @@ -69,4 +89,4 @@ fn fs_main(input: VertexOutput) -> @location(0) vec4<f32> {
}

return color;
}
}