self render
This commit is contained in:
parent
c2c9a2e507
commit
8ff78b65a3
15 changed files with 738 additions and 474 deletions
8
assets/shader/outline.fsh.glsl
Normal file
8
assets/shader/outline.fsh.glsl
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#version 100
|
||||||
|
precision mediump float;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
|
||||||
|
gl_FragColor = vec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
|
||||||
|
}
|
21
assets/shader/outline.vsh.glsl
Normal file
21
assets/shader/outline.vsh.glsl
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
#version 100
|
||||||
|
precision mediump float;
|
||||||
|
|
||||||
|
attribute vec3 pos;
|
||||||
|
uniform vec3 wpos;
|
||||||
|
|
||||||
|
uniform mat4 view;
|
||||||
|
uniform mat4 proj;
|
||||||
|
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
mat4 drawProj = mat4(
|
||||||
|
vec4(-1.0, 0.0, 0.0, 0.0),
|
||||||
|
vec4(0.0, 1.0, 0.0, 0.0),
|
||||||
|
vec4(0.0, 0.0, -1.0, 0.0),
|
||||||
|
vec4(-wpos.x, wpos.y, -wpos.z, 1.0)
|
||||||
|
);
|
||||||
|
gl_Position = proj * view * drawProj * vec4(pos, 1.0);
|
||||||
|
gl_Position.z -= 0.0001;
|
||||||
|
|
||||||
|
}
|
128
src/game.rs
128
src/game.rs
|
@ -1,28 +1,32 @@
|
||||||
use std::vec;
|
use std::{collections::HashMap, vec};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
tools::{WPos, Sides}, graphics::DrawType, systems::{WorldGenerator, BlockType},
|
systems::{BlockType, WorldGenerator, DrawType},
|
||||||
|
tools::{Sides, WPos},
|
||||||
};
|
};
|
||||||
|
|
||||||
use self::{world::World};
|
use self::{world::{GetBlock, World}, block::Block};
|
||||||
|
|
||||||
pub mod block;
|
pub mod block;
|
||||||
pub mod chunk;
|
pub mod chunk;
|
||||||
pub mod world;
|
pub mod world;
|
||||||
|
|
||||||
|
|
||||||
pub struct Game {
|
pub struct Game {
|
||||||
worlds: Vec<World>,
|
pub worlds: HashMap<usize, World>,
|
||||||
types: Vec<Box<dyn BlockType>>,
|
pub types: Vec<Box<dyn BlockType>>,
|
||||||
type_names: Vec<String>,
|
type_names: Vec<String>,
|
||||||
|
w_gens: Vec<WorldGenerator>,
|
||||||
|
w_gens_names: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Game {
|
impl Game {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
let mut g = Game {
|
let mut g = Game {
|
||||||
worlds: vec![],
|
worlds: HashMap::new(),
|
||||||
types: vec![],
|
types: vec![],
|
||||||
type_names: vec![],
|
type_names: vec![],
|
||||||
|
w_gens: vec![],
|
||||||
|
w_gens_names: vec![],
|
||||||
};
|
};
|
||||||
g.add_type(Box::new(Air {
|
g.add_type(Box::new(Air {
|
||||||
id: "air".to_string(),
|
id: "air".to_string(),
|
||||||
|
@ -30,28 +34,30 @@ impl Game {
|
||||||
g
|
g
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add_gen(&mut self, gen: WorldGenerator, name: String) -> usize{
|
||||||
|
self.w_gens.push(gen);
|
||||||
|
self.w_gens_names.push(name.clone());
|
||||||
|
self.w_gens.len()-1
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_type(&self, id: usize) -> Option<&Box<dyn BlockType>> {
|
pub fn get_type(&self, id: usize) -> Option<&Box<dyn BlockType>> {
|
||||||
self.types.get(id)
|
self.types.get(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_type(&self, id: String) -> Option<(usize, &Box<dyn BlockType>)> {
|
pub fn find_type(&self, id: String) -> Option<usize> {
|
||||||
let index = self.type_names.iter().position(|r| r.eq(&id));
|
self.type_names.iter().position(|r| r.eq(&id))
|
||||||
if let Some(i) = index {
|
|
||||||
return Some((i, &self.types[i]));
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn do_tick(&mut self, instant: bool) -> usize {
|
pub fn do_tick(&mut self, instant: bool) -> usize {
|
||||||
let mut num = 0;
|
let mut num = 0;
|
||||||
for w in 0..self.worlds.len() {
|
for (w_id, w) in self.worlds.iter_mut() {
|
||||||
num += self.worlds[w].do_tick(instant, &self.types);
|
num += w.do_tick(instant, &self.types);
|
||||||
}
|
}
|
||||||
num
|
num
|
||||||
}
|
}
|
||||||
pub fn do_tex_tick(&mut self) {
|
pub fn do_tex_tick(&mut self) {
|
||||||
for w in 0..self.worlds.len() {
|
for (w_id, w) in self.worlds.iter_mut() {
|
||||||
self.worlds[w].do_tex_tick(&self.types);
|
w.do_tex_tick(&self.types);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn add_type(&mut self, mut block_type: Box<dyn BlockType>) -> usize {
|
pub fn add_type(&mut self, mut block_type: Box<dyn BlockType>) -> usize {
|
||||||
|
@ -62,15 +68,87 @@ impl Game {
|
||||||
index
|
index
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_world(&mut self) -> usize {
|
pub fn add_world(&mut self, wordl_id: usize) -> usize {
|
||||||
self.worlds.push(World::new());
|
self.worlds.insert(wordl_id, World::new());
|
||||||
self.worlds.len() - 1
|
wordl_id
|
||||||
}
|
}
|
||||||
pub fn get_world(&mut self, id: usize) -> Option<&mut World> {
|
pub fn get_world(&mut self, id: usize) -> Option<&mut World> {
|
||||||
self.worlds.get_mut(id)
|
self.worlds.get_mut(&id)
|
||||||
}
|
}
|
||||||
pub fn get_world_im(&self, id: usize) -> Option<&World> {
|
pub fn get_world_im(&self, id: usize) -> Option<&World> {
|
||||||
self.worlds.get(id)
|
self.worlds.get(&id)
|
||||||
|
}
|
||||||
|
pub fn get_block(&mut self, world: usize, pos: &WPos) -> GetBlock<&mut Block> {
|
||||||
|
if let Some(w) = self.worlds.get_mut(&world) {
|
||||||
|
w.get_block(pos);
|
||||||
|
}
|
||||||
|
return GetBlock::None;
|
||||||
|
}
|
||||||
|
pub fn get_block_im(&self, world: usize, pos: &WPos) -> GetBlock<&Block> {
|
||||||
|
if let Some(w) = self.worlds.get(&world) {
|
||||||
|
w.get_block_im(pos);
|
||||||
|
}
|
||||||
|
return GetBlock::None;
|
||||||
|
}
|
||||||
|
pub fn load_chunk(&mut self, world: usize, chunk_x: i32, chunk_z: i32) -> bool {
|
||||||
|
let mut built = false;
|
||||||
|
if let Some(w) = self.worlds.get_mut(&world){
|
||||||
|
if w.add_chunk(chunk_x, chunk_z){
|
||||||
|
if let Some(gen) = self.w_gens.get_mut(w.gen){
|
||||||
|
gen(self, world, chunk_x, chunk_z);
|
||||||
|
built = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if built{self.worlds.get_mut(&world).unwrap().rebuild_chunk_tex(chunk_x, chunk_z);}
|
||||||
|
built
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load_chunk_around_point(
|
||||||
|
&mut self,
|
||||||
|
world: usize,
|
||||||
|
chunk_x: i32,
|
||||||
|
chunk_z: i32,
|
||||||
|
width: i32,
|
||||||
|
) {
|
||||||
|
if let Some(w) = self.worlds.get_mut(&world){
|
||||||
|
if !w.chunks.contains_key(&(chunk_x, chunk_z)) {
|
||||||
|
self.load_chunk(world, chunk_x, chunk_z);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for dist in 1..=width {
|
||||||
|
for side_w in 0..=dist {
|
||||||
|
if side_w * side_w + dist * dist > width * width {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if self.load_chunk(world, chunk_x + dist, chunk_z + side_w) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if self.load_chunk(world, chunk_x + dist, chunk_z - side_w) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if self.load_chunk(world, chunk_x - dist, chunk_z + side_w) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if self.load_chunk(world, chunk_x - dist, chunk_z - side_w) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if self.load_chunk(world, chunk_x + side_w, chunk_z + dist) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if self.load_chunk(world, chunk_x - side_w, chunk_z + dist) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if self.load_chunk(world, chunk_x + side_w, chunk_z - dist) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if self.load_chunk(world, chunk_x - side_w, chunk_z - dist) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,10 +160,4 @@ impl BlockType for Air {
|
||||||
fn get_id(&self) -> String {
|
fn get_id(&self) -> String {
|
||||||
self.id.to_string()
|
self.id.to_string()
|
||||||
}
|
}
|
||||||
fn is_sided(&self) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
fn texture(&self) -> &DrawType {
|
|
||||||
&DrawType::None()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use crate::{graphics::{Draw, DrawType}, tools::PrimitiveData};
|
use crate::{tools::PrimitiveData};
|
||||||
|
|
||||||
use super::{WPos, world::World};
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Block {
|
pub struct Block {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use gl_matrix::common::Vec3;
|
||||||
|
|
||||||
use crate::tools::Sides;
|
use crate::tools::Sides;
|
||||||
|
|
||||||
|
@ -14,7 +15,9 @@ pub enum Instances {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Chunk {
|
pub struct Chunk {
|
||||||
pub blocks: HashMap<(u8, u8, u8), Block>, //[[[Block; 16]; 256]; 16],
|
pub blocks: HashMap<(u8, u8, u8), Block>, //[[[Block; 16]; 256]; 16],
|
||||||
pub instances: HashMap<usize, Instances>,
|
//pub instances: HashMap<usize, Instances>,
|
||||||
|
pub instances: HashMap<usize, Vec<Vec<Vec3>>>,
|
||||||
|
pub single: HashMap<usize, Vec<Vec3>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Chunk {
|
impl Chunk {
|
||||||
|
@ -23,6 +26,7 @@ impl Chunk {
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
blocks: HashMap::new(),
|
blocks: HashMap::new(),
|
||||||
instances: HashMap::new(),
|
instances: HashMap::new(),
|
||||||
|
single: HashMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,101 +45,78 @@ impl Chunk {
|
||||||
self.blocks.remove(&(inner_x, pos[1] as u8, inner_z));
|
self.blocks.remove(&(inner_x, pos[1] as u8, inner_z));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_pos(&mut self, block_type: usize, pos: &WPos) {
|
pub fn remove_instanced(&mut self, pos: &WPos) {
|
||||||
if let Some(data) = self.instances.get_mut(&block_type) {
|
let mut remove_type: Vec<usize> = vec![];
|
||||||
match data {
|
|
||||||
Instances::Single(d) => {
|
|
||||||
d.retain(|f| pos[0] != f[0] || pos[1] != f[1] || pos[2] != f[2]);
|
|
||||||
if d.len() == 0 {
|
|
||||||
self.instances.remove(&block_type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Instances::Sided(d) => {
|
|
||||||
for i in 0..6 {
|
|
||||||
d[i].retain(|f| pos[0] != f[0] || pos[1] != f[1] || pos[2] != f[2]);
|
|
||||||
}
|
|
||||||
if d[0].len() == 0
|
|
||||||
&& d[1].len() == 0
|
|
||||||
&& d[2].len() == 0
|
|
||||||
&& d[3].len() == 0
|
|
||||||
&& d[4].len() == 0
|
|
||||||
&& d[5].len() == 0
|
|
||||||
{
|
|
||||||
self.instances.remove(&block_type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn remove_all_pos(&mut self, pos: &WPos) {
|
|
||||||
let mut rem_inst: Vec<usize> = vec![];
|
|
||||||
for (block_type, data) in &mut self.instances {
|
for (block_type, data) in &mut self.instances {
|
||||||
match data {
|
let mut not_empty = false;
|
||||||
Instances::Single(d) => {
|
for i in 0..data.len() {
|
||||||
d.retain(|f| pos[0] != f[0] || pos[1] != f[1] || pos[2] != f[2]);
|
data[i].retain(|f| {
|
||||||
if d.len() == 0 {
|
pos[0] as f32 != f[0] || pos[1] as f32 != f[1] || pos[2] as f32 != f[2]
|
||||||
rem_inst.push(*block_type);
|
});
|
||||||
}
|
if data[i].len() > 0 {
|
||||||
}
|
not_empty = true;
|
||||||
Instances::Sided(d) => {
|
|
||||||
for i in 0..6 {
|
|
||||||
d[i].retain(|f| pos[0] != f[0] || pos[1] != f[1] || pos[2] != f[2]);
|
|
||||||
}
|
|
||||||
if d[0].len() == 0
|
|
||||||
&& d[1].len() == 0
|
|
||||||
&& d[2].len() == 0
|
|
||||||
&& d[3].len() == 0
|
|
||||||
&& d[4].len() == 0
|
|
||||||
&& d[5].len() == 0
|
|
||||||
{
|
|
||||||
rem_inst.push(*block_type);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if !not_empty {
|
||||||
|
remove_type.push(*block_type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for b_t in rem_inst.iter() {
|
for block_type in remove_type{
|
||||||
self.instances.remove(&b_t);
|
self.instances.remove(&block_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn remove_single(&mut self, pos: &WPos) {
|
||||||
|
let mut remove_type: Vec<usize> = vec![];
|
||||||
|
for (block_type, data) in &mut self.single {
|
||||||
|
data.retain(|f| {
|
||||||
|
pos[0] as f32 != f[0] || pos[1] as f32 != f[1] || pos[2] as f32 != f[2]
|
||||||
|
});
|
||||||
|
|
||||||
|
if data.len() == 0 {
|
||||||
|
remove_type.push(*block_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for block_type in remove_type{
|
||||||
|
self.single.remove(&block_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_tex_pos(&mut self, block_type: usize, pos: &WPos) {
|
pub fn remove_pos(&mut self, pos: &WPos) {
|
||||||
if let Some(inst) = self.instances.get_mut(&block_type) {
|
self.remove_instanced(pos);
|
||||||
if let Instances::Single(vec) = inst {
|
self.remove_single(pos);
|
||||||
if !vec.contains(&pos) {
|
}
|
||||||
vec.push(pos.clone());
|
|
||||||
}
|
pub fn set_single(&mut self, block_type: usize, pos: &WPos) {
|
||||||
} else {
|
self.remove_instanced(pos);
|
||||||
panic!("Wrong side Type")
|
if !self.single.contains_key(&block_type){
|
||||||
|
self.single.insert(block_type, vec![]);
|
||||||
|
}
|
||||||
|
if let Some(data) = self.single.get_mut(&block_type) {
|
||||||
|
let fpos: Vec3 = [pos[0] as f32, pos[1] as f32, pos[2] as f32];
|
||||||
|
if !data.contains(&fpos) {
|
||||||
|
data.push(fpos.clone());
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
self.instances
|
|
||||||
.insert(block_type, Instances::Single(vec![pos.clone()]));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn add_tex_pos_sided(&mut self, block_type: usize, pos: &WPos, sides: Sides<bool>) {
|
pub fn set_instanced(&mut self, block_type: usize, pos: &WPos, states: Vec<bool>) {
|
||||||
if let Some(inst) = self.instances.get_mut(&block_type) {
|
self.remove_single(pos);
|
||||||
if let Instances::Sided(vec) = inst {
|
if !self.instances.contains_key(&block_type){
|
||||||
for i in 0..6 {
|
self.instances.insert(block_type, vec![]);
|
||||||
if sides[i] {
|
}
|
||||||
if !vec[i].contains(&pos) {
|
if let Some(data) = self.instances.get_mut(&block_type) {
|
||||||
vec[i].push(pos.clone());
|
let fpos: Vec3 = [pos[0] as f32, pos[1] as f32, pos[2] as f32];
|
||||||
}
|
for i in 0..states.len() {
|
||||||
} else {
|
if i >= data.len(){data.push(vec![]);}
|
||||||
vec[i].retain(|f| pos[0] != f[0] || pos[1] != f[1] || pos[2] != f[2]);
|
if states[i] {
|
||||||
|
if !data[i].contains(&fpos) {
|
||||||
|
data[i].push(fpos.clone());
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
} else {
|
data[i].retain(|f| {
|
||||||
panic!("Wrong side Type")
|
pos[0] as f32 != f[0] || pos[1] as f32 != f[1] || pos[2] as f32 != f[2]
|
||||||
}
|
});
|
||||||
} else {
|
|
||||||
let mut new_arr: [Vec<[i32; 3]>; 6] = [vec![], vec![], vec![], vec![], vec![], vec![]];
|
|
||||||
for i in 0..6 {
|
|
||||||
if sides[i] {
|
|
||||||
new_arr[i].push(pos.clone());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.instances.insert(block_type, Instances::Sided(new_arr));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use crate::systems::Draw;
|
||||||
use crate::{graphics::Draw, systems::WorldGenerator};
|
|
||||||
|
|
||||||
use super::{block::Block, chunk::Chunk, BlockType, Sides, WPos};
|
use super::{block::Block, chunk::Chunk, BlockType, Sides, WPos};
|
||||||
|
|
||||||
|
@ -18,7 +17,7 @@ pub struct World {
|
||||||
i_updates: Vec<WPos>,
|
i_updates: Vec<WPos>,
|
||||||
t_updates: Vec<WPos>,
|
t_updates: Vec<WPos>,
|
||||||
|
|
||||||
gen: Box<WorldGenerator>,
|
pub gen: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl World {
|
impl World {
|
||||||
|
@ -28,14 +27,10 @@ impl World {
|
||||||
updates: vec![],
|
updates: vec![],
|
||||||
i_updates: vec![],
|
i_updates: vec![],
|
||||||
t_updates: vec![],
|
t_updates: vec![],
|
||||||
gen: Box::new(|_world: &mut World, _chunk_x: i32, _chunk_z: i32| {}),
|
gen: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_gen(&mut self, gen: Box<WorldGenerator>) {
|
|
||||||
self.gen = gen;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_block(&mut self, pos: &WPos) -> GetBlock<&mut Block> {
|
pub fn get_block(&mut self, pos: &WPos) -> GetBlock<&mut Block> {
|
||||||
if pos[1] < 0 || pos[1] > 256 {
|
if pos[1] < 0 || pos[1] > 256 {
|
||||||
return GetBlock::None;
|
return GetBlock::None;
|
||||||
|
@ -78,55 +73,16 @@ impl World {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_chunk_around_point(
|
pub fn add_chunk(&mut self, chunk_x: i32, chunk_z: i32) -> bool {
|
||||||
&mut self,
|
|
||||||
//gen: &Box<WorldGenerator>,
|
|
||||||
chunk_x: i32,
|
|
||||||
chunk_z: i32,
|
|
||||||
width: i32,
|
|
||||||
) {
|
|
||||||
if !self.chunks.contains_key(&(chunk_x, chunk_z)) {
|
|
||||||
self.load_chunk(chunk_x, chunk_z);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for w in 1..=width {
|
|
||||||
for side_w in 0..=w {
|
|
||||||
if side_w * side_w + w * w > width * width {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if self.load_chunk(chunk_x + w, chunk_z + side_w) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if self.load_chunk(chunk_x + w, chunk_z - side_w) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if self.load_chunk(chunk_x - w, chunk_z + side_w) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if self.load_chunk(chunk_x - w, chunk_z - side_w) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if self.load_chunk(chunk_x + side_w, chunk_z + w) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if self.load_chunk(chunk_x - side_w, chunk_z + w) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if self.load_chunk(chunk_x + side_w, chunk_z - w) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if self.load_chunk(chunk_x - side_w, chunk_z - w) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn load_chunk(&mut self, chunk_x: i32, chunk_z: i32) -> bool {
|
|
||||||
if !self.chunks.contains_key(&(chunk_x, chunk_z)) {
|
if !self.chunks.contains_key(&(chunk_x, chunk_z)) {
|
||||||
self.chunks
|
self.chunks
|
||||||
.insert((chunk_x, chunk_z), Chunk::new(chunk_x, chunk_z));
|
.insert((chunk_x, chunk_z), Chunk::new(chunk_x, chunk_z));
|
||||||
self.gen.as_mut()(self, chunk_x, chunk_z);
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
pub fn rebuild_chunk_tex(&mut self, chunk_x: i32, chunk_z: i32) -> bool{
|
||||||
|
if self.chunks.contains_key(&(chunk_x, chunk_z)) {
|
||||||
for x in chunk_x * 16 - 1..=chunk_x * 16 + 16 {
|
for x in chunk_x * 16 - 1..=chunk_x * 16 + 16 {
|
||||||
for z in chunk_z * 16 - 1..=chunk_z * 16 + 16 {
|
for z in chunk_z * 16 - 1..=chunk_z * 16 + 16 {
|
||||||
for y in 0..256 {
|
for y in 0..256 {
|
||||||
|
@ -135,14 +91,6 @@ impl World {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
/*for x in 0..16 {
|
|
||||||
for y in 0..256 {
|
|
||||||
self.update_texture(&[chunk_x * 16 + x, y, chunk_z * 16 - 1]);
|
|
||||||
self.update_texture(&[chunk_x * 16 + x, y, chunk_z * 16 + 16]);
|
|
||||||
self.update_texture(&[chunk_x * 16 - 1, y, chunk_z * 16 + x]);
|
|
||||||
self.update_texture(&[chunk_x * 16 + 16, y, chunk_z * 16 + x]);
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
@ -210,20 +158,11 @@ impl World {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete_block(
|
pub fn delete_block(&mut self, pos: &WPos, update: Sides<bool>) {
|
||||||
&mut self,
|
|
||||||
pos: &WPos,
|
|
||||||
update: Sides<bool>,
|
|
||||||
) {
|
|
||||||
self.delete_block_tex(pos, update, true);
|
self.delete_block_tex(pos, update, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete_block_tex(
|
pub fn delete_block_tex(&mut self, pos: &WPos, update: Sides<bool>, update_tex_surr: bool) {
|
||||||
&mut self,
|
|
||||||
pos: &WPos,
|
|
||||||
update: Sides<bool>,
|
|
||||||
update_tex_surr: bool,
|
|
||||||
) {
|
|
||||||
if pos[1] < 0 {
|
if pos[1] < 0 {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -325,33 +264,25 @@ impl World {
|
||||||
|
|
||||||
if let Some(chunk) = self.chunks.get_mut(&(chunk_x, chunk_z)) {
|
if let Some(chunk) = self.chunks.get_mut(&(chunk_x, chunk_z)) {
|
||||||
match draw {
|
match draw {
|
||||||
Draw::Sides(s) => {
|
Draw::Instanced(s) => {
|
||||||
if block_type.is_sided() {
|
chunk.set_instanced(block_type_num, &pos, s);
|
||||||
chunk.add_tex_pos_sided(block_type_num, &pos, s);
|
|
||||||
} else {
|
|
||||||
chunk.add_tex_pos(block_type_num, &pos);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Draw::All() => {
|
Draw::Single() => {
|
||||||
if block_type.is_sided() {
|
chunk.set_single(block_type_num, &pos);
|
||||||
chunk.add_tex_pos_sided(block_type_num, &pos, Sides::all(true));
|
|
||||||
} else {
|
|
||||||
chunk.add_tex_pos(block_type_num, &pos);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Draw::None() => {
|
Draw::None() => {
|
||||||
chunk.remove_pos(block_type_num, &pos);
|
chunk.remove_pos(&pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else{
|
} else {
|
||||||
if let Some(chunk) = self.chunks.get_mut(&(chunk_x, chunk_z)) {
|
if let Some(chunk) = self.chunks.get_mut(&(chunk_x, chunk_z)) {
|
||||||
chunk.remove_all_pos(&pos)
|
chunk.remove_pos(&pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else{
|
} else {
|
||||||
if let Some(chunk) = self.chunks.get_mut(&(chunk_x, chunk_z)) {
|
if let Some(chunk) = self.chunks.get_mut(&(chunk_x, chunk_z)) {
|
||||||
chunk.remove_all_pos(&pos)
|
chunk.remove_pos(&pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,29 +2,20 @@ use std::collections::HashMap;
|
||||||
|
|
||||||
use miniquad::*;
|
use miniquad::*;
|
||||||
|
|
||||||
use crate::tools::Sides;
|
use crate::tools::Vertex;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Draw {
|
|
||||||
All(), //single Model
|
|
||||||
None(),
|
|
||||||
Sides(Sides<bool>),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum DrawType {
|
|
||||||
All(Texture), //single Model
|
|
||||||
None(),
|
|
||||||
Sides(Sides<Texture>),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Graphics {
|
pub struct Graphics {
|
||||||
pub textures: HashMap<String, Texture>,
|
pub textures: HashMap<String, Texture>,
|
||||||
pub pipelines: HashMap<String, Pipeline>,
|
pub pipelines: HashMap<String, Pipeline>,
|
||||||
|
pub models: HashMap<String, (Buffer, Buffer)>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Graphics {
|
impl Graphics {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Graphics { textures: HashMap::new(), pipelines: HashMap::new() }
|
Graphics { textures: HashMap::new(), pipelines: HashMap::new(), models: HashMap::new() }
|
||||||
}
|
}
|
||||||
pub fn load_texture(&mut self, ctx: &mut Context, bytes: &[u8], id: String) -> Texture {
|
pub fn load_texture(&mut self, ctx: &mut Context, bytes: &[u8], id: String) -> Texture {
|
||||||
let decoder = png::Decoder::new(bytes);
|
let decoder = png::Decoder::new(bytes);
|
||||||
|
@ -37,7 +28,7 @@ impl Graphics {
|
||||||
bytes,
|
bytes,
|
||||||
TextureParams {
|
TextureParams {
|
||||||
format: TextureFormat::RGBA8,
|
format: TextureFormat::RGBA8,
|
||||||
wrap: TextureWrap::Clamp,
|
wrap: TextureWrap::Repeat,
|
||||||
filter: FilterMode::Nearest,
|
filter: FilterMode::Nearest,
|
||||||
width: info.width,
|
width: info.width,
|
||||||
height: info.height,
|
height: info.height,
|
||||||
|
@ -50,9 +41,14 @@ impl Graphics {
|
||||||
|
|
||||||
text
|
text
|
||||||
}
|
}
|
||||||
pub fn addPipeline(&mut self, pipeline: Pipeline, id:String) {
|
pub fn add_pipeline(&mut self, pipeline: Pipeline, id:String) {
|
||||||
self.pipelines.insert(id, pipeline);
|
self.pipelines.insert(id, pipeline);
|
||||||
}
|
}
|
||||||
|
pub fn add_model(&mut self, ctx: &mut Context, vertices: Vec<Vertex>, indices: Vec<i32>, id:String){
|
||||||
|
let vertex_buffer = Buffer::immutable(ctx, BufferType::VertexBuffer, &vertices);
|
||||||
|
let index_buffer = Buffer::immutable(ctx, BufferType::IndexBuffer, &indices);
|
||||||
|
self.models.insert(id, (vertex_buffer, index_buffer));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
114
src/jucraft.rs
114
src/jucraft.rs
|
@ -1,7 +1,7 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
game::{world::World, *},
|
game::*,
|
||||||
graphics::*,
|
graphics::*,
|
||||||
tools::Sides,
|
tools::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
use default_solid_block::DefaultSolidBlock;
|
use default_solid_block::DefaultSolidBlock;
|
||||||
|
@ -10,7 +10,7 @@ use miniquad::*;
|
||||||
mod default_solid_block;
|
mod default_solid_block;
|
||||||
pub mod default_solid_shader;
|
pub mod default_solid_shader;
|
||||||
|
|
||||||
pub fn register(ctx: &mut Context, game: &mut Game, graphics: &mut Graphics, default_world: usize) {
|
pub fn register(ctx: &mut Context, game: &mut Game, graphics: &mut Graphics) {
|
||||||
graphics.load_texture(
|
graphics.load_texture(
|
||||||
ctx,
|
ctx,
|
||||||
include_bytes!(concat!("../assets/break/empty_overlay.png")),
|
include_bytes!(concat!("../assets/break/empty_overlay.png")),
|
||||||
|
@ -86,40 +86,102 @@ pub fn register(ctx: &mut Context, game: &mut Game, graphics: &mut Graphics, def
|
||||||
include_bytes!(concat!("../assets/blocks/grass_bottom.png")),
|
include_bytes!(concat!("../assets/blocks/grass_bottom.png")),
|
||||||
"grass_bottom".to_string(),
|
"grass_bottom".to_string(),
|
||||||
);
|
);
|
||||||
let stone = game.add_type(Box::new(DefaultSolidBlock {
|
|
||||||
id: "stone".to_string(),
|
#[rustfmt::skip]
|
||||||
texture: DrawType::All(stone_tex),
|
let vertices = vec![
|
||||||
}));
|
Vertex{pos:[0.0, 0.0, 1.0], uv:[0.0, 1.0]},
|
||||||
let dirt = game.add_type(Box::new(DefaultSolidBlock {
|
Vertex{pos:[1.0, 0.0, 1.0], uv:[1.0, 1.0]},
|
||||||
id: "dirt".to_string(),
|
Vertex{pos:[0.0, 1.0, 1.0], uv:[0.0, 0.0]},
|
||||||
texture: DrawType::All(dirt_tex),
|
Vertex{pos:[1.0, 1.0, 1.0], uv:[1.0, 0.0]},
|
||||||
}));
|
|
||||||
let cobblestone = game.add_type(Box::new(DefaultSolidBlock {
|
Vertex{pos:[0.0, 0.0, 0.0], uv:[0.0, 1.0]},
|
||||||
id: "cobblestone".to_string(),
|
Vertex{pos:[0.0, 0.0, 1.0], uv:[1.0, 1.0]},
|
||||||
texture: DrawType::All(cobble_tex),
|
Vertex{pos:[0.0, 1.0, 0.0], uv:[0.0, 0.0]},
|
||||||
}));
|
Vertex{pos:[0.0, 1.0, 1.0], uv:[1.0, 0.0]},
|
||||||
let grassblock = game.add_type(Box::new(DefaultSolidBlock {
|
|
||||||
id: "grassblock".to_string(),
|
Vertex{pos:[1.0, 0.0, 0.0], uv:[0.0, 1.0]},
|
||||||
texture: DrawType::Sides(Sides {
|
Vertex{pos:[0.0, 0.0, 0.0], uv:[1.0, 1.0]},
|
||||||
|
Vertex{pos:[1.0, 1.0, 0.0], uv:[0.0, 0.0]},
|
||||||
|
Vertex{pos:[0.0, 1.0, 0.0], uv:[1.0, 0.0]},
|
||||||
|
|
||||||
|
Vertex{pos:[1.0, 0.0, 1.0], uv:[0.0, 1.0]},
|
||||||
|
Vertex{pos:[1.0, 0.0, 0.0], uv:[1.0, 1.0]},
|
||||||
|
Vertex{pos:[1.0, 1.0, 1.0], uv:[0.0, 0.0]},
|
||||||
|
Vertex{pos:[1.0, 1.0, 0.0], uv:[1.0, 0.0]},
|
||||||
|
|
||||||
|
Vertex{pos:[0.0, 1.0, 0.0], uv:[0.0, 1.0]},
|
||||||
|
Vertex{pos:[0.0, 1.0, 1.0], uv:[1.0, 1.0]},
|
||||||
|
Vertex{pos:[1.0, 1.0, 0.0], uv:[0.0, 0.0]},
|
||||||
|
Vertex{pos:[1.0, 1.0, 1.0], uv:[1.0, 0.0]},
|
||||||
|
|
||||||
|
Vertex{pos:[0.0, 0.0, 0.0], uv:[0.0, 1.0]},
|
||||||
|
Vertex{pos:[1.0, 0.0, 0.0], uv:[1.0, 1.0]},
|
||||||
|
Vertex{pos:[0.0, 0.0, 1.0], uv:[0.0, 0.0]},
|
||||||
|
Vertex{pos:[1.0, 0.0, 1.0], uv:[1.0, 0.0]}
|
||||||
|
];
|
||||||
|
|
||||||
|
let indices = vec![
|
||||||
|
16, 17, 18, // top
|
||||||
|
19, 18, 17,
|
||||||
|
|
||||||
|
20, 21, 22, // bottom
|
||||||
|
23, 22, 21,
|
||||||
|
|
||||||
|
12, 13, 14, // left
|
||||||
|
15, 14, 13,
|
||||||
|
|
||||||
|
4, 5, 6, //right
|
||||||
|
7, 6, 5,
|
||||||
|
|
||||||
|
8, 9, 10, // front
|
||||||
|
11, 10, 9,
|
||||||
|
|
||||||
|
0, 1, 2, // back
|
||||||
|
3, 2, 1,
|
||||||
|
];
|
||||||
|
|
||||||
|
graphics.add_model(ctx, vertices, indices, "block".to_string());
|
||||||
|
|
||||||
|
|
||||||
|
let stone = game.add_type(Box::new(DefaultSolidBlock::new(
|
||||||
|
"stone".to_string(),
|
||||||
|
Sides::all(stone_tex),
|
||||||
|
)));
|
||||||
|
let dirt = game.add_type(Box::new(DefaultSolidBlock::new(
|
||||||
|
"dirt".to_string(),
|
||||||
|
Sides::all(dirt_tex),
|
||||||
|
)));
|
||||||
|
let cobblestone = game.add_type(Box::new(DefaultSolidBlock::new(
|
||||||
|
"cobblestone".to_string(),
|
||||||
|
Sides::all(cobble_tex),
|
||||||
|
)));
|
||||||
|
let grassblock = game.add_type(Box::new(DefaultSolidBlock::new(
|
||||||
|
"grassblock".to_string(),
|
||||||
|
Sides {
|
||||||
top: grass_top,
|
top: grass_top,
|
||||||
bottom: grass_bottom,
|
bottom: grass_bottom,
|
||||||
left: grass_side,
|
left: grass_side,
|
||||||
right: grass_side,
|
right: grass_side,
|
||||||
front: grass_side,
|
front: grass_side,
|
||||||
back: grass_side,
|
back: grass_side,
|
||||||
}),
|
},
|
||||||
}));
|
)));
|
||||||
|
|
||||||
if let Some(world) = game.get_world(default_world) {
|
game.add_gen(
|
||||||
world.set_gen(Box::new(|world: &mut World, chunk_x: i32, chunk_z: i32| {
|
|game: &mut Game, world: usize, chunk_x: i32, chunk_z: i32| {
|
||||||
|
let stone = game.find_type("stone".to_string()).unwrap();
|
||||||
|
let grassblock = game.find_type("grassblock".to_string()).unwrap();
|
||||||
|
let w = game.get_world(world).unwrap();
|
||||||
for x in chunk_x * 16..chunk_x * 16 + 16 {
|
for x in chunk_x * 16..chunk_x * 16 + 16 {
|
||||||
for z in chunk_z * 16..chunk_z * 16 + 16 {
|
for z in chunk_z * 16..chunk_z * 16 + 16 {
|
||||||
for y in 0..63 {
|
for y in 0..63 {
|
||||||
world.set_block_tex(&[x, y, z], 1, Sides::all(false), false, false);
|
w.set_block_tex(&[x, y, z], stone, Sides::all(false), false, false);
|
||||||
}
|
}
|
||||||
world.set_block_tex(&[x, 63, z], 4, Sides::all(false), false, false);
|
w.set_block_tex(&[x, 63, z], grassblock, Sides::all(false), false, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}));
|
},
|
||||||
}
|
"flat".to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,39 @@
|
||||||
|
|
||||||
use gl_matrix::common::*;
|
use gl_matrix::common::*;
|
||||||
|
use miniquad::*;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
game::{block::*, world::*},
|
game::{block::*, chunk::Chunk, world::*},
|
||||||
graphics::*,
|
graphics::Graphics,
|
||||||
tools::*, systems::BlockType,
|
systems::{BlockType, Draw},
|
||||||
|
tools::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Requieres Block Model and break textures
|
||||||
pub struct DefaultSolidBlock {
|
pub struct DefaultSolidBlock {
|
||||||
pub id: String,
|
pub id: String,
|
||||||
pub texture: DrawType,
|
pub texture: Sides<Texture>,
|
||||||
|
bindings: Option<Bindings>,
|
||||||
|
}
|
||||||
|
impl DefaultSolidBlock {
|
||||||
|
pub fn new(id: String, texture: Sides<Texture>) -> Self {
|
||||||
|
Self {
|
||||||
|
id,
|
||||||
|
texture,
|
||||||
|
bindings: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
impl BlockType for DefaultSolidBlock {
|
impl BlockType for DefaultSolidBlock {
|
||||||
fn get_id(&self) -> String {
|
fn get_id(&self) -> String {
|
||||||
self.id.to_string()
|
self.id.to_string()
|
||||||
}
|
}
|
||||||
|
fn init(&mut self, ctx: &mut Context, graphics: &Graphics, instanzeBuf: Buffer) {
|
||||||
|
self.bindings = Some(Bindings {
|
||||||
|
vertex_buffers: vec![graphics.models["block"].0, instanzeBuf],
|
||||||
|
index_buffer: graphics.models["block"].1,
|
||||||
|
images: vec![graphics.textures["d-1"], self.texture.top],
|
||||||
|
});
|
||||||
|
}
|
||||||
fn create(
|
fn create(
|
||||||
&self,
|
&self,
|
||||||
world: &mut World,
|
world: &mut World,
|
||||||
|
@ -28,11 +47,12 @@ impl BlockType for DefaultSolidBlock {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn render(
|
fn render(&self, world: &mut World, block: WPos) -> Draw {
|
||||||
&self,
|
if let GetBlock::Some(b) = world.get_block(&block){
|
||||||
world: &mut World,
|
if b.destroy > 0{
|
||||||
block: WPos,
|
return Draw::Single()
|
||||||
) -> Draw {
|
}
|
||||||
|
}
|
||||||
let mut sides = Sides::all(true);
|
let mut sides = Sides::all(true);
|
||||||
sides.top = match world.get_block(&[block[0], block[1] + 1, block[2]]) {
|
sides.top = match world.get_block(&[block[0], block[1] + 1, block[2]]) {
|
||||||
GetBlock::Some(bt) => !bt.solid,
|
GetBlock::Some(bt) => !bt.solid,
|
||||||
|
@ -67,20 +87,55 @@ impl BlockType for DefaultSolidBlock {
|
||||||
if sides.are_all(false) {
|
if sides.are_all(false) {
|
||||||
Draw::None()
|
Draw::None()
|
||||||
} else {
|
} else {
|
||||||
Draw::Sides(sides)
|
Draw::Instanced(sides.vec())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn texture(&self) -> &DrawType {
|
fn render_instanced(&self, ctx: &mut Context, graphics: &Graphics, positions: &Vec<Vec3>, state: usize) {
|
||||||
&self.texture
|
if let Some(bindings) = &self.bindings {
|
||||||
|
ctx.apply_bindings(&Bindings {
|
||||||
|
vertex_buffers: bindings.vertex_buffers.clone(),
|
||||||
|
index_buffer: bindings.index_buffer,
|
||||||
|
images: vec![ graphics.textures["d-1"], self.texture[state]],
|
||||||
|
});
|
||||||
|
bindings.vertex_buffers[1].update(ctx, &positions);
|
||||||
|
ctx.draw(6 * state as i32, 6, positions.len() as i32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn render_single(&self, ctx: &mut Context, graphics: &Graphics, world: &World, positions: &Vec<Vec3>) {
|
||||||
|
if let Some(bindings) = &self.bindings {
|
||||||
|
for pos in positions {
|
||||||
|
let breaking = if let GetBlock::Some(block) = world.get_block_im(&[pos[0] as i32, pos[1] as i32, pos[2] as i32]){
|
||||||
|
block.destroy
|
||||||
|
}else{
|
||||||
|
0
|
||||||
|
};
|
||||||
|
for state in 0..6{
|
||||||
|
ctx.apply_bindings(&Bindings {
|
||||||
|
vertex_buffers: bindings.vertex_buffers.clone(),
|
||||||
|
index_buffer: bindings.index_buffer,
|
||||||
|
images: vec![match breaking {
|
||||||
|
1 => graphics.textures["d0"],
|
||||||
|
2 => graphics.textures["d1"],
|
||||||
|
3 => graphics.textures["d2"],
|
||||||
|
4 => graphics.textures["d3"],
|
||||||
|
5 => graphics.textures["d4"],
|
||||||
|
6 => graphics.textures["d5"],
|
||||||
|
7 => graphics.textures["d6"],
|
||||||
|
8 => graphics.textures["d7"],
|
||||||
|
_ => graphics.textures["d-1"],
|
||||||
|
}, self.texture[state]],
|
||||||
|
});
|
||||||
|
bindings.vertex_buffers[1].update(ctx, pos);
|
||||||
|
ctx.draw(6 * state as i32, 6, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_sided(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
fn collision(&self, _world: &World, _block: WPos) -> Vec<(Vec3, Vec3)> {
|
fn collision(&self, _world: &World, _block: WPos) -> Vec<(Vec3, Vec3)> {
|
||||||
vec![([0.,0.,0.], [1.,1.,1.])]
|
vec![([0., 0., 0.], [1., 1., 1.])]
|
||||||
}
|
}
|
||||||
fn interaction(&self, _world: &World, _block: &Block, _pos: WPos) -> Vec<(Vec3, Vec3)> {
|
fn interaction(&self, _world: &World, _block: &Block, _pos: WPos) -> Vec<(Vec3, Vec3)> {
|
||||||
vec![([0.,0.,0.], [1.,1.,1.])]
|
vec![([0., 0., 0.], [1., 1., 1.])]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ pub struct Player {
|
||||||
// retundant
|
// retundant
|
||||||
pub speed: f32,
|
pub speed: f32,
|
||||||
pub on_gound: bool,
|
pub on_gound: bool,
|
||||||
|
pub looking_at: Option<(Side, WPos)>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Player {
|
impl Player {
|
||||||
|
@ -38,6 +39,7 @@ impl Player {
|
||||||
|
|
||||||
speed: 0.,
|
speed: 0.,
|
||||||
on_gound: false,
|
on_gound: false,
|
||||||
|
looking_at: None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn update(&mut self, game: &mut Game, s_move: &Sides<bool>, delta: f32) {
|
pub fn update(&mut self, game: &mut Game, s_move: &Sides<bool>, delta: f32) {
|
||||||
|
@ -187,6 +189,15 @@ impl Player {
|
||||||
if self.pos[1] < -50. {
|
if self.pos[1] < -50. {
|
||||||
self.pos[1] = 256. + 128.;
|
self.pos[1] = 256. + 128.;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let start = date::now();
|
||||||
|
|
||||||
|
self.looking_at = self.looking_at(&game, 6., 0.1);
|
||||||
|
|
||||||
|
|
||||||
|
//println!("pos trace time: {}µs", (date::now() - start) * 1000000.);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_clipped(&self, game: &mut Game) -> Option<(Vec3, Vec3)> {
|
pub fn is_clipped(&self, game: &mut Game) -> Option<(Vec3, Vec3)> {
|
||||||
|
@ -237,17 +248,24 @@ impl Player {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn right_click(&self, game: &mut Game) {}
|
pub fn right_click(&self, game: &mut Game) {
|
||||||
pub fn left_click(&self, game: &mut Game) {
|
|
||||||
|
|
||||||
let start = date::now();
|
}
|
||||||
if let Some((_, pos)) = self.looking_at(&game, 6., 0.1) {
|
pub fn left_click(&self, game: &mut Game) {
|
||||||
|
if let Some((_, pos)) = self.looking_at {
|
||||||
if let Some(world) = game.get_world(self.world) {
|
if let Some(world) = game.get_world(self.world) {
|
||||||
world.delete_block(&pos, Sides::all(true));
|
if let GetBlock::Some(block) = world.get_block(&pos) {
|
||||||
|
block.destroy += 1;
|
||||||
|
if block.destroy > 8 {
|
||||||
|
world.delete_block(&pos, Sides::all(true));
|
||||||
|
} else {
|
||||||
|
world.update_texture(&pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("pos trace time: {}µs", (date::now() - start) * 1000000.);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn looking_at(&self, game: &Game, dist: f32, offset: f32) -> Option<(Side, WPos)> {
|
pub fn looking_at(&self, game: &Game, dist: f32, offset: f32) -> Option<(Side, WPos)> {
|
||||||
|
@ -261,37 +279,34 @@ impl Player {
|
||||||
];
|
];
|
||||||
|
|
||||||
let mut curr_dist = offset;
|
let mut curr_dist = offset;
|
||||||
let mut c_x:i32 = i32::max_value();
|
let mut x: i32 = (start[0] + curr_dist * dirc[0]) as i32;
|
||||||
let mut c_y:i32 = i32::max_value();
|
let mut y: i32 = (start[1] + curr_dist * dirc[1]) as i32;
|
||||||
let mut c_z:i32 = i32::max_value();
|
let mut z: i32 = (start[2] + curr_dist * dirc[2]) as i32;
|
||||||
while curr_dist < dist {
|
while curr_dist < dist {
|
||||||
let x = (start[0] + dirc[0] * curr_dist).floor() as i32;
|
if let GetBlock::Some(block) = world.get_block_im(&[x, y, z]) {
|
||||||
let y = (start[1] + dirc[1] * curr_dist).floor() as i32;
|
if let Some(b_t) = game.get_type(block.block_type) {
|
||||||
let z = (start[2] + dirc[2] * curr_dist).floor() as i32;
|
let boxes: Vec<([f32; 3], [f32; 3])> =
|
||||||
if x != c_x || y != c_y || z != c_z {
|
b_t.interaction(&world, block, [x, y, z]);
|
||||||
c_x = x;
|
for (pos, size) in boxes {
|
||||||
c_y = y;
|
if let Some((b_dist, side)) = block_collision(
|
||||||
c_z = z;
|
start,
|
||||||
if let GetBlock::Some(block) = world.get_block_im(&[x, y, z]) {
|
[x as f32 + pos[0], y as f32 + pos[1], z as f32 + pos[2]],
|
||||||
if let Some(b_t) = game.get_type(block.block_type) {
|
dirc,
|
||||||
let boxes: Vec<([f32; 3], [f32; 3])> =
|
size,
|
||||||
b_t.interaction(&world, block, [x, y, z]);
|
) {
|
||||||
for (pos, size) in boxes {
|
if b_dist < dist {
|
||||||
if let Some((b_dist, side)) = block_collision(
|
return Some((side, [x, y, z]));
|
||||||
start,
|
|
||||||
[x as f32 + pos[0], y as f32 + pos[1], z as f32 + pos[2]],
|
|
||||||
dirc,
|
|
||||||
size,
|
|
||||||
) {
|
|
||||||
if b_dist < dist {
|
|
||||||
return Some((side, [x, y, z]));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
curr_dist += 0.05;
|
let cords = next_cord([x, y, z], start, dirc);
|
||||||
|
//println!("{:?}", cords);
|
||||||
|
x = cords.0[0];
|
||||||
|
y = cords.0[1];
|
||||||
|
z = cords.0[2];
|
||||||
|
curr_dist = cords.1.abs();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
use std::f64::consts::PI;
|
use std::f64::consts::PI;
|
||||||
|
|
||||||
use gl_matrix::*;
|
use gl_matrix::{common::*, *};
|
||||||
use miniquad::*;
|
use miniquad::{*, gl::glDrawArrays};
|
||||||
|
|
||||||
|
pub mod outline;
|
||||||
pub mod post;
|
pub mod post;
|
||||||
|
|
||||||
pub struct RenderHelper {
|
pub struct RenderHelper {
|
||||||
post_processing_pipeline: Pipeline,
|
post_processing_pipeline: Pipeline,
|
||||||
post_processing_bind: Bindings,
|
post_processing_bind: Bindings,
|
||||||
|
outline_bind: Bindings,
|
||||||
|
outline_pipline: Pipeline,
|
||||||
offscreen_pass: RenderPass,
|
offscreen_pass: RenderPass,
|
||||||
post_enabled: bool,
|
post_enabled: bool,
|
||||||
}
|
}
|
||||||
|
@ -67,11 +70,65 @@ impl RenderHelper {
|
||||||
post_shader,
|
post_shader,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let shader_outline =
|
||||||
|
Shader::new(ctx, outline::VERTEX, outline::FRAGMENT, outline::meta()).unwrap();
|
||||||
|
|
||||||
|
let outline_vertices: Vec<Vec3> = vec![
|
||||||
|
[-0.001, -0.001, -0.001], //0
|
||||||
|
[-0.001, -0.001, 1.001], //1
|
||||||
|
[-0.001, 1.001, -0.001], //2
|
||||||
|
[-0.001, 1.001, 1.001], //3
|
||||||
|
[1.001, -0.001, -0.001], //4
|
||||||
|
[1.001, -0.001, 1.001], //5
|
||||||
|
[1.001, 1.001, -0.001], //6
|
||||||
|
[1.001, 1.001, 1.001], //7
|
||||||
|
];
|
||||||
|
let outline_vertex_buffer = Buffer::immutable(ctx, BufferType::VertexBuffer, &outline_vertices);
|
||||||
|
|
||||||
|
let outline_indices = vec![
|
||||||
|
0, 1, 0, 2, 0, 4, 1, 3, 1, 5, 2, 3, 2, 6, 3, 7, 4, 5, 4, 6, 5, 7, 6, 7,
|
||||||
|
];
|
||||||
|
|
||||||
|
let outline_index_buffer = Buffer::immutable(ctx, BufferType::IndexBuffer, &outline_indices);
|
||||||
|
|
||||||
|
|
||||||
|
let outline_bind = Bindings{
|
||||||
|
vertex_buffers: vec![outline_vertex_buffer],
|
||||||
|
index_buffer: outline_index_buffer,
|
||||||
|
images: vec![],
|
||||||
|
};
|
||||||
|
|
||||||
|
let outline_pipline = Pipeline::with_params(
|
||||||
|
ctx,
|
||||||
|
&[BufferLayout::default()],
|
||||||
|
&[VertexAttribute::with_buffer("pos", VertexFormat::Float3, 0)],
|
||||||
|
shader_outline,
|
||||||
|
PipelineParams {
|
||||||
|
depth_test: Comparison::LessOrEqual,
|
||||||
|
depth_write: true,
|
||||||
|
primitive_type: PrimitiveType::Lines,
|
||||||
|
color_blend: Some(BlendState::new(
|
||||||
|
Equation::Add,
|
||||||
|
BlendFactor::One,
|
||||||
|
BlendFactor::OneMinusValue(BlendValue::SourceAlpha),
|
||||||
|
)),
|
||||||
|
alpha_blend: Some(BlendState::new(
|
||||||
|
Equation::Add,
|
||||||
|
BlendFactor::One,
|
||||||
|
BlendFactor::Zero,
|
||||||
|
)),
|
||||||
|
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
post_processing_pipeline,
|
post_processing_pipeline,
|
||||||
post_processing_bind,
|
post_processing_bind,
|
||||||
offscreen_pass,
|
offscreen_pass,
|
||||||
post_enabled: false,
|
post_enabled: false,
|
||||||
|
outline_bind,
|
||||||
|
outline_pipline
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,6 +170,13 @@ impl RenderHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn draw_outline(&self, ctx: &mut Context, uniforms:&outline::Uniforms){
|
||||||
|
ctx.apply_pipeline(&self.outline_pipline);
|
||||||
|
ctx.apply_bindings(&self.outline_bind);
|
||||||
|
ctx.apply_uniforms(uniforms);
|
||||||
|
ctx.draw(0,24,1);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn do_post_begin_ui(&self, ctx: &mut Context) {
|
pub fn do_post_begin_ui(&self, ctx: &mut Context) {
|
||||||
ctx.end_render_pass();
|
ctx.end_render_pass();
|
||||||
if self.post_enabled {
|
if self.post_enabled {
|
||||||
|
@ -121,7 +185,7 @@ impl RenderHelper {
|
||||||
ctx.apply_pipeline(&self.post_processing_pipeline);
|
ctx.apply_pipeline(&self.post_processing_pipeline);
|
||||||
ctx.apply_bindings(&self.post_processing_bind);
|
ctx.apply_bindings(&self.post_processing_bind);
|
||||||
|
|
||||||
let invert = ((t).sin()/2.0 + 0.5) as f32;
|
let invert = ((t).sin() / 2.0 + 0.5) as f32;
|
||||||
ctx.apply_uniforms(&post::Uniforms {
|
ctx.apply_uniforms(&post::Uniforms {
|
||||||
wobble: [1., ((t * 6.0) % (2.0 * PI)) as f32],
|
wobble: [1., ((t * 6.0) % (2.0 * PI)) as f32],
|
||||||
invert: [invert, invert, invert],
|
invert: [invert, invert, invert],
|
||||||
|
|
26
src/render_helper/outline.rs
Normal file
26
src/render_helper/outline.rs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
use gl_matrix::common::*;
|
||||||
|
use miniquad::*;
|
||||||
|
|
||||||
|
pub const VERTEX: &str = include_str!(concat!("../../assets/shader/outline.vsh.glsl"));
|
||||||
|
|
||||||
|
pub const FRAGMENT: &str = include_str!(concat!("../../assets/shader/outline.fsh.glsl"));
|
||||||
|
|
||||||
|
pub fn meta() -> ShaderMeta {
|
||||||
|
ShaderMeta {
|
||||||
|
images: vec![],
|
||||||
|
uniforms: UniformBlockLayout {
|
||||||
|
uniforms: vec![
|
||||||
|
UniformDesc::new("view", UniformType::Mat4),
|
||||||
|
UniformDesc::new("proj", UniformType::Mat4),
|
||||||
|
UniformDesc::new("wpos", UniformType::Float3),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct Uniforms {
|
||||||
|
pub view: Mat4,
|
||||||
|
pub proj: Mat4,
|
||||||
|
pub wpos: Vec3,
|
||||||
|
}
|
298
src/stage.rs
298
src/stage.rs
|
@ -1,14 +1,21 @@
|
||||||
|
use gl_matrix::{common::*, mat4};
|
||||||
use gl_matrix::{mat4, common::*};
|
|
||||||
use miniquad::*;
|
use miniquad::*;
|
||||||
|
|
||||||
use crate::{game::{Game, chunk::*, world::World}, graphics::{Graphics, DrawType}, jucraft::{*, self}, render_helper::RenderHelper, tools::*, player::Player};
|
use crate::{
|
||||||
|
game::{chunk::*, world::World, Game},
|
||||||
|
graphics::Graphics,
|
||||||
|
jucraft::{self, *},
|
||||||
|
player::Player,
|
||||||
|
render_helper::{RenderHelper, outline},
|
||||||
|
systems::DrawType,
|
||||||
|
tools::*,
|
||||||
|
};
|
||||||
|
|
||||||
const MAX_INSTANT_TICKS: i32 = 50;
|
const MAX_INSTANT_TICKS: i32 = 50;
|
||||||
|
|
||||||
pub struct Stage {
|
pub struct Stage {
|
||||||
game: Game,
|
pub game: Game,
|
||||||
graphics: Graphics,
|
pub graphics: Graphics,
|
||||||
|
|
||||||
render_helper: RenderHelper,
|
render_helper: RenderHelper,
|
||||||
|
|
||||||
|
@ -17,11 +24,9 @@ pub struct Stage {
|
||||||
last_frame: f64,
|
last_frame: f64,
|
||||||
|
|
||||||
pipeline: Pipeline,
|
pipeline: Pipeline,
|
||||||
bindings: Bindings,
|
|
||||||
|
|
||||||
|
|
||||||
fullscreen: bool,
|
fullscreen: bool,
|
||||||
player: Player,
|
pub player: Player,
|
||||||
mouse_grab: bool,
|
mouse_grab: bool,
|
||||||
s_move: Sides<bool>,
|
s_move: Sides<bool>,
|
||||||
|
|
||||||
|
@ -29,107 +34,54 @@ pub struct Stage {
|
||||||
y: i32,
|
y: i32,
|
||||||
z: i32,
|
z: i32,
|
||||||
|
|
||||||
t_fp:f64,
|
t_fp: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Stage {
|
impl Stage {
|
||||||
pub fn new(ctx: &mut Context) -> Stage {
|
pub fn new(ctx: &mut Context) -> Stage {
|
||||||
let mut game = Game::new();
|
let mut game = Game::new();
|
||||||
let mut graphics = Graphics::new();
|
let mut graphics = Graphics::new();
|
||||||
let world = game.add_world();
|
let world = game.add_world(0);
|
||||||
|
|
||||||
let mut player = Player::new(
|
let mut player = Player::new([0., 0.], [16. * 10., 64., 16. * 10.]);
|
||||||
[0.,0.],
|
|
||||||
[16.*10.,64.,16.*10.],
|
|
||||||
);
|
|
||||||
|
|
||||||
|
jucraft::register(ctx, &mut game, &mut graphics);
|
||||||
|
|
||||||
jucraft::register(ctx,&mut game, &mut graphics, world);
|
|
||||||
|
|
||||||
player.world = world;
|
player.world = world;
|
||||||
|
|
||||||
let post = RenderHelper::new(ctx);
|
let post = RenderHelper::new(ctx);
|
||||||
|
|
||||||
#[rustfmt::skip]
|
|
||||||
let vertices = vec![
|
|
||||||
Vertex{pos:[0.0, 0.0, 1.0], uv:[0.0, 1.0]},
|
|
||||||
Vertex{pos:[1.0, 0.0, 1.0], uv:[1.0, 1.0]},
|
|
||||||
Vertex{pos:[0.0, 1.0, 1.0], uv:[0.0, 0.0]},
|
|
||||||
Vertex{pos:[1.0, 1.0, 1.0], uv:[1.0, 0.0]},
|
|
||||||
|
|
||||||
Vertex{pos:[0.0, 0.0, 0.0], uv:[0.0, 1.0]},
|
|
||||||
Vertex{pos:[0.0, 0.0, 1.0], uv:[1.0, 1.0]},
|
|
||||||
Vertex{pos:[0.0, 1.0, 0.0], uv:[0.0, 0.0]},
|
|
||||||
Vertex{pos:[0.0, 1.0, 1.0], uv:[1.0, 0.0]},
|
|
||||||
|
|
||||||
Vertex{pos:[1.0, 0.0, 0.0], uv:[0.0, 1.0]},
|
|
||||||
Vertex{pos:[0.0, 0.0, 0.0], uv:[1.0, 1.0]},
|
|
||||||
Vertex{pos:[1.0, 1.0, 0.0], uv:[0.0, 0.0]},
|
|
||||||
Vertex{pos:[0.0, 1.0, 0.0], uv:[1.0, 0.0]},
|
|
||||||
|
|
||||||
Vertex{pos:[1.0, 0.0, 1.0], uv:[0.0, 1.0]},
|
|
||||||
Vertex{pos:[1.0, 0.0, 0.0], uv:[1.0, 1.0]},
|
|
||||||
Vertex{pos:[1.0, 1.0, 1.0], uv:[0.0, 0.0]},
|
|
||||||
Vertex{pos:[1.0, 1.0, 0.0], uv:[1.0, 0.0]},
|
|
||||||
|
|
||||||
Vertex{pos:[0.0, 1.0, 0.0], uv:[0.0, 1.0]},
|
|
||||||
Vertex{pos:[0.0, 1.0, 1.0], uv:[1.0, 1.0]},
|
|
||||||
Vertex{pos:[1.0, 1.0, 0.0], uv:[0.0, 0.0]},
|
|
||||||
Vertex{pos:[1.0, 1.0, 1.0], uv:[1.0, 0.0]},
|
|
||||||
|
|
||||||
Vertex{pos:[0.0, 0.0, 0.0], uv:[0.0, 1.0]},
|
|
||||||
Vertex{pos:[1.0, 0.0, 0.0], uv:[1.0, 1.0]},
|
|
||||||
Vertex{pos:[0.0, 0.0, 1.0], uv:[0.0, 0.0]},
|
|
||||||
Vertex{pos:[1.0, 0.0, 1.0], uv:[1.0, 0.0]}
|
|
||||||
];
|
|
||||||
let vertex_buffer = Buffer::immutable(ctx, BufferType::VertexBuffer, &vertices);
|
|
||||||
|
|
||||||
let indices = vec![
|
|
||||||
16, 17, 18, // top
|
|
||||||
19, 18, 17,
|
|
||||||
|
|
||||||
20, 21, 22, // bottom
|
|
||||||
23, 22, 21,
|
|
||||||
|
|
||||||
12, 13, 14, // left
|
|
||||||
15, 14, 13,
|
|
||||||
|
|
||||||
4, 5, 6, //right
|
|
||||||
7, 6, 5,
|
|
||||||
|
|
||||||
8, 9, 10, // front
|
|
||||||
11, 10, 9,
|
|
||||||
|
|
||||||
0, 1, 2, // back
|
|
||||||
3, 2, 1,
|
|
||||||
];
|
|
||||||
let index_buffer = Buffer::immutable(ctx, BufferType::IndexBuffer, &indices);
|
|
||||||
|
|
||||||
let positions_vertex_buffer = Buffer::stream(
|
let positions_vertex_buffer = Buffer::stream(
|
||||||
ctx,
|
ctx,
|
||||||
BufferType::VertexBuffer,
|
BufferType::VertexBuffer,
|
||||||
16*16*256 * std::mem::size_of::<WPos>(),
|
16 * 16 * 256 * std::mem::size_of::<Vec3>(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let bindings = Bindings {
|
for t in game.types.iter_mut() {
|
||||||
vertex_buffers: vec![vertex_buffer, positions_vertex_buffer],
|
t.as_mut().init(ctx, &graphics, positions_vertex_buffer);
|
||||||
index_buffer: index_buffer,
|
}
|
||||||
images: vec![graphics.textures["stone"], graphics.textures["d-1"]],
|
|
||||||
};
|
|
||||||
|
|
||||||
let shader = Shader::new(ctx, default_solid_shader::VERTEX, default_solid_shader::FRAGMENT, default_solid_shader::meta()).unwrap();
|
let shader = Shader::new(
|
||||||
|
ctx,
|
||||||
|
default_solid_shader::VERTEX,
|
||||||
|
default_solid_shader::FRAGMENT,
|
||||||
|
default_solid_shader::meta(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let pipeline = Pipeline::with_params(
|
let pipeline = Pipeline::with_params(
|
||||||
ctx,
|
ctx,
|
||||||
&[BufferLayout::default(), BufferLayout {
|
|
||||||
step_func: VertexStep::PerInstance,
|
|
||||||
..Default::default()
|
|
||||||
}],
|
|
||||||
&[
|
&[
|
||||||
VertexAttribute::with_buffer("pos", VertexFormat::Float3,0),
|
BufferLayout::default(),
|
||||||
VertexAttribute::with_buffer("uv", VertexFormat::Float2,0),
|
BufferLayout {
|
||||||
VertexAttribute::with_buffer("wpos", VertexFormat::Int3, 1),
|
step_func: VertexStep::PerInstance,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
],
|
||||||
|
&[
|
||||||
|
VertexAttribute::with_buffer("pos", VertexFormat::Float3, 0),
|
||||||
|
VertexAttribute::with_buffer("uv", VertexFormat::Float2, 0),
|
||||||
|
VertexAttribute::with_buffer("wpos", VertexFormat::Float3, 1),
|
||||||
],
|
],
|
||||||
shader,
|
shader,
|
||||||
PipelineParams {
|
PipelineParams {
|
||||||
|
@ -137,10 +89,19 @@ impl Stage {
|
||||||
depth_write: true,
|
depth_write: true,
|
||||||
cull_face: CullFace::Back,
|
cull_face: CullFace::Back,
|
||||||
front_face_order: FrontFaceOrder::CounterClockwise,
|
front_face_order: FrontFaceOrder::CounterClockwise,
|
||||||
color_blend: Some(BlendState::new(Equation::Add, BlendFactor::One, BlendFactor::OneMinusValue(BlendValue::SourceAlpha))),
|
color_blend: Some(BlendState::new(
|
||||||
alpha_blend: Some(BlendState::new(Equation::Add, BlendFactor::One, BlendFactor::Zero)),
|
Equation::Add,
|
||||||
|
BlendFactor::One,
|
||||||
|
BlendFactor::OneMinusValue(BlendValue::SourceAlpha),
|
||||||
|
)),
|
||||||
|
alpha_blend: Some(BlendState::new(
|
||||||
|
Equation::Add,
|
||||||
|
BlendFactor::One,
|
||||||
|
BlendFactor::Zero,
|
||||||
|
)),
|
||||||
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
println!("created");
|
println!("created");
|
||||||
|
@ -153,7 +114,6 @@ impl Stage {
|
||||||
last_frame: date::now(),
|
last_frame: date::now(),
|
||||||
render_helper: post,
|
render_helper: post,
|
||||||
pipeline,
|
pipeline,
|
||||||
bindings,
|
|
||||||
|
|
||||||
fullscreen: false,
|
fullscreen: false,
|
||||||
|
|
||||||
|
@ -189,18 +149,22 @@ impl EventHandler for Stage {
|
||||||
self.last_tick += 1. / 20.;
|
self.last_tick += 1. / 20.;
|
||||||
self.game.do_tick(false);
|
self.game.do_tick(false);
|
||||||
|
|
||||||
//eprintln!("fps: {}|{}", 1. / self.delta, self.t_fp);
|
eprintln!("fps: {}|{}", 1. / self.delta, self.t_fp);
|
||||||
if let Some(world) = self.game.get_world(0) {
|
self.game.load_chunk_around_point(
|
||||||
world.load_chunk_around_point( (self.player.pos[0] as i32).div_euclid(16), (self.player.pos[2] as i32).div_euclid(16), 10);
|
self.player.world,
|
||||||
}
|
(self.player.pos[0] as i32).div_euclid(16),
|
||||||
|
(self.player.pos[2] as i32).div_euclid(16),
|
||||||
|
10,
|
||||||
|
);
|
||||||
|
|
||||||
if self.last_tick < t - 5. {
|
if self.last_tick < t - 5. {
|
||||||
self.last_tick = t - 1. / 20.;
|
self.last_tick = t - 1. / 20.;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.game.do_tex_tick();
|
self.game.do_tex_tick();
|
||||||
|
|
||||||
self.player.update(&mut self.game, &self.s_move, self.delta as f32);
|
self.player
|
||||||
|
.update(&mut self.game, &self.s_move, self.delta as f32);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw(&mut self, ctx: &mut Context) {
|
fn draw(&mut self, ctx: &mut Context) {
|
||||||
|
@ -209,11 +173,16 @@ impl EventHandler for Stage {
|
||||||
let t = date::now();
|
let t = date::now();
|
||||||
|
|
||||||
ctx.apply_pipeline(&self.pipeline);
|
ctx.apply_pipeline(&self.pipeline);
|
||||||
ctx.apply_bindings(&self.bindings);
|
|
||||||
|
|
||||||
let (w,h) = ctx.screen_size();
|
let (w, h) = ctx.screen_size();
|
||||||
let mut proj_matrix = mat4::create();
|
let mut proj_matrix = mat4::create();
|
||||||
mat4::perspective(&mut proj_matrix, 90.0f32.to_radians(), w as f32 / h as f32, 0.1, Some(10000.0));
|
mat4::perspective(
|
||||||
|
&mut proj_matrix,
|
||||||
|
90.0f32.to_radians(),
|
||||||
|
w as f32 / h as f32,
|
||||||
|
0.1,
|
||||||
|
Some(10000.0),
|
||||||
|
);
|
||||||
|
|
||||||
let mut cammat = mat4::create();
|
let mut cammat = mat4::create();
|
||||||
let mut cammat1 = mat4::create();
|
let mut cammat1 = mat4::create();
|
||||||
|
@ -221,59 +190,67 @@ impl EventHandler for Stage {
|
||||||
mat4::identity(&mut cammat);
|
mat4::identity(&mut cammat);
|
||||||
mat4::rotate_x(&mut cammat1, &cammat, -(self.player.rot[0] / 180. * PI));
|
mat4::rotate_x(&mut cammat1, &cammat, -(self.player.rot[0] / 180. * PI));
|
||||||
mat4::rotate_y(&mut cammat, &cammat1, self.player.rot[1] / 180. * PI);
|
mat4::rotate_y(&mut cammat, &cammat1, self.player.rot[1] / 180. * PI);
|
||||||
mat4::translate(&mut cammat1, &cammat, &[self.player.pos[0], -self.player.pos[1]- self.player.eyes, self.player.pos[2]]);
|
mat4::translate(
|
||||||
|
&mut cammat1,
|
||||||
|
&cammat,
|
||||||
|
&[
|
||||||
|
self.player.pos[0],
|
||||||
|
-self.player.pos[1] - self.player.eyes,
|
||||||
|
self.player.pos[2],
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
let mut view_matrix = mat4::create();
|
let mut view_matrix = mat4::create();
|
||||||
mat4::look_at(&mut view_matrix, &[0., 0., 0.], &[0., 0., 0.], &[0., 0., 0.]);
|
mat4::look_at(
|
||||||
|
&mut view_matrix,
|
||||||
|
&[0., 0., 0.],
|
||||||
|
&[0., 0., 0.],
|
||||||
|
&[0., 0., 0.],
|
||||||
|
);
|
||||||
mat4::multiply(&mut cammat, &cammat1, &view_matrix);
|
mat4::multiply(&mut cammat, &cammat1, &view_matrix);
|
||||||
|
|
||||||
ctx.apply_uniforms(&default_solid_shader::Uniforms {
|
ctx.apply_uniforms(&default_solid_shader::Uniforms {
|
||||||
proj: proj_matrix,
|
proj: proj_matrix,
|
||||||
view: cammat,
|
view: cammat,
|
||||||
fog: [140.0, 160.0]
|
fog: [140.0, 160.0],
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some(world) = self.game.get_world_im(self.player.world){
|
if let Some(world) = self.game.get_world_im(self.player.world) {
|
||||||
for (_,chunk) in &world.chunks {
|
for (_, chunk) in &world.chunks {
|
||||||
for (b_type, inst) in &chunk.instances{
|
for (b_type, inst) in &chunk.instances {
|
||||||
if let Some(b_t) = self.game.get_type(*b_type){
|
if let Some(b_t) = self.game.get_type(*b_type) {
|
||||||
let tex = b_t.texture();
|
for (state, positions) in inst.iter().enumerate() {
|
||||||
if let DrawType::All(ttt) = tex {
|
if positions.len() > 0 {
|
||||||
self.bindings.images[0] = *ttt;
|
b_t.render_instanced(ctx, &self.graphics, positions, state);
|
||||||
ctx.apply_bindings(&self.bindings);
|
}
|
||||||
}
|
}
|
||||||
match inst {
|
}
|
||||||
Instances::Single(c) => {
|
}
|
||||||
if c.len() > 0{
|
for (b_type, inst) in &chunk.single {
|
||||||
self.bindings.vertex_buffers[1].update(ctx, &c);
|
if let Some(b_t) = self.game.get_type(*b_type) {
|
||||||
ctx.draw(0, 36, c.len() as i32);
|
if inst.len() > 0 {
|
||||||
}
|
b_t.render_single(ctx, &self.graphics, world, inst);
|
||||||
},
|
|
||||||
Instances::Sided(s) => {
|
|
||||||
for i in 0..6 {
|
|
||||||
let len = s[i].len() as i32;
|
|
||||||
if len > 0{
|
|
||||||
if let DrawType::Sides(ttt) = tex {
|
|
||||||
self.bindings.images[0] = ttt[i];
|
|
||||||
ctx.apply_bindings(&self.bindings);
|
|
||||||
}
|
|
||||||
self.bindings.vertex_buffers[1].update(ctx, &s[i]);
|
|
||||||
ctx.draw(6 * i as i32, 6, len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(looking_at) = &self.player.looking_at{
|
||||||
|
self.render_helper.draw_outline(ctx, &outline::Uniforms{
|
||||||
|
view: cammat,
|
||||||
|
proj: proj_matrix,
|
||||||
|
wpos: [looking_at.1[0] as f32, looking_at.1[1] as f32, looking_at.1[2] as f32],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
self.render_helper.do_post_begin_ui(ctx);
|
self.render_helper.do_post_begin_ui(ctx);
|
||||||
|
|
||||||
let end = date::now();
|
let end = date::now();
|
||||||
|
|
||||||
self.t_fp = self.t_fp *0.9 + 0.1/(end-t);
|
self.t_fp = self.t_fp * 0.9 + 0.1 / (end - t);
|
||||||
|
|
||||||
// TODO: render 2D UI
|
// TODO: render 2D UI
|
||||||
|
|
||||||
|
@ -284,30 +261,35 @@ impl EventHandler for Stage {
|
||||||
self.render_helper.resize(ctx, width, height);
|
self.render_helper.resize(ctx, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn key_down_event(&mut self, _ctx: &mut Context, keycode: KeyCode, _keymods: KeyMods,_repeatt: bool) {
|
fn key_down_event(
|
||||||
if keycode == KeyCode::Space{
|
&mut self,
|
||||||
|
_ctx: &mut Context,
|
||||||
|
keycode: KeyCode,
|
||||||
|
_keymods: KeyMods,
|
||||||
|
_repeatt: bool,
|
||||||
|
) {
|
||||||
|
if keycode == KeyCode::Space {
|
||||||
self.s_move.top = true;
|
self.s_move.top = true;
|
||||||
}else if keycode == KeyCode::LeftShift{
|
} else if keycode == KeyCode::LeftShift {
|
||||||
self.s_move.bottom = true;
|
self.s_move.bottom = true;
|
||||||
}else if keycode == KeyCode::W{
|
} else if keycode == KeyCode::W {
|
||||||
self.s_move.front = true;
|
self.s_move.front = true;
|
||||||
}else if keycode == KeyCode::A{
|
} else if keycode == KeyCode::A {
|
||||||
self.s_move.left = true;
|
self.s_move.left = true;
|
||||||
}else if keycode == KeyCode::S{
|
} else if keycode == KeyCode::S {
|
||||||
self.s_move.back = true;
|
self.s_move.back = true;
|
||||||
}else if keycode == KeyCode::D{
|
} else if keycode == KeyCode::D {
|
||||||
self.s_move.right = true;
|
self.s_move.right = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn key_up_event(&mut self, ctx: &mut Context, keycode: KeyCode, _keymods: KeyMods) {
|
fn key_up_event(&mut self, ctx: &mut Context, keycode: KeyCode, _keymods: KeyMods) {
|
||||||
|
|
||||||
if keycode == KeyCode::F11 {
|
if keycode == KeyCode::F11 {
|
||||||
if self.fullscreen {
|
if self.fullscreen {
|
||||||
ctx.set_fullscreen(false);
|
ctx.set_fullscreen(false);
|
||||||
ctx.set_window_size(900* 16 / 9, 900);
|
ctx.set_window_size(900 * 16 / 9, 900);
|
||||||
self.fullscreen = false;
|
self.fullscreen = false;
|
||||||
}else {
|
} else {
|
||||||
ctx.set_fullscreen(true);
|
ctx.set_fullscreen(true);
|
||||||
self.fullscreen = true;
|
self.fullscreen = true;
|
||||||
}
|
}
|
||||||
|
@ -317,27 +299,25 @@ impl EventHandler for Stage {
|
||||||
ctx.show_mouse(true);
|
ctx.show_mouse(true);
|
||||||
self.mouse_grab = false;
|
self.mouse_grab = false;
|
||||||
}
|
}
|
||||||
}else if keycode == KeyCode::Escape {
|
} else if keycode == KeyCode::Escape {
|
||||||
ctx.set_cursor_grab(false);
|
ctx.set_cursor_grab(false);
|
||||||
ctx.show_mouse(true);
|
ctx.show_mouse(true);
|
||||||
self.mouse_grab = false;
|
self.mouse_grab = false;
|
||||||
|
} else if keycode == KeyCode::Space {
|
||||||
}else if keycode == KeyCode::Space{
|
|
||||||
self.s_move.top = false;
|
self.s_move.top = false;
|
||||||
}else if keycode == KeyCode::LeftShift{
|
} else if keycode == KeyCode::LeftShift {
|
||||||
self.s_move.bottom = false;
|
self.s_move.bottom = false;
|
||||||
}else if keycode == KeyCode::W{
|
} else if keycode == KeyCode::W {
|
||||||
self.s_move.front = false;
|
self.s_move.front = false;
|
||||||
}else if keycode == KeyCode::A{
|
} else if keycode == KeyCode::A {
|
||||||
self.s_move.left = false;
|
self.s_move.left = false;
|
||||||
}else if keycode == KeyCode::S{
|
} else if keycode == KeyCode::S {
|
||||||
self.s_move.back = false;
|
self.s_move.back = false;
|
||||||
}else if keycode == KeyCode::D{
|
} else if keycode == KeyCode::D {
|
||||||
self.s_move.right = false;
|
self.s_move.right = false;
|
||||||
}else if keycode == KeyCode::F{
|
} else if keycode == KeyCode::F {
|
||||||
self.player.flying = !self.player.flying;
|
self.player.flying = !self.player.flying;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn window_minimized_event(&mut self, ctx: &mut Context) {
|
fn window_minimized_event(&mut self, ctx: &mut Context) {
|
||||||
|
@ -346,7 +326,13 @@ impl EventHandler for Stage {
|
||||||
self.mouse_grab = false;
|
self.mouse_grab = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mouse_button_down_event(&mut self,ctx: &mut Context, button: MouseButton,_x: f32,_y: f32) {
|
fn mouse_button_down_event(
|
||||||
|
&mut self,
|
||||||
|
ctx: &mut Context,
|
||||||
|
button: MouseButton,
|
||||||
|
_x: f32,
|
||||||
|
_y: f32,
|
||||||
|
) {
|
||||||
if button == MouseButton::Left {
|
if button == MouseButton::Left {
|
||||||
if !self.mouse_grab {
|
if !self.mouse_grab {
|
||||||
ctx.set_cursor_grab(true);
|
ctx.set_cursor_grab(true);
|
||||||
|
@ -364,7 +350,5 @@ impl EventHandler for Stage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn touch_event(&mut self, ctx: &mut Context, phase: TouchPhase, _id: u64, x: f32, y: f32) {
|
fn touch_event(&mut self, ctx: &mut Context, phase: TouchPhase, _id: u64, x: f32, y: f32) {}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +1,41 @@
|
||||||
use gl_matrix::common::*;
|
use gl_matrix::common::*;
|
||||||
|
use miniquad::*;
|
||||||
|
|
||||||
use crate::{game::{world::World, block::Block, Game}, tools::WPos, graphics::{Draw, DrawType}};
|
use crate::{game::{world::World, block::Block, Game, chunk::Chunk}, tools::{WPos, Sides}, graphics::Graphics};
|
||||||
|
|
||||||
|
|
||||||
|
pub type WorldGenerator = fn(game: &mut Game, world: usize, chunk_x: i32, chunk_z:i32);
|
||||||
|
|
||||||
/*pub trait WorldGenerator {
|
#[derive(Debug)]
|
||||||
fn get_id(&self) -> String;
|
pub enum Draw {
|
||||||
fn generate_chunk(&self, world: &mut World, chunk_x: i32, chunk_z:i32);
|
None(),
|
||||||
}*/
|
Instanced(Vec<bool>),
|
||||||
|
Single()
|
||||||
|
}
|
||||||
|
|
||||||
pub type WorldGenerator = fn(world: &mut World, chunk_x: i32, chunk_z:i32);
|
pub enum DrawType {
|
||||||
|
All(Texture), //single Model
|
||||||
|
None(),
|
||||||
|
Sides(Sides<Texture>),
|
||||||
|
}
|
||||||
|
|
||||||
pub trait BlockType {
|
pub trait BlockType {
|
||||||
fn get_id(&self) -> String;
|
fn get_id(&self) -> String;
|
||||||
fn is_sided(&self) -> bool;
|
//fn is_sided(&self) -> bool;
|
||||||
|
|
||||||
|
fn set_index(&mut self, id: usize){}
|
||||||
|
|
||||||
|
fn init(&mut self, ctx: &mut Context, graphics: &Graphics, instanzeBuf: Buffer) {}
|
||||||
|
|
||||||
fn set_index(&mut self, _id: usize) {}
|
|
||||||
fn create(&self, _world: &mut World, _block: WPos, _types: &Vec<Box<dyn BlockType>>, _instant: bool) {}
|
fn create(&self, _world: &mut World, _block: WPos, _types: &Vec<Box<dyn BlockType>>, _instant: bool) {}
|
||||||
fn update(&self, _world: &mut World, _block: WPos, _types: &Vec<Box<dyn BlockType>>, _instant: bool) {}
|
fn update(&self, _world: &mut World, _block: WPos, _types: &Vec<Box<dyn BlockType>>, _instant: bool) {}
|
||||||
fn render(&self, _world: &mut World, _block: WPos) -> Draw { Draw::None() }
|
|
||||||
|
fn render(&self, _world: &mut World, _block: WPos) -> Draw { Draw::None() }
|
||||||
|
fn render_instanced(&self, ctx: &mut Context, graphics: &Graphics, positions: &Vec<Vec3>, state: usize) {}
|
||||||
|
fn render_single(&self, ctx: &mut Context, graphics: &Graphics, world: &World, positions: &Vec<Vec3>) {}
|
||||||
|
//fn texture(&self) -> &DrawType;
|
||||||
|
|
||||||
fn collision(&self, _world: &World, _block: WPos) -> Vec<(Vec3, Vec3)> { vec![] }
|
fn collision(&self, _world: &World, _block: WPos) -> Vec<(Vec3, Vec3)> { vec![] }
|
||||||
fn interaction(&self, _world: &World, _block: &Block, _pos: WPos) -> Vec<(Vec3, Vec3)> { vec![] }
|
fn interaction(&self, _world: &World, _block: &Block, _pos: WPos) -> Vec<(Vec3, Vec3)> { vec![] }
|
||||||
fn texture(&self) -> &DrawType;
|
|
||||||
}
|
}
|
39
src/tools.rs
39
src/tools.rs
|
@ -42,6 +42,16 @@ impl<T: Copy + PartialEq> Sides<T> {
|
||||||
&& self.front == v
|
&& self.front == v
|
||||||
&& self.back == v
|
&& self.back == v
|
||||||
}
|
}
|
||||||
|
pub fn vec(&self) -> Vec<T> {
|
||||||
|
vec![
|
||||||
|
self.top,
|
||||||
|
self.bottom,
|
||||||
|
self.left,
|
||||||
|
self.right,
|
||||||
|
self.front,
|
||||||
|
self.back,
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Copy + PartialEq> Index<usize> for Sides<T> {
|
impl<T: Copy + PartialEq> Index<usize> for Sides<T> {
|
||||||
|
@ -110,12 +120,12 @@ pub fn block_collision(
|
||||||
let x = pos1[0] + d_z * direction[0];
|
let x = pos1[0] + d_z * direction[0];
|
||||||
let y = pos1[1] + d_z * direction[1];
|
let y = pos1[1] + d_z * direction[1];
|
||||||
if x > pos2[0] && x < pos2[0] + size2[0] && y > pos2[1] && y < pos2[1] + size2[1] {
|
if x > pos2[0] && x < pos2[0] + size2[0] && y > pos2[1] && y < pos2[1] + size2[1] {
|
||||||
out = Some((d_z, Side::Back));
|
out = Some((d_z, Side::Back));
|
||||||
dist = d_z;
|
dist = d_z;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if d_b_x > 0. && dist > d_b_x{
|
if d_b_x > 0. && dist > d_b_x {
|
||||||
let y = pos1[1] + d_x * direction[1];
|
let y = pos1[1] + d_x * direction[1];
|
||||||
let z = pos1[2] + d_x * direction[2];
|
let z = pos1[2] + d_x * direction[2];
|
||||||
if y > pos2[1] && y < pos2[1] + size2[1] && z > pos2[2] && z < pos2[2] + size2[2] {
|
if y > pos2[1] && y < pos2[1] + size2[1] && z > pos2[2] && z < pos2[2] + size2[2] {
|
||||||
|
@ -141,6 +151,31 @@ pub fn block_collision(
|
||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn to_unit(n: f32) -> i32 {
|
||||||
|
if n >= 0. {
|
||||||
|
1
|
||||||
|
} else {
|
||||||
|
-1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn next_cord(n_pos: WPos, pos: Vec3, direction: Vec3) -> (WPos, f32) {
|
||||||
|
let x_dir = to_unit(direction[0]);
|
||||||
|
let y_dir = to_unit(direction[1]);
|
||||||
|
let z_dir = to_unit(direction[2]);
|
||||||
|
let d_x = (n_pos[0] as f32 + x_dir as f32 - pos[0]) / direction[0];
|
||||||
|
let d_y = (n_pos[1] as f32 + y_dir as f32 - pos[1]) / direction[1];
|
||||||
|
let d_z = (n_pos[2] as f32 + z_dir as f32 - pos[2]) / direction[2];
|
||||||
|
|
||||||
|
if d_x < d_y && d_x < d_z {
|
||||||
|
return ([n_pos[0] + x_dir, n_pos[1], n_pos[2]], d_x);
|
||||||
|
}
|
||||||
|
if d_y < d_x && d_y < d_z {
|
||||||
|
return ([n_pos[0], n_pos[1] + y_dir, n_pos[2]], d_y);
|
||||||
|
}
|
||||||
|
return ([n_pos[0], n_pos[1], n_pos[2] + z_dir], d_z);
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum PrimitiveData {
|
pub enum PrimitiveData {
|
||||||
String(String),
|
String(String),
|
||||||
|
|
Loading…
Reference in a new issue