Skip to content
This repository has been archived by the owner on Jun 19, 2021. It is now read-only.

One vertex buffer to rule them all #190

Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 18 additions & 15 deletions base/src/math/axial_point.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,34 +31,37 @@ impl AxialPoint {
/// system using `world::{HEX_INNER_RADIUS, HEX_OUTER_RADIUS}`.
pub fn to_real(&self) -> Point2f {
Point2f {
x: ((2 * self.q + self.r) as DefaultFloat) * HEX_INNER_RADIUS,
x: ((2 * self.q - self.r) as DefaultFloat) * HEX_INNER_RADIUS,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wow, not even this was correct?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well... there are many "correct" versions. In the version of the axial coordinate system that I chose this was wrong, yes.

y: (self.r as DefaultFloat) * (3.0 / 2.0) * HEX_OUTER_RADIUS,
}
}

/// Return the `AxialPoint` from a `Point2f`
pub fn from_real(real: Point2f) -> Self {
let q: f32 = (real.x * ::math::SQRT_3 / 3.0 - real.y / 3.0) / HEX_OUTER_RADIUS;
let r: f32 = (real.y * 2.0 / 3.0) / HEX_OUTER_RADIUS;
let q = (real.x * ::math::SQRT_3 / 3.0 - real.y / 3.0) / HEX_OUTER_RADIUS;
let r = (real.y * 2.0 / 3.0) / HEX_OUTER_RADIUS;

let y: f32 = -q - r;
let s = -q - r;

// Rounding
let mut rx: i32 = q.round() as i32;
let ry: i32 = y.round() as i32;
let mut rz: i32 = r.round() as i32;
let rq = q.round();
let mut rr = r.round();
let mut rs = s.round();

// To test the right rounding
let x_diff = (rx as f32 - q).abs();
let y_diff = (ry as f32 - y).abs();
let z_diff = (rz as f32 - r).abs();
if x_diff > y_diff && x_diff > z_diff {
rx = -ry - rz;
} else if y_diff <= z_diff {
rz = -rx - ry;
let q_diff = (rq - q).abs();
let r_diff = (rr - r).abs();
let s_diff = (rs - s).abs();

if q_diff > r_diff && q_diff > s_diff {
// rq = -rr - rs;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this stay or should this go?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I actually want this to stay, since it then represents the algorithm from redblobgames.com more closely. But I can add a comment. Will do it tomorrow when fixing the other stuff.

} else if s_diff > r_diff {
rr = -rq - rs;
} else {
rs = -rq - rr;
}

AxialPoint { q: rx, r: rz }
AxialPoint { q: -rs as AxialType, r: rr as AxialType}
}

/// Returns the `s` component of corresponding cube coordinates. In cube
Expand Down
2 changes: 1 addition & 1 deletion base/src/math/axial_vector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ impl AxialVector {
/// system using `world::{HEX_INNER_RADIUS, HEX_OUTER_RADIUS}`.
pub fn to_real(&self) -> Vector2f {
Vector2f {
x: ((2 * self.q + self.r) as DefaultFloat) * HEX_INNER_RADIUS,
x: ((2 * self.q - self.r) as DefaultFloat) * HEX_INNER_RADIUS,
y: (self.r as DefaultFloat) * (3.0 / 2.0) * HEX_OUTER_RADIUS,
}
}
Expand Down
10 changes: 5 additions & 5 deletions base/src/world/chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ impl<'a> Iterator for ChunkPillars<'a> {

fn next(&mut self) -> Option<Self::Item> {
if self.i < CHUNK_SIZE * CHUNK_SIZE {
let axial = AxialVector::new((self.i / CHUNK_SIZE).into(),
(self.i % CHUNK_SIZE).into());
let axial = AxialVector::new((self.i % CHUNK_SIZE).into(),
(self.i / CHUNK_SIZE).into());
let item = (axial, &self.pillars[self.i as usize]);
self.i += 1;
Some(item)
Expand Down Expand Up @@ -97,9 +97,9 @@ impl Chunk {
let start_q = CHUNK_SIZE as i32 * chunk_index.0.q;
let start_r = CHUNK_SIZE as i32 * chunk_index.0.r;

for q in start_q..start_q + CHUNK_SIZE as i32 {
for r in start_r..start_r + CHUNK_SIZE as i32 {
let pos = AxialPoint::new(q.into(), r.into());
for r in start_r..start_r + CHUNK_SIZE as i32 {
for q in start_q..start_q + CHUNK_SIZE as i32 {
let pos = AxialPoint::new(q, r);
hec.push(func(pos));
}
}
Expand Down
15 changes: 14 additions & 1 deletion base/src/world/ground.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#[derive(Clone, Debug)]
#[derive(Clone, Copy, Debug)]
pub enum GroundMaterial {
Dirt,
Grass,
Expand All @@ -24,4 +24,17 @@ impl GroundMaterial {
GroundMaterial::Debug => [1.0, 0.0, 0.0],
}
}

pub fn get_id(&self) -> i32 {
match *self {
GroundMaterial::Grass => 1,
GroundMaterial::Sand => 2,
GroundMaterial::Snow => 3,
GroundMaterial::Dirt => 4,
GroundMaterial::Stone => 5,
GroundMaterial::JungleGrass => 1,
GroundMaterial::Mulch => 7,
GroundMaterial::Debug => 8,
}
}
}
3 changes: 0 additions & 3 deletions base/src/world/world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,6 @@ impl World {
if inner_pos.r < 0 {
inner_pos.r += chunk_size;
}
if chunk_pos.q != chunk_pos.r {
::std::mem::swap(&mut inner_pos.r, &mut inner_pos.q);
}
&chunk[inner_pos]
});

Expand Down
10 changes: 2 additions & 8 deletions client/shader/chunk_shadow.vert
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,14 @@
in vec3 position;
in vec3 normal;

// Per-instance attributes:
// Height in units, not world coordinates, since the "pillar prototype" has a
// height of one unit.
in float height;
in vec3 offset;
//in vec3 material_color;

uniform mat4 proj_matrix;
uniform mat4 view_matrix;
uniform vec2 offset;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks unused too

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uhm... what about ...


void main() {
vec4 world_coords = vec4(
position.xy + offset.xy,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, nevermind 😆

position.z * height + offset.z,
position.z,
1);
gl_Position = proj_matrix * view_matrix * world_coords;
}
16 changes: 3 additions & 13 deletions client/shader/chunk_std.vert
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,6 @@ in vec3 position;
in vec3 normal;
in float radius;
in vec2 tex_coords;

// Per-instance attributes:
// Height in units, not world coordinates, since the "pillar prototype" has a
// height of one unit.
in float height;
in vec3 offset;
in vec3 material_color;
in int ground;

Expand All @@ -32,12 +26,13 @@ out vec3 pos;
uniform mat4 proj_matrix;
uniform mat4 view_matrix;
uniform mat4 depth_view_proj;
uniform vec2 offset;
Copy link
Contributor

@jonas-schievink jonas-schievink Aug 7, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems unused? Nevermind

uniform vec3 cam_pos;

void main() {
vec4 world_coords = vec4(
position.xy + offset.xy,
position.z * height + offset.z,
position.z,
1);

gl_Position = proj_matrix * view_matrix * world_coords;
Expand All @@ -48,15 +43,10 @@ void main() {
x_radius = radius;
x_tex_coords = tex_coords;

// adjusting the height for the sides of each hexagon
if(tex_coords.y > 1.5){
x_tex_coords.y = height;
}

x_position = position;
x_ground = ground;

// position in relation to player ignoring hight, needed for fog
pos = vec3(offset - cam_pos);
// pos = vec3(offset - cam_pos);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes the line below read pos before it is initialized, which causes the rendering glitches I was experiencing.

pos = vec3(pos.x, pos.y, 0);
}
2 changes: 0 additions & 2 deletions client/shader/plants.tcs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ struct OutputPatch {

patch out OutputPatch oPatch;



vec3 ProjectToPlane(vec3 Point, vec3 PlanePoint, vec3 PlaneNormal)
{
vec3 v = Point - PlanePoint;
Expand Down
77 changes: 22 additions & 55 deletions client/src/world/chunk_renderer.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@

use base::world;
use std::f32::consts;
use world::chunk_view::Vertex;
use glium::{IndexBuffer, Program, VertexBuffer};
use glium::index::PrimitiveType;
use glium::texture::Texture2d;
Expand All @@ -17,12 +15,6 @@ pub struct ChunkRenderer {
program: Program,
/// Shadow map shader
shadow_program: Program,
/// Vertex buffer for a single `HexPillar`, repeated, scaled and colored as
/// needed to draw chunks.
pillar_vbuf: VertexBuffer<Vertex>,
/// Index Buffer for `pillar_vbuf`.
pillar_ibuf: IndexBuffer<u32>,
/// Texturemaps for fragment shader
pub noise_sand: Texture2d,
pub noise_snow: Texture2d,
pub noise_grass: Texture2d,
Expand All @@ -41,17 +33,6 @@ pub struct ChunkRenderer {

impl ChunkRenderer {
pub fn new(context: Rc<GameContext>) -> Self {
let mut vertices = Vec::new();
let mut indices = Vec::new();
get_top_hexagon_model(&mut vertices, &mut indices);
get_bottom_hexagon_model(&mut vertices, &mut indices);
get_side_hexagon_model(4, 5, &mut vertices, &mut indices);
get_side_hexagon_model(1, 2, &mut vertices, &mut indices);
get_side_hexagon_model(5, 0, &mut vertices, &mut indices);
get_side_hexagon_model(0, 1, &mut vertices, &mut indices);
get_side_hexagon_model(3, 4, &mut vertices, &mut indices);
get_side_hexagon_model(2, 3, &mut vertices, &mut indices);

// Get a tupel of a heightmap and texturemap
let sand = tex_generator::create_texture_maps(GroundMaterial::Sand);
let snow = tex_generator::create_texture_maps(GroundMaterial::Snow);
Expand All @@ -63,11 +44,6 @@ impl ChunkRenderer {
ChunkRenderer {
program: context.load_program("chunk_std").unwrap(),
shadow_program: context.load_program("chunk_shadow").unwrap(),
pillar_vbuf: VertexBuffer::new(context.get_facade(), &vertices).unwrap(),
pillar_ibuf: IndexBuffer::new(context.get_facade(),
PrimitiveType::TrianglesList,
&indices)
.unwrap(),
// Creating a sampler2D from the texturemap
noise_sand: Texture2d::new(context.get_facade(), sand.1).unwrap(),
noise_snow: Texture2d::new(context.get_facade(), snow.1).unwrap(),
Expand Down Expand Up @@ -107,21 +83,11 @@ impl ChunkRenderer {
pub fn shadow_program(&self) -> &Program {
&self.shadow_program
}

/// Gets the `VertexBuffer` to use for drawing a pillar
pub fn pillar_vertices(&self) -> &VertexBuffer<Vertex> {
&self.pillar_vbuf
}

/// Gets the `IndexBuffer` to use for drawing a pillar
pub fn pillar_indices(&self) -> &IndexBuffer<u32> {
&self.pillar_ibuf
}
}

pub struct HexagonOutline {
program: Program,
vbuf: VertexBuffer<Vertex>,
vbuf: VertexBuffer<OutlineVertex>,
ibuf: IndexBuffer<u32>,
pub pos: Vector3f,
pub display: bool,
Expand Down Expand Up @@ -155,7 +121,7 @@ impl HexagonOutline {
&self.pos
}

pub fn vertices(&self) -> &VertexBuffer<Vertex> {
pub fn vertices(&self) -> &VertexBuffer<OutlineVertex> {
&self.vbuf
}

Expand All @@ -168,6 +134,15 @@ impl HexagonOutline {
}
}

#[derive(Clone, Copy)]
pub struct OutlineVertex {
pub position: [f32; 3],
pub normal: [f32; 3],
pub tex_coords: [f32; 2],
}

implement_vertex!(OutlineVertex, position, normal, tex_coords);



/// Calculates one Point-coordinates of a Hexagon
Expand All @@ -193,27 +168,25 @@ fn tex_map(i: i32) -> (f32, f32) {
}

/// Calculates the top face of the Hexagon and normals
fn get_top_hexagon_model(vertices: &mut Vec<Vertex>, indices: &mut Vec<u32>) {
fn get_top_hexagon_model(vertices: &mut Vec<OutlineVertex>, indices: &mut Vec<u32>) {
let cur_len = vertices.len() as u32;
// Corner vertices
for i in 0..6 {
let (x, y) = hex_corner(world::HEX_OUTER_RADIUS, i);

let (a, b) = tex_map(i);

vertices.push(Vertex {
vertices.push(OutlineVertex {
position: [x, y, world::PILLAR_STEP_HEIGHT],
normal: [0.0, 0.0, 1.0],
radius: 1.0,
tex_coords: [a, b],
});
}

// Central Vertex
vertices.push(Vertex {
vertices.push(OutlineVertex {
position: [0.0, 0.0, world::PILLAR_STEP_HEIGHT],
normal: [0.0, 0.0, 1.0],
radius: 0.0,
tex_coords: [0.5, 0.5],
});

Expand All @@ -238,25 +211,23 @@ fn get_top_hexagon_model(vertices: &mut Vec<Vertex>, indices: &mut Vec<u32>) {
}

/// Calculates the bottom face of the Hexagon and the normals
fn get_bottom_hexagon_model(vertices: &mut Vec<Vertex>, indices: &mut Vec<u32>) {
fn get_bottom_hexagon_model(vertices: &mut Vec<OutlineVertex>, indices: &mut Vec<u32>) {
let cur_len = vertices.len() as u32;
for i in 0..6 {
let (x, y) = hex_corner(world::HEX_OUTER_RADIUS, i);

let (a, b) = tex_map(i);

vertices.push(Vertex {
vertices.push(OutlineVertex {
position: [x, y, 0.0],
normal: [0.0, 0.0, -1.0],
radius: 1.0,
tex_coords: [a, b],
});
}

vertices.push(Vertex {
vertices.push(OutlineVertex {
position: [0.0, 0.0, 0.0],
normal: [0.0, 0.0, -1.0],
radius: 0.0,
tex_coords: [0.5, 0.5],
});

Expand All @@ -283,36 +254,32 @@ fn get_bottom_hexagon_model(vertices: &mut Vec<Vertex>, indices: &mut Vec<u32>)
/// Calculates the sides of the Hexagon and normals
fn get_side_hexagon_model(ind1: i32,
ind2: i32,
vertices: &mut Vec<Vertex>,
vertices: &mut Vec<OutlineVertex>,
indices: &mut Vec<u32>) {
let cur_len = vertices.len() as u32;
let (x1, y1) = hex_corner(world::HEX_OUTER_RADIUS, ind1);
let (x2, y2) = hex_corner(world::HEX_OUTER_RADIUS, ind2);
let normal = [y1 + y2, x1 + x2, 0.0];

// TODO: tex_coords fix
vertices.push(Vertex {
vertices.push(OutlineVertex {
position: [x1, y1, world::PILLAR_STEP_HEIGHT],
normal: normal,
radius: 0.0,
tex_coords: [0.0, 2.0],
});
vertices.push(Vertex {
vertices.push(OutlineVertex {
position: [x1, y1, 0.0],
normal: normal,
radius: 0.0,
tex_coords: [0.0, 0.0],
});
vertices.push(Vertex {
vertices.push(OutlineVertex {
position: [x2, y2, world::PILLAR_STEP_HEIGHT],
normal: normal,
radius: 0.0,
tex_coords: [1.0, 2.0],
});
vertices.push(Vertex {
vertices.push(OutlineVertex {
position: [x2, y2, 0.0],
normal: normal,
radius: 0.0,
tex_coords: [1.0, 0.0],
});

Expand Down
Loading