diff --git a/common/Cargo.toml b/common/Cargo.toml index b07fcfde69..0975cf220f 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -9,3 +9,4 @@ specs = "0.14" shred = "0.7" vek = "0.9" dot_vox = "1.0" +threadpool = "1.7" diff --git a/common/src/lib.rs b/common/src/lib.rs index 1aee96ce50..4d33fd7988 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -5,5 +5,6 @@ pub mod comp; pub mod figure; pub mod state; pub mod terrain; +pub mod util; pub mod volumes; pub mod vol; diff --git a/common/src/util/mod.rs b/common/src/util/mod.rs new file mode 100644 index 0000000000..05f0169051 --- /dev/null +++ b/common/src/util/mod.rs @@ -0,0 +1 @@ +pub mod worker_pool; diff --git a/common/src/util/worker_pool.rs b/common/src/util/worker_pool.rs new file mode 100644 index 0000000000..a5be780a44 --- /dev/null +++ b/common/src/util/worker_pool.rs @@ -0,0 +1,10 @@ +// Library +use threadpool::ThreadPool; + +pub struct WorkerPool { + thread_pool: ThreadPool, +} + +impl WorkerPool { + +} diff --git a/voxygen/shaders/figure.frag b/voxygen/shaders/figure.frag index 769bf224a8..bf6889d61c 100644 --- a/voxygen/shaders/figure.frag +++ b/voxygen/shaders/figure.frag @@ -3,6 +3,7 @@ in vec3 f_pos; in vec3 f_norm; in vec3 f_col; +flat in uint f_bone_idx; layout (std140) uniform u_locals { @@ -20,10 +21,23 @@ uniform u_globals { vec4 tick; }; +struct BoneData { + mat4 bone_mat; +}; + +layout (std140) +uniform u_bones { + BoneData bones[16]; +}; + out vec4 tgt_color; void main() { - vec3 world_norm = (model_mat * vec4(f_norm, 0.0)).xyz; + vec3 world_norm = ( + model_mat * + bones[f_bone_idx].bone_mat * + vec4(f_norm, 0.0) + ).xyz; float ambient = 0.5; diff --git a/voxygen/shaders/figure.vert b/voxygen/shaders/figure.vert index 1e8d15524c..7880d7876c 100644 --- a/voxygen/shaders/figure.vert +++ b/voxygen/shaders/figure.vert @@ -33,11 +33,13 @@ uniform u_bones { out vec3 f_pos; out vec3 f_norm; out vec3 f_col; +flat out uint f_bone_idx; void main() { f_pos = v_pos; f_norm = v_norm; f_col = v_col; + f_bone_idx = v_bone_idx; gl_Position = proj_mat * diff --git a/voxygen/shaders/terrain.frag b/voxygen/shaders/terrain.frag new file mode 100644 index 0000000000..1b718c3633 --- /dev/null +++ b/voxygen/shaders/terrain.frag @@ -0,0 +1,33 @@ +#version 330 core + +in vec3 f_pos; +in vec3 f_norm; +in vec3 f_col; + +layout (std140) +uniform u_locals { + vec3 model_offs; +}; + +layout (std140) +uniform u_globals { + mat4 view_mat; + mat4 proj_mat; + vec4 cam_pos; + vec4 focus_pos; + vec4 view_distance; + vec4 time_of_day; + vec4 tick; +}; + +out vec4 tgt_color; + +void main() { + float ambient = 0.5; + + vec3 sun_dir = normalize(vec3(1.3, 1.7, 1.1)); + + float sun_diffuse = dot(sun_dir, f_norm) * 0.5; + + tgt_color = vec4(f_col * (ambient + sun_diffuse), 1.0); +} diff --git a/voxygen/shaders/terrain.vert b/voxygen/shaders/terrain.vert new file mode 100644 index 0000000000..e195a1c464 --- /dev/null +++ b/voxygen/shaders/terrain.vert @@ -0,0 +1,36 @@ +#version 330 core + +in vec3 v_pos; +in vec3 v_norm; +in vec3 v_col; + +layout (std140) +uniform u_locals { + vec3 model_offs; +}; + +layout (std140) +uniform u_globals { + mat4 view_mat; + mat4 proj_mat; + vec4 cam_pos; + vec4 focus_pos; + vec4 view_distance; + vec4 time_of_day; + vec4 tick; +}; + +out vec3 f_pos; +out vec3 f_norm; +out vec3 f_col; + +void main() { + f_pos = v_pos; + f_norm = v_norm; + f_col = v_col; + + gl_Position = + proj_mat * + view_mat * + vec4(v_pos + model_offs, 1); +} diff --git a/voxygen/src/anim/character/run.rs b/voxygen/src/anim/character/run.rs index f1bedf8c07..92411ebc94 100644 --- a/voxygen/src/anim/character/run.rs +++ b/voxygen/src/anim/character/run.rs @@ -17,8 +17,8 @@ impl Animation for RunAnimation { skeleton: &mut Self::Skeleton, time: f64, ) { - let wave = (time as f32 * 8.0).sin(); - let wave_fast = (time as f32 * 4.0).sin(); + let wave = (time as f32 * 12.0).sin(); + let wave_fast = (time as f32 * 6.0).sin(); skeleton.head.offset = Vec3::unit_z() * 13.0; skeleton.head.ori = Quaternion::rotation_z(wave * 0.3); @@ -27,16 +27,18 @@ impl Animation for RunAnimation { skeleton.chest.ori = Quaternion::rotation_z(wave * 0.3); skeleton.belt.offset = Vec3::unit_z() * 7.0; - skeleton.belt.ori = Quaternion::rotation_z(wave * 0.3); + skeleton.belt.ori = Quaternion::rotation_z(wave * 0.2); skeleton.shorts.offset = Vec3::unit_z() * 4.0; - skeleton.shorts.ori = Quaternion::rotation_z(wave * 0.3); + skeleton.shorts.ori = Quaternion::rotation_z(wave * 0.1); - skeleton.l_hand.offset = Vec3::new(-8.0, wave * 5.0, 9.0); - skeleton.r_hand.offset = Vec3::new(8.0, -wave * 5.0, 9.0); + skeleton.l_hand.offset = Vec3::new(-7.5, wave * 5.0, 9.0); + skeleton.r_hand.offset = Vec3::new(7.5, -wave * 5.0, 9.0); - skeleton.l_foot.offset = Vec3::new(-3.5, -wave * 4.0, -(wave_fast.abs() - 0.5).abs() * 4.0); - skeleton.r_foot.offset = Vec3::new(3.5, wave * 4.0, -(wave_fast.abs() - 0.5).abs() * 4.0); + skeleton.l_foot.offset = Vec3::new(-3.5, 2.0 - wave * 8.0, 3.5 - (wave_fast.abs() - 0.5).abs() * 4.0); + skeleton.l_foot.ori = Quaternion::rotation_x(-wave + 1.0); + skeleton.r_foot.offset = Vec3::new(3.5, 2.0 + wave * 8.0, 3.5 - (wave_fast.abs() - 0.5).abs() * 4.0); + skeleton.r_foot.ori = Quaternion::rotation_x(wave + 1.0); skeleton.back.offset = Vec3::new(-8.0, 5.0, 16.0); skeleton.back.ori = Quaternion::rotation_y(2.5); diff --git a/voxygen/src/render/mod.rs b/voxygen/src/render/mod.rs index a61e8ce7fd..7088eb4c19 100644 --- a/voxygen/src/render/mod.rs +++ b/voxygen/src/render/mod.rs @@ -23,6 +23,10 @@ pub use self::{ SkyboxPipeline, Locals as SkyboxLocals, }, + terrain::{ + TerrainPipeline, + Locals as TerrainLocals, + }, }, }; diff --git a/voxygen/src/render/pipelines/mod.rs b/voxygen/src/render/pipelines/mod.rs index cd5f408181..445259b8ce 100644 --- a/voxygen/src/render/pipelines/mod.rs +++ b/voxygen/src/render/pipelines/mod.rs @@ -1,5 +1,6 @@ pub mod figure; pub mod skybox; +pub mod terrain; // Library use gfx::{ diff --git a/voxygen/src/render/pipelines/terrain.rs b/voxygen/src/render/pipelines/terrain.rs new file mode 100644 index 0000000000..dd1e7bcf74 --- /dev/null +++ b/voxygen/src/render/pipelines/terrain.rs @@ -0,0 +1,68 @@ +// Library +use gfx::{ + self, + // Macros + gfx_defines, + gfx_vertex_struct_meta, + gfx_constant_struct_meta, + gfx_impl_struct_meta, + gfx_pipeline, + gfx_pipeline_inner, +}; +use vek::*; + +// Local +use super::{ + Globals, + super::{ + Pipeline, + TgtColorFmt, + TgtDepthFmt, + }, +}; + +gfx_defines! { + vertex Vertex { + pos: [f32; 3] = "v_pos", + norm: [f32; 3] = "v_norm", + col: [f32; 3] = "v_col", + } + + constant Locals { + model_offs: [f32; 3] = "model_offs", + } + + pipeline pipe { + vbuf: gfx::VertexBuffer = (), + + locals: gfx::ConstantBuffer = "u_locals", + globals: gfx::ConstantBuffer = "u_globals", + + tgt_color: gfx::RenderTarget = "tgt_color", + tgt_depth: gfx::DepthTarget = gfx::preset::depth::LESS_EQUAL_WRITE, + } +} + +impl Vertex { + pub fn new(pos: Vec3, norm: Vec3, col: Rgb) -> Self { + Self { + pos: pos.into_array(), + col: col.into_array(), + norm: norm.into_array(), + } + } +} + +impl Locals { + pub fn default() -> Self { + Self { + model_offs: [0.0; 3], + } + } +} + +pub struct TerrainPipeline; + +impl Pipeline for TerrainPipeline { + type Vertex = Vertex; +} diff --git a/voxygen/src/render/renderer.rs b/voxygen/src/render/renderer.rs index 2e23f70f69..dc4e8e053a 100644 --- a/voxygen/src/render/renderer.rs +++ b/voxygen/src/render/renderer.rs @@ -17,6 +17,7 @@ use super::{ Globals, figure, skybox, + terrain, }, }; @@ -43,6 +44,7 @@ pub struct Renderer { skybox_pipeline: GfxPipeline>, figure_pipeline: GfxPipeline>, + terrain_pipeline: GfxPipeline>, } impl Renderer { @@ -70,6 +72,14 @@ impl Renderer { include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/shaders/figure.frag")), )?; + // Construct a pipeline for rendering terrain + let terrain_pipeline = create_pipeline( + &mut factory, + terrain::pipe::new(), + include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/shaders/terrain.vert")), + include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/shaders/terrain.frag")), + )?; + Ok(Self { device, encoder: factory.create_command_buffer().into(), @@ -80,6 +90,7 @@ impl Renderer { skybox_pipeline, figure_pipeline, + terrain_pipeline, }) } @@ -164,6 +175,26 @@ impl Renderer { }, ); } + + /// Queue the rendering of the provided terrain chunk model in the upcoming frame. + pub fn render_terrain_chunk( + &mut self, + model: &Model, + globals: &Consts, + locals: &Consts, + ) { + self.encoder.draw( + &model.slice, + &self.terrain_pipeline.pso, + &terrain::pipe::Data { + vbuf: model.vbuf.clone(), + locals: locals.buf.clone(), + globals: globals.buf.clone(), + tgt_color: self.tgt_color_view.clone(), + tgt_depth: self.tgt_depth_view.clone(), + }, + ); + } } struct GfxPipeline { diff --git a/voxygen/src/scene/mod.rs b/voxygen/src/scene/mod.rs index c3bb5c1585..beb8de6fa5 100644 --- a/voxygen/src/scene/mod.rs +++ b/voxygen/src/scene/mod.rs @@ -82,8 +82,8 @@ impl Scene { Some(load_segment("pants.vox").generate_mesh_with_offset(Vec3::new(-5.0, -3.0, 0.0))), Some(load_segment("hand.vox").generate_mesh_with_offset(Vec3::new(-2.0, -2.0, -1.0))), Some(load_segment("hand.vox").generate_mesh_with_offset(Vec3::new(-2.0, -2.0, -1.0))), - Some(load_segment("foot.vox").generate_mesh_with_offset(Vec3::new(-2.5, -3.0, 0.0))), - Some(load_segment("foot.vox").generate_mesh_with_offset(Vec3::new(-2.5, -3.0, 0.0))), + Some(load_segment("foot.vox").generate_mesh_with_offset(Vec3::new(-2.5, -3.0, -2.0))), + Some(load_segment("foot.vox").generate_mesh_with_offset(Vec3::new(-2.5, -3.0, -2.0))), Some(load_segment("sword.vox").generate_mesh_with_offset(Vec3::new(-6.5, -1.0, 0.0))), None, None, diff --git a/voxygen/test_assets/elf/belt.vox b/voxygen/test_assets/elf/belt.vox new file mode 100644 index 0000000000..61c639ec67 Binary files /dev/null and b/voxygen/test_assets/elf/belt.vox differ diff --git a/voxygen/test_assets/elf/chest.vox b/voxygen/test_assets/elf/chest.vox new file mode 100644 index 0000000000..a0d9980bb0 Binary files /dev/null and b/voxygen/test_assets/elf/chest.vox differ diff --git a/voxygen/test_assets/elf/foot.vox b/voxygen/test_assets/elf/foot.vox new file mode 100644 index 0000000000..4c5d106656 Binary files /dev/null and b/voxygen/test_assets/elf/foot.vox differ diff --git a/voxygen/test_assets/elf/hand.vox b/voxygen/test_assets/elf/hand.vox new file mode 100644 index 0000000000..b4dc12e5c8 Binary files /dev/null and b/voxygen/test_assets/elf/hand.vox differ diff --git a/voxygen/test_assets/elf/head.vox b/voxygen/test_assets/elf/head.vox new file mode 100644 index 0000000000..06fd5e17d2 Binary files /dev/null and b/voxygen/test_assets/elf/head.vox differ diff --git a/voxygen/test_assets/elf/pants.vox b/voxygen/test_assets/elf/pants.vox new file mode 100644 index 0000000000..d407e00911 Binary files /dev/null and b/voxygen/test_assets/elf/pants.vox differ diff --git a/voxygen/test_assets/elf/sword.vox b/voxygen/test_assets/elf/sword.vox new file mode 100644 index 0000000000..87b1fb118b Binary files /dev/null and b/voxygen/test_assets/elf/sword.vox differ