Tidy up chunk rendering
This commit is contained in:
parent
c5af132a21
commit
70ccd5cd3d
|
@ -16,7 +16,7 @@ pub struct ChunkBuilder {
|
|||
free_builders: Vec<(usize, Vec<u8>)>,
|
||||
built_recv: mpsc::Receiver<(usize, BuildReply)>,
|
||||
|
||||
sections: Vec<(i32, i32, i32, Arc<world::SectionKey>)>,
|
||||
sections: Vec<(i32, i32, i32)>,
|
||||
next_collection: f64,
|
||||
|
||||
models: Arc<RwLock<model::Factory>>,
|
||||
|
@ -65,7 +65,9 @@ impl ChunkBuilder {
|
|||
while let Ok((id, mut val)) = self.built_recv.try_recv() {
|
||||
world.reset_building_flag(val.position);
|
||||
|
||||
renderer.update_chunk_solid(val.position, val.key, &val.solid_buffer, val.solid_count);
|
||||
if let Some(render_buffer) = world.get_section_buffer(val.position.0, val.position.1, val.position.2) {
|
||||
renderer.update_chunk_solid(render_buffer, &val.solid_buffer, val.solid_count);
|
||||
}
|
||||
|
||||
val.solid_buffer.clear();
|
||||
self.free_builders.push((id, val.solid_buffer));
|
||||
|
@ -96,7 +98,7 @@ impl ChunkBuilder {
|
|||
self.sections = sections;
|
||||
self.next_collection = 60.0;
|
||||
}
|
||||
while let Some((x, y, z, key)) = self.sections.pop() {
|
||||
while let Some((x, y, z)) = self.sections.pop() {
|
||||
let t_id = self.free_builders.pop().unwrap();
|
||||
world.set_building_flag((x, y, z));
|
||||
let (cx, cy, cz) = (x << 4, y << 4, z << 4);
|
||||
|
@ -105,7 +107,6 @@ impl ChunkBuilder {
|
|||
self.threads[t_id.0].0.send(BuildReq {
|
||||
snapshot: snapshot,
|
||||
position: (x, y, z),
|
||||
key: key,
|
||||
buffer: t_id.1,
|
||||
}).unwrap();
|
||||
if self.free_builders.is_empty() {
|
||||
|
@ -118,7 +119,6 @@ impl ChunkBuilder {
|
|||
struct BuildReq {
|
||||
snapshot: world::Snapshot,
|
||||
position: (i32, i32, i32),
|
||||
key: Arc<world::SectionKey>,
|
||||
buffer: Vec<u8>,
|
||||
}
|
||||
|
||||
|
@ -126,7 +126,6 @@ struct BuildReply {
|
|||
position: (i32, i32, i32),
|
||||
solid_buffer: Vec<u8>,
|
||||
solid_count: usize,
|
||||
key: Arc<world::SectionKey>,
|
||||
}
|
||||
|
||||
fn build_func(id: usize, models: Arc<RwLock<model::Factory>>, work_recv: mpsc::Receiver<BuildReq>, built_send: mpsc::Sender<(usize, BuildReply)>) {
|
||||
|
@ -135,7 +134,6 @@ fn build_func(id: usize, models: Arc<RwLock<model::Factory>>, work_recv: mpsc::R
|
|||
let BuildReq {
|
||||
snapshot,
|
||||
position,
|
||||
key,
|
||||
buffer,
|
||||
} = match work_recv.recv() {
|
||||
Ok(val) => val,
|
||||
|
@ -179,7 +177,6 @@ fn build_func(id: usize, models: Arc<RwLock<model::Factory>>, work_recv: mpsc::R
|
|||
position: position,
|
||||
solid_buffer: solid_buffer,
|
||||
solid_count: solid_count,
|
||||
key: key,
|
||||
})).unwrap();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
|
||||
#![recursion_limit="200"]
|
||||
#![feature(const_fn)]
|
||||
#![feature(arc_counts)]
|
||||
|
||||
extern crate glutin;
|
||||
extern crate image;
|
||||
|
@ -222,7 +221,7 @@ fn main() {
|
|||
.unwrap()
|
||||
.tick(&mut ui_container, &mut game.renderer, delta, width as f64);
|
||||
ui_container.tick(&mut game.renderer, delta, width as f64, height as f64);
|
||||
game.renderer.tick(delta, width, height);
|
||||
game.renderer.tick(&mut game.server.world, delta, width, height);
|
||||
|
||||
let _ = window.swap_buffers();
|
||||
|
||||
|
|
|
@ -60,7 +60,6 @@ pub struct Renderer {
|
|||
chunk_shader_alpha: ChunkShaderAlpha,
|
||||
trans_shader: TransShader,
|
||||
|
||||
chunks: HashMap<(i32, i32, i32), ChunkBuffer, BuildHasherDefault<FNVHash>>,
|
||||
element_buffer: gl::Buffer,
|
||||
element_buffer_size: usize,
|
||||
element_buffer_type: gl::Type,
|
||||
|
@ -72,18 +71,22 @@ pub struct Renderer {
|
|||
|
||||
last_width: u32,
|
||||
last_height: u32,
|
||||
|
||||
chunk_gc_timer: f64,
|
||||
}
|
||||
|
||||
struct ChunkBuffer {
|
||||
key: Arc<world::SectionKey>,
|
||||
position: (i32, i32, i32),
|
||||
|
||||
pub struct ChunkBuffer {
|
||||
solid: Option<ChunkRenderInfo>,
|
||||
trans: Option<ChunkRenderInfo>,
|
||||
}
|
||||
|
||||
impl ChunkBuffer {
|
||||
pub fn new() -> ChunkBuffer {
|
||||
ChunkBuffer {
|
||||
solid: None,
|
||||
trans: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ChunkRenderInfo {
|
||||
array: gl::VertexArray,
|
||||
buffer: gl::Buffer,
|
||||
|
@ -191,7 +194,6 @@ impl Renderer {
|
|||
chunk_shader_alpha: chunk_shader_alpha,
|
||||
trans_shader: trans_shader,
|
||||
|
||||
chunks: HashMap::with_hasher(BuildHasherDefault::default()),
|
||||
element_buffer: gl::Buffer::new(),
|
||||
element_buffer_size: 0,
|
||||
element_buffer_type: gl::UNSIGNED_BYTE,
|
||||
|
@ -207,12 +209,10 @@ impl Renderer {
|
|||
perspective_matrix: cgmath::Matrix4::zero(),
|
||||
|
||||
trans: None,
|
||||
|
||||
chunk_gc_timer: 120.0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tick(&mut self, delta: f64, width: u32, height: u32) {
|
||||
pub fn tick(&mut self, world: &mut world::World, delta: f64, width: u32, height: u32) {
|
||||
use std::f64::consts::PI as PI64;
|
||||
{
|
||||
let rm = self.resources.read().unwrap();
|
||||
|
@ -242,20 +242,6 @@ impl Renderer {
|
|||
self.init_trans(width, height);
|
||||
}
|
||||
|
||||
self.chunk_gc_timer -= delta;
|
||||
if self.chunk_gc_timer <= 0.0 {
|
||||
self.chunk_gc_timer = 120.0;
|
||||
let mut unload_queue = vec![];
|
||||
for (pos, info) in &self.chunks {
|
||||
if Arc::strong_count(&info.key) == 1 {
|
||||
unload_queue.push(*pos);
|
||||
}
|
||||
}
|
||||
for unload in unload_queue {
|
||||
self.chunks.remove(&unload);
|
||||
}
|
||||
}
|
||||
|
||||
let trans = self.trans.as_mut().unwrap();
|
||||
trans.main.bind();
|
||||
|
||||
|
@ -283,8 +269,6 @@ impl Renderer {
|
|||
);
|
||||
let camera_matrix = camera_matrix * cgmath::Matrix4::from_nonuniform_scale(-1.0, 1.0, 1.0);
|
||||
|
||||
// TODO Frustum
|
||||
|
||||
self.chunk_shader.perspective_matrix.set_matrix4(&self.perspective_matrix);
|
||||
self.chunk_shader.camera_matrix.set_matrix4(&camera_matrix);
|
||||
self.chunk_shader.texture.set_int(0);
|
||||
|
@ -293,25 +277,25 @@ impl Renderer {
|
|||
|
||||
let frustum = collision::Frustum::from_matrix4(self.perspective_matrix * camera_matrix).unwrap();
|
||||
|
||||
for (pos, info) in &self.chunks {
|
||||
for (pos, info) in world.get_render_list(&frustum) {
|
||||
if let Some(solid) = info.solid.as_ref() {
|
||||
let min = cgmath::Point3::new(pos.0 as f32 * 16.0, -pos.1 as f32 * 16.0, pos.2 as f32 * 16.0);
|
||||
let bounds = collision::Aabb3::new(min, min + cgmath::Vector3::new(16.0, -16.0, 16.0));
|
||||
if frustum.contains(bounds) != collision::Relation::Out {
|
||||
self.chunk_shader.offset.set_int3(pos.0, pos.1 * 4096, pos.2);
|
||||
solid.array.bind();
|
||||
gl::draw_elements(gl::TRIANGLES, solid.count, self.element_buffer_type, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Line rendering
|
||||
// Model rendering
|
||||
// Cloud rendering
|
||||
|
||||
// Trans chunk rendering
|
||||
|
||||
// TODO: trans chunk shader stuff
|
||||
self.chunk_shader_alpha.program.use_program();
|
||||
self.chunk_shader_alpha.perspective_matrix.set_matrix4(&self.perspective_matrix);
|
||||
self.chunk_shader_alpha.camera_matrix.set_matrix4(&camera_matrix);
|
||||
self.chunk_shader_alpha.texture.set_int(0);
|
||||
self.chunk_shader_alpha.light_level.set_float(LIGHT_LEVEL);
|
||||
self.chunk_shader_alpha.sky_offset.set_float(SKY_OFFSET);
|
||||
|
||||
// Copy the depth buffer
|
||||
trans.main.bind_read();
|
||||
|
@ -357,15 +341,8 @@ impl Renderer {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn update_chunk_solid(&mut self, pos: (i32, i32, i32), key: Arc<world::SectionKey>, data: &[u8], count: usize) {
|
||||
pub fn update_chunk_solid(&mut self, buffer: &mut ChunkBuffer, data: &[u8], count: usize) {
|
||||
self.ensure_element_buffer(count);
|
||||
let buffer = self.chunks.entry(pos).or_insert_with(||ChunkBuffer {
|
||||
key: key.clone(),
|
||||
position: pos,
|
||||
solid: None,
|
||||
trans: None,
|
||||
});
|
||||
buffer.key = key;
|
||||
if count == 0 {
|
||||
if buffer.solid.is_some() {
|
||||
buffer.solid = None;
|
||||
|
|
|
@ -12,8 +12,6 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
use ui;
|
||||
use render;
|
||||
use format::{self, Component, TextComponent};
|
||||
|
|
|
@ -14,13 +14,15 @@
|
|||
|
||||
pub mod block;
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::collections::HashMap;
|
||||
use std::hash::BuildHasherDefault;
|
||||
use types::bit;
|
||||
use types::nibble;
|
||||
use types::hash::FNVHash;
|
||||
use protocol;
|
||||
use render;
|
||||
use collision;
|
||||
use cgmath;
|
||||
|
||||
pub mod biome;
|
||||
|
||||
|
@ -55,13 +57,39 @@ impl World {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_dirty_chunk_sections(&mut self) -> Vec<(i32, i32, i32, Arc<SectionKey>)> {
|
||||
pub fn get_render_list(&self, frustum: &collision::Frustum<f32>) -> Vec<((i32, i32, i32), &render::ChunkBuffer)> {
|
||||
let mut ret = vec![];
|
||||
for (pos, chunk) in &self.chunks {
|
||||
for (y, sec) in chunk.sections.iter().enumerate() {
|
||||
if let Some(sec) = sec.as_ref() {
|
||||
let pos = (pos.0, y as i32, pos.1);
|
||||
let min = cgmath::Point3::new(pos.0 as f32 * 16.0, -pos.1 as f32 * 16.0, pos.2 as f32 * 16.0);
|
||||
let bounds = collision::Aabb3::new(min, min + cgmath::Vector3::new(16.0, -16.0, 16.0));
|
||||
if frustum.contains(bounds) != collision::Relation::Out {
|
||||
ret.push((pos, &sec.render_buffer));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
pub fn get_section_buffer(&mut self, x: i32, y: i32, z: i32) -> Option<&mut render::ChunkBuffer> {
|
||||
if let Some(chunk) = self.chunks.get_mut(&CPos(x, z)) {
|
||||
if let Some(sec) = chunk.sections[y as usize].as_mut() {
|
||||
return Some(&mut sec.render_buffer);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn get_dirty_chunk_sections(&mut self) -> Vec<(i32, i32, i32)> {
|
||||
let mut out = vec![];
|
||||
for (_, chunk) in &mut self.chunks {
|
||||
for sec in &mut chunk.sections {
|
||||
if let Some(sec) = sec.as_mut() {
|
||||
if !sec.building && sec.dirty {
|
||||
out.push((chunk.position.0, sec.y as i32, chunk.position.1, sec.key.clone()));
|
||||
out.push((chunk.position.0, sec.y as i32, chunk.position.1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -391,7 +419,7 @@ pub struct SectionKey {
|
|||
}
|
||||
|
||||
struct Section {
|
||||
key: Arc<SectionKey>,
|
||||
pub render_buffer: render::ChunkBuffer,
|
||||
y: u8,
|
||||
|
||||
blocks: bit::Map,
|
||||
|
@ -408,9 +436,7 @@ struct Section {
|
|||
impl Section {
|
||||
fn new(x: i32, y: u8, z: i32) -> Section {
|
||||
let mut section = Section {
|
||||
key: Arc::new(SectionKey{
|
||||
pos: (x, y, z),
|
||||
}),
|
||||
render_buffer: render::ChunkBuffer::new(),
|
||||
y: y,
|
||||
|
||||
blocks: bit::Map::new(4096, 4),
|
||||
|
|
Loading…
Reference in New Issue