Skip to content

Commit

Permalink
tesselator now uses reference to vertices
Browse files Browse the repository at this point in the history
  • Loading branch information
Uriopass committed Feb 5, 2024
1 parent bfe4335 commit 77f474a
Show file tree
Hide file tree
Showing 17 changed files with 308 additions and 259 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ world
*.tar.gz
__pycache__
*/target*
target*
2 changes: 1 addition & 1 deletion assets_gui/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ fn create_shown(gfx: &mut GfxContext, _state: &State, inspected: Inspected) -> S
))
}
};
let mut sb: SpriteBatchBuilder<false> = SpriteBatchBuilder::new(tex, gfx);
let mut sb: SpriteBatchBuilder<false> = SpriteBatchBuilder::new(&tex, gfx);
sb.push(Vec3::ZERO, Vec3::X, LinearColor::WHITE, (100.0, 100.0));
Shown::Sprite(sb.build(gfx).unwrap())
}
Expand Down
4 changes: 2 additions & 2 deletions engine/src/drawables/spritebatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ impl InstanceRaw {
impl<const PERSISTENT: bool> SpriteBatchBuilder<PERSISTENT> {
pub fn from_path(gfx: &mut GfxContext, path: impl Into<PathBuf>) -> Self {
let tex = gfx.texture(path, "some spritebatch tex");
Self::new(tex, gfx)
Self::new(&tex, gfx)
}

pub fn clear(&mut self) {
Expand All @@ -67,7 +67,7 @@ impl<const PERSISTENT: bool> SpriteBatchBuilder<PERSISTENT> {
self
}

pub fn new(albedo: Arc<Texture>, gfx: &mut GfxContext) -> Self {
pub fn new(albedo: &Texture, gfx: &mut GfxContext) -> Self {
let max_extent = albedo.extent.width.max(albedo.extent.height) as f32;

let stretch_x = 0.5 * albedo.extent.width as f32 / max_extent;
Expand Down
182 changes: 96 additions & 86 deletions engine/src/geometry/tesselator.rs
Original file line number Diff line number Diff line change
@@ -1,39 +1,51 @@
use crate::geometry::earcut::earcut;
use crate::meshbuild::MeshBuilder;
use crate::{GfxContext, Material, MeshVertex, MetallicRoughness};
use geom::{vec3, Intersect, LinearColor, Segment, Vec2, Vec3, AABB};
use itertools::Itertools;

pub struct Tesselator<const PERSISTENT: bool> {
use geom::{vec3, Intersect, LinearColor, Segment, Vec2, Vec3, AABB};

use crate::geometry::earcut::earcut;
use crate::{IndexType, MeshVertex};

pub struct Tesselator<'a> {
pub color: LinearColor,
pub meshbuilder: MeshBuilder<PERSISTENT>,
pub vertices: &'a mut Vec<MeshVertex>,
pub indices: &'a mut Vec<IndexType>,
pub cull_rect: Option<AABB>,
pub zoom: f32,
pub normal: Vec3,
}

impl<const PERSISTENT: bool> Tesselator<PERSISTENT> {
pub fn new(gfx: &mut GfxContext, cull_rect: Option<AABB>, zoom: f32) -> Self {
let mat = gfx.register_material(Material::new(
gfx,
gfx.palette(),
MetallicRoughness {
metallic: 0.0,
roughness: 1.0,
tex: None,
},
None,
));

impl<'a> Tesselator<'a> {
pub fn new(
vertices: &'a mut Vec<MeshVertex>,
indices: &'a mut Vec<IndexType>,
cull_rect: Option<AABB>,
zoom: f32,
) -> Self {
Tesselator {
color: LinearColor::BLACK,
meshbuilder: MeshBuilder::new(mat),
vertices,
indices,
cull_rect,
zoom,
normal: Vec3::Z,
}
}

pub fn extend(&mut self, vertices: &[MeshVertex], indices: &[IndexType]) {
self.vertices.extend_from_slice(vertices);
self.indices.extend_from_slice(indices);
}

pub fn extend_with(&mut self, f: impl FnOnce(&mut Vec<MeshVertex>, &mut dyn FnMut(IndexType))) {
let offset = self.vertices.len() as IndexType;
let vertices = &mut self.vertices;
let indices = &mut self.indices;
let mut x = move |index: IndexType| {
indices.push(index + offset);
};
f(vertices, &mut x);
}

pub fn draw_circle(&mut self, p: Vec3, r: f32) -> bool {
if r <= 0.0
|| self
Expand Down Expand Up @@ -66,7 +78,7 @@ impl<const PERSISTENT: bool> Tesselator<PERSISTENT> {
let n_pointsu32 = n_points as u32;
let normal = self.normal;

self.meshbuilder.extend_with(None, |vertices, index_push| {
self.extend_with(|vertices, index_push| {
vertices.push(MeshVertex {
position: p.into(),
color,
Expand Down Expand Up @@ -108,7 +120,7 @@ impl<const PERSISTENT: bool> Tesselator<PERSISTENT> {

let color: [f32; 4] = self.color.into();
let normal = self.normal;
self.meshbuilder.extend_with(None, |vertices, index_push| {
self.extend_with(|vertices, index_push| {
vertices.extend(points.iter().map(|p| MeshVertex {
position: [p.x, p.y, z],
color,
Expand Down Expand Up @@ -142,7 +154,7 @@ impl<const PERSISTENT: bool> Tesselator<PERSISTENT> {

let color = self.color.into();
let normal = self.normal;
self.meshbuilder.extend_with(None, |vertices, index_push| {
self.extend_with(|vertices, index_push| {
vertices.push(MeshVertex {
position: (p + Vec3::x(r + halfthick)).into(),
color,
Expand Down Expand Up @@ -248,7 +260,7 @@ impl<const PERSISTENT: bool> Tesselator<PERSISTENT> {
tangent: [0.0; 4],
},
];
self.meshbuilder.extend(None, &verts, &[2, 1, 0, 3, 2, 0]);
self.extend(&verts, &[2, 1, 0, 3, 2, 0]);
true
}

Expand Down Expand Up @@ -307,8 +319,7 @@ impl<const PERSISTENT: bool> Tesselator<PERSISTENT> {
},
];

self.meshbuilder.extend(
None,
self.extend(
&verts,
if self.normal.z < 0.0 {
&[2, 1, 0, 3, 2, 0]
Expand Down Expand Up @@ -371,76 +382,75 @@ impl<const PERSISTENT: bool> Tesselator<PERSISTENT> {
let color = self.color.into();
let normal = self.normal;
let swap = (self.normal.z < 0.0) as u32 * 2;
self.meshbuilder
.extend_with(None, move |verts, index_push| {
let mut idx_quad = move |index| {
index_push(index * 2 + swap);
index_push(index * 2 + 1);
index_push(index * 2 + 2 - swap);

index_push(index * 2 + 3 - swap);
index_push(index * 2 + 2);
index_push(index * 2 + 1 + swap);
};
self.extend_with(move |verts, index_push| {
let mut idx_quad = move |index| {
index_push(index * 2 + swap);
index_push(index * 2 + 1);
index_push(index * 2 + 2 - swap);

index_push(index * 2 + 3 - swap);
index_push(index * 2 + 2);
index_push(index * 2 + 1 + swap);
};

let mut pvert = move |pos: Vec3| {
verts.push(MeshVertex {
position: pos.into(),
color,
normal,
uv: [0.0; 2],
tangent: [0.0; 4],
});
};
let mut pvert = move |pos: Vec3| {
verts.push(MeshVertex {
position: pos.into(),
color,
normal,
uv: [0.0; 2],
tangent: [0.0; 4],
});
};

let mut index: u32 = 0;
for (a, elbow, c) in points.tuple_windows() {
let a: Vec3 = a;
let elbow: Vec3 = elbow;
let c: Vec3 = c;
if index == 0 {
let nor = -first_dir.perpendicular();
pvert(a + (nor * (offset + halfthick)).z0());
pvert(a + (nor * (offset - halfthick)).z0());
}
let mut index: u32 = 0;
for (a, elbow, c) in points.tuple_windows() {
let a: Vec3 = a;
let elbow: Vec3 = elbow;
let c: Vec3 = c;
if index == 0 {
let nor = -first_dir.perpendicular();
pvert(a + (nor * (offset + halfthick)).z0());
pvert(a + (nor * (offset - halfthick)).z0());
}

let ae = unwrap_or!((elbow - a).xy().try_normalize(), continue);
let ce = unwrap_or!((elbow - c).xy().try_normalize(), continue);

let dir = match (ae + ce).try_normalize() {
Some(x) => {
let d = ae.perp_dot(ce);
if d.abs() < 0.01 {
-ae.perpendicular()
} else if d < 0.0 {
-x
} else {
x
}
let ae = unwrap_or!((elbow - a).xy().try_normalize(), continue);
let ce = unwrap_or!((elbow - c).xy().try_normalize(), continue);

let dir = match (ae + ce).try_normalize() {
Some(x) => {
let d = ae.perp_dot(ce);
if d.abs() < 0.01 {
-ae.perpendicular()
} else if d < 0.0 {
-x
} else {
x
}
None => -ae.perpendicular(),
};
}
None => -ae.perpendicular(),
};

let mul = 1.0 + (1.0 + ae.dot(ce).min(0.0)) * (std::f32::consts::SQRT_2 - 1.0);
let mul = 1.0 + (1.0 + ae.dot(ce).min(0.0)) * (std::f32::consts::SQRT_2 - 1.0);

let p1 = elbow + (mul * dir * (offset + halfthick)).z0();
let p2 = elbow + (mul * dir * (offset - halfthick)).z0();
let p1 = elbow + (mul * dir * (offset + halfthick)).z0();
let p2 = elbow + (mul * dir * (offset - halfthick)).z0();
pvert(p1);
pvert(p2);
idx_quad(index);

index += 1;
if index as usize == n_points - 2 {
let nor = -last_dir.perpendicular();

let p1 = c + ((offset + halfthick) * nor).z0();
let p2 = c + ((offset - halfthick) * nor).z0();
pvert(p1);
pvert(p2);
idx_quad(index);

index += 1;
if index as usize == n_points - 2 {
let nor = -last_dir.perpendicular();

let p1 = c + ((offset + halfthick) * nor).z0();
let p2 = c + ((offset - halfthick) * nor).z0();
pvert(p1);
pvert(p2);
idx_quad(index);
}
}
});
}
});
true
}

Expand Down
59 changes: 48 additions & 11 deletions engine/src/gfx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ use crate::passes::{BackgroundPipeline, Pbr};
use crate::perf_counters::PerfCounters;
use crate::{
bg_layout_litmesh, passes, CompiledModule, Drawable, IndexType, LampLights, Material,
MaterialID, MaterialMap, MipmapGenerator, PipelineBuilder, Pipelines, Texture,
TextureBuildError, TextureBuilder, Uniform, UvVertex, WaterPipeline, TL,
MaterialID, MaterialMap, MetallicRoughness, MipmapGenerator, PipelineBuilder, Pipelines,
Texture, TextureBuildError, TextureBuilder, Uniform, UvVertex, WaterPipeline, TL,
};
use common::FastMap;
use geom::{vec2, Camera, InfiniteFrustrum, LinearColor, Matrix4, Plane, Vec2, Vec3};
Expand All @@ -16,12 +16,12 @@ use std::time::{Duration, Instant};
use wgpu::util::{backend_bits_from_env, BufferInitDescriptor, DeviceExt};
use wgpu::{
Adapter, Backends, BindGroupLayout, BlendState, CommandBuffer, CommandEncoder,
CommandEncoderDescriptor, CompositeAlphaMode, DepthBiasState, Device, Face, FilterMode,
FragmentState, FrontFace, InstanceDescriptor, MultisampleState, PipelineLayoutDescriptor,
PrimitiveState, Queue, RenderPassColorAttachment, RenderPassDescriptor, RenderPipeline,
RenderPipelineDescriptor, SamplerDescriptor, Surface, SurfaceConfiguration, SurfaceTexture,
TextureAspect, TextureFormat, TextureUsages, TextureView, TextureViewDescriptor,
TextureViewDimension, VertexBufferLayout, VertexState,
CommandEncoderDescriptor, CompositeAlphaMode, DepthBiasState, Device, Extent3d, Face,
FilterMode, FragmentState, FrontFace, ImageCopyTexture, ImageDataLayout, InstanceDescriptor,
MultisampleState, PipelineLayoutDescriptor, PrimitiveState, Queue, RenderPassColorAttachment,
RenderPassDescriptor, RenderPipeline, RenderPipelineDescriptor, SamplerDescriptor, Surface,
SurfaceConfiguration, SurfaceTexture, TextureAspect, TextureFormat, TextureUsages, TextureView,
TextureViewDescriptor, TextureViewDimension, VertexBufferLayout, VertexState,
};
use winit::window::{Fullscreen, Window};

Expand Down Expand Up @@ -49,14 +49,15 @@ pub struct GfxContext {

pub(crate) materials: MaterialMap,
pub(crate) default_material: Material,
pub tess_material: MaterialID,
pub tick: u64,
pub(crate) pipelines: RefCell<Pipelines>,
pub frustrum: InfiniteFrustrum,
pub(crate) sun_params: [Uniform<RenderParams>; N_CASCADES],
pub render_params: Uniform<RenderParams>,
pub(crate) texture_cache_paths: FastMap<PathBuf, Arc<Texture>>,
pub(crate) texture_cache_bytes: Mutex<HashMap<u64, Arc<Texture>, common::TransparentHasherU64>>,
pub(crate) null_texture: Texture,
pub null_texture: Texture,
pub(crate) linear_sampler: wgpu::Sampler,

pub(crate) samples: u32,
Expand Down Expand Up @@ -338,7 +339,27 @@ impl GfxContext {
let null_texture = TextureBuilder::empty(1, 1, 1, TextureFormat::Rgba8Unorm)
.with_srgb(false)
.with_label("null texture")
.build(&device, &queue);
.build_no_queue(&device);

queue.write_texture(
ImageCopyTexture {
texture: &null_texture.texture,
mip_level: 0,
origin: wgpu::Origin3d::ZERO,
aspect: Default::default(),
},
&[255, 255, 255, 255],
ImageDataLayout {
offset: 0,
bytes_per_row: Some(4),
rows_per_image: None,
},
Extent3d {
width: 1,
height: 1,
depth_or_array_layers: 1,
},
);

let linear_sampler = device.create_sampler(&SamplerDescriptor {
label: Some("basic linear sampler"),
Expand All @@ -348,6 +369,21 @@ impl GfxContext {
..Default::default()
});

let mut materials = MaterialMap::default();

let tess_material = Material::new_raw(
&device,
&null_texture,
MetallicRoughness {
metallic: 0.0,
roughness: 1.0,
tex: None,
},
None,
&null_texture,
);
let tess_material_id = materials.insert(tess_material);

let mut me = Self {
window,
size: (win_width, win_height, win_scale_factor),
Expand All @@ -357,7 +393,8 @@ impl GfxContext {
fbos,
surface,
pipelines: RefCell::new(Pipelines::new()),
materials: Default::default(),
materials,
tess_material: tess_material_id,
default_material: Material::new_default(&device, &queue, &null_texture),
tick: 0,
frustrum: InfiniteFrustrum::new([Plane::X; 5]),
Expand Down
Loading

0 comments on commit 77f474a

Please sign in to comment.