Migrate map rendering to the new representation

This commit is contained in:
Tad Hardesty 2018-09-22 01:51:56 -07:00
parent f8eb39269a
commit d743eb5a3e
5 changed files with 47 additions and 88 deletions

7
Cargo.lock generated
View file

@ -1101,6 +1101,11 @@ dependencies = [
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "slice-of-array"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "slug"
version = "0.1.3"
@ -1153,6 +1158,7 @@ dependencies = [
"petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.76 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.76 (registry+https://github.com/rust-lang/crates.io-index)",
"slice-of-array 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"weak-table 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1679,6 +1685,7 @@ dependencies = [
"checksum serde_derive 1.0.76 (registry+https://github.com/rust-lang/crates.io-index)" = "7d8384360683b7114fc6eeeb41dde6ee37eeba2cf3660deef3a7a0d7548e55e9"
"checksum serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)" = "44dd2cfde475037451fa99b7e5df77aa3cfd1536575fa8e7a538ab36dcde49ae"
"checksum shared_library 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "5a9e7e0f2bfae24d8a5b5a66c5b257a83c7412304311512a0c054cd5e619da11"
"checksum slice-of-array 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fde46a15b5790cd2f87ea1a29368c2804295ba4b79f191d08e64182a13099ee5"
"checksum slug 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "797bcb4d24e91239a8615415814f4afb2d8ca400c472de3c73f803a5a7689e11"
"checksum smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "153ffa32fd170e9944f7e0838edf824a754ec4c1fc64746fcc9fe1f8fa602e5d"
"checksum smithay-client-toolkit 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f1609083d6bca3991a3c648d80ae16e1764d70881c3321bee1c915149073d605"

View file

@ -26,3 +26,4 @@ serde_derive = "1.0.76"
toml = "0.4.6"
petgraph = { version = "0.4.9", default-features = false }
weak-table = "0.2.3"
slice-of-array = "0.2.0"

View file

@ -17,6 +17,7 @@ extern crate toml;
extern crate petgraph;
extern crate gfx_gl as gl;
extern crate weak_table;
extern crate slice_of_array;
extern crate dreammaker as dm;
extern crate dmm_tools;
@ -221,6 +222,12 @@ impl EditorScene {
Ok(map) => map,
Err(arc) => (*arc).clone(),
};
let (x, y, z) = val.dim_xyz();
map.center = [x as f32 * 16.0, y as f32 * 16.0];
map.rendered.clear();
for _ in 0..z {
map.rendered.push(None);
}
MapState::Active { merge_base, hist: History::new("Loaded".to_owned(), val) }
} else {
MapState::Preparing(base, rx)
@ -1042,7 +1049,6 @@ impl EditorScene {
}
Ok(nfd::Response::OkayMultiple(fnames)) => {
for each in fnames {
// TODO: order these?
self.load_map(each.into());
}
}
@ -1132,17 +1138,16 @@ impl EditorScene {
fn render_map(&mut self, force: bool) {
if let Some(env) = self.environment.as_ref() {
if let Some(map) = self.maps.get_mut(self.map_current) {
/*TODO if map.rendered[map.z_current].is_some() && !force {
return;
if let Some(hist) = map.state.hist() {
if map.rendered[map.z_current].is_some() && !force {
return;
}
map.rendered[map.z_current] = Some(self.map_renderer.render(
hist.current(),
map.z_current as u32,
&mut self.factory,
));
}
map.rendered[map.z_current] = Some(self.map_renderer.prepare(
&env.objtree,
map.hist.current(),
map.z_current,
).render(
&mut self.map_renderer,
&mut self.factory,
));*/
}
}
}

View file

@ -6,14 +6,15 @@ use gfx;
use gfx::traits::{Factory as FactoryTrait, FactoryExt};
use {Resources, Factory, Encoder, ColorFormat, RenderTargetView, Texture};
use ndarray::Axis;
use slice_of_array::prelude::*;
use dm::objtree::ObjectTree;
use dm::constants::Constant;
use dmm_tools::dmm::{Map, Prefab};
use dmm_tools::dmm::Prefab;
use dmm_tools::minimap::{self, GetVar};
use dmi::*;
use map_repr::AtomMap;
const TILE_SIZE: u32 = 32;
@ -64,13 +65,6 @@ pub struct MapRenderer {
pub sampler: gfx::handle::Sampler<Resources>,
}
pub struct PreparedMap {
duration: f32,
pops: Vec<RenderPop>,
vertices: Vec<Vertex>,
instances: Vec<(u32, usize)>,
}
pub struct RenderedMap {
pub atoms_len: usize,
pub pops_len: usize,
@ -116,97 +110,49 @@ impl MapRenderer {
}
#[must_use]
pub fn prepare(&mut self, objtree: &ObjectTree, map: &Map, z: usize) -> PreparedMap {
use std::collections::BTreeMap;
pub fn render(&mut self, map: &AtomMap, z: u32, factory: &mut Factory) -> RenderedMap {
// ...
let start = Instant::now();
let level = &map.levels[z as usize];
// create pops from the dictionary
let mut pops = Vec::new();
let mut pop_reverse = BTreeMap::new();
let mut pop_dictionary = BTreeMap::new();
for (key, prefabs) in map.dictionary.iter() {
let mut all = Vec::new();
for fab in prefabs {
if let Some(pop) = RenderPop::from_prefab(&mut self.icons, objtree, fab) {
let idx;
if let Some(&i) = pop_reverse.get(&pop) {
idx = i;
} else {
idx = pops.len();
pop_reverse.insert(pop.clone(), idx);
pops.push(pop);
}
all.push(idx);
}
}
pop_dictionary.insert(*key, all);
}
// create instances from the grid
let mut vertices = Vec::new();
let mut instances = Vec::new();
for (y, row) in map.z_level(z).axis_iter(Axis(0)).rev().enumerate() {
for (x, key) in row.iter().enumerate() {
for &pop_id in pop_dictionary[key].iter() {
let v_start = vertices.len() as u32;
vertices.extend_from_slice(&pops[pop_id].instance((x as u32, y as u32)));
instances.push((v_start, pop_id));
}
}
}
// sort instances
instances.sort_by_key(|&(_, pop_id)| pops[pop_id].sort_key());
let duration = to_seconds(Instant::now() - start);
PreparedMap {
duration,
pops,
vertices,
instances,
}
}
}
impl PreparedMap {
#[must_use]
pub fn render(&self, parent: &mut MapRenderer, factory: &mut Factory) -> RenderedMap {
let start = Instant::now();
// TODO: determine how much of this loop belongs in prepare()
// TODO: use pre-maintained index buffer
// create index buffer
let mut indices = Vec::new();
let mut draw_calls: Vec<DrawCall> = Vec::new();
for &(start, pop_id) in self.instances.iter() {
for &inst in level.sorted_order.iter() {
let start = (4 * inst) as u32;
let i_start = indices.len() as u32;
indices.extend_from_slice(&[start, start+1, start+3, start+1, start+2, start+3]);
let pop = self.pops[pop_id];
let pop = &level.instances.get_key(inst).pop;
let rpop = match map.pops.get(pop) {
Some(rpop) => rpop,
None => continue,
};
if let Some(call) = draw_calls.last_mut() {
if call.texture_id == pop.texture && call.category == pop.category {
if call.texture_id == rpop.texture && call.category == rpop.category {
call.len += 6;
continue;
}
}
let texture = parent.icon_textures.retrieve(factory, &parent.icons, pop.texture as usize);
let texture = self.icon_textures.retrieve(factory, &self.icons, rpop.texture as usize);
draw_calls.push(DrawCall {
category: pop.category,
texture_id: pop.texture,
category: rpop.category,
texture_id: rpop.texture,
texture: texture.clone(),
start: i_start,
len: 6,
});
}
let vbuf = factory.create_vertex_buffer(&self.vertices[..]);
let vbuf = factory.create_vertex_buffer(map.vertex_buffer(z).flat());
let ibuf = factory.create_index_buffer(&indices[..]);
RenderedMap {
atoms_len: self.instances.len(),
pops_len: self.pops.len(),
duration: [self.duration, to_seconds(Instant::now() - start)],
atoms_len: level.instances.len(),
pops_len: map.pops.len(),
duration: [0.0, to_seconds(Instant::now() - start)],
draw_calls,
ibuf,

View file

@ -60,7 +60,7 @@ impl AtomMap {
for ((y, x), key) in map.z_level(z).indexed_iter() {
for fab in map.dictionary[key].iter() {
let pop = defer.add_pop(fab, icons, objtree);
defer.add_instance((x as u32, y as u32), pop);
defer.add_instance((x as u32, (dim_y - 1 - y) as u32), pop);
}
}
});