Skip to content
This repository was archived by the owner on Jan 9, 2026. It is now read-only.

Commit ca53bea

Browse files
authored
Merge pull request #3 from XavierCS-dev/rewrite
Rewrite texturing system
2 parents 862a3f8 + c7a251f commit ca53bea

22 files changed

Lines changed: 749 additions & 864 deletions

Cargo.lock

Lines changed: 108 additions & 158 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ edition = "2021"
77

88
[dependencies]
99
winit = { version = "0.29", features = ["rwh_05"]}
10-
wgpu = "0.18"
10+
wgpu = "0.19"
1111
pollster = "0.3.0"
1212
raw-window-handle = "0.6.0"
1313
bytemuck = { version = "1.14", features = [ "derive" ] }

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2023 Shirubā
3+
Copyright (c) 2023 Shiruba
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 43 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,43 @@
1-
## Next Steps (Phase 1 - Renderer)
2-
- [x] Remove EntityGroup2D - don't want it to take entity owernship
3-
- [x] Find different way to pass refs to entities grouped by layer to render function
4-
- [x] Render function - iterate through layers to draw, call methods to get buffers
5-
- [x] Layers - Create and write to buffers when needed.
6-
- [x] TextureAtlas2D - Complete atlas, to expand across width and height, and limit self to 8096x8096
7-
- [x] Create descriptors for entity
8-
- [ ] Create Transform 2D maths stuff for entity (later)
9-
- [ ] Create buffers in shader
10-
- [x] Add buffer layouts to pipeline
11-
- [ ] Add bind group layouts to pipeline (Mainly for entity)
12-
- [ ] Implement Entity2D::new()
13-
- [x] Switch HashMap to BTreeMap where it makes sense to do so
14-
- [ ] Add unit tests
15-
- [x] Fix buffer locations
16-
- [ ] Modify Texture to be added to a layer upon creation
17-
- [ ] Refactor
18-
- [ ] Reduce black box state
19-
- [ ] Increase unit test friendliness
20-
- [ ] Hide main loop from user, or at least, make it easier to use
21-
- [ ] Event System
1+
## Next Steps (Rewrite)
2+
- [x] Remove TexturePool entirely.
3+
- [x] Implement one time texture init for layer2D and atlas2D
4+
- [x] Cleanup entity2D
5+
- [x] Reimplement TextureAtlas2D.
6+
- [x] Increase use of ECS paradigm.
7+
- [x] Increase simplicity of Layer2D to be used directly by a user.
8+
- [x] Increase overall simplicity and reduce abstraction.
9+
- [x] Make complex high performance paths optional
10+
- [x] Make layers and their atlases not allow dynamic addition and removal of textures
11+
- [x] Fix incorrect buffer allocation / entity copying
12+
- [x] Fix (shaders maybe?) to use correct texture atlas coordinates
13+
- store total width and height in layer atlas then use to calc exact tex position
14+
- [x] Fix tex aspect ratio
15+
- [x] Remove * 10.0 in vertex group when texture atlas complete
16+
- [x] Fix issues where entity buffers aren't updated correctly
17+
- [x] Fix entity positioning being incorrect
18+
~~¬- [ ] Implement 2D transformations first~~
19+
- [x] Fix broken buffers
20+
- [x] Fix bug which causes different entities to use the texture of the first one in the buffer
21+
- [x] Finish rewrite and clean everything up
22+
- [ ] Find alternative to limit worldspace inaccuracies.
23+
- [x] Remove unnecessary params
24+
- [x] Remove unecessary functions
25+
- [x] Add functions so user doesn't need to access queue and device
26+
- [x] Any other issues
27+
- [ ] Merge with main
28+
29+
- [ ] Further goals (0.2.0 release blockers)
30+
- [ ] Implement Transformation2D
31+
- [ ] Implement Camera2D (using 3D proj matrix)
32+
33+
- [ ] Possible 0.3.0 release
34+
- [ ] Sound system
35+
- [ ] User input system
36+
37+
- [ ] Possible 0.4.0 release
38+
- [ ] Physics system including Collision2D suvat etc
39+
40+
- [ ] Possible 0.5.0 release
41+
- [ ] GUI using framework eg iced egui
42+
43+
- [ ] 1.0 release when all basic components needed to make a game present and code is in good shape + performant

bob.png

391 Bytes
Loading

evil.png

478 Bytes
Loading

memes.png

2.94 KB
Loading

src/engine/engine.rs

Lines changed: 70 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,28 @@
1+
use std::sync::Arc;
2+
13
use crate::engine::entity::entity::Entity2D;
24
use crate::engine::entity::entity::Entity2DRaw;
35
use crate::engine::layer::layer::*;
46
use wgpu::util::DeviceExt;
7+
use winit::dpi::PhysicalSize;
58

69
use super::primitives::vector::Vector3;
710
use super::{
811
primitives::vertex::Vertex,
9-
texture::{
10-
texture2d::{Texture2D, TextureID},
11-
texture_pool::TexturePool2D,
12-
},
12+
texture::texture2d::{Texture2D, TextureID},
1313
traits::layer::Layer,
1414
};
1515

16+
use anyhow::Result;
17+
1618
pub struct Engine {
17-
surface: wgpu::Surface,
19+
surface: wgpu::Surface<'static>,
1820
device: wgpu::Device,
1921
queue: wgpu::Queue,
2022
surface_configuration: wgpu::SurfaceConfiguration,
21-
window: winit::window::Window,
23+
window: Arc<winit::window::Window>,
2224
render_pipeline: wgpu::RenderPipeline,
23-
texture_pool: TexturePool2D,
25+
texture_bgl: wgpu::BindGroupLayout,
2426
}
2527

2628
/*
@@ -33,7 +35,8 @@ impl Engine {
3335
backends: wgpu::Backends::all(),
3436
..Default::default()
3537
});
36-
let surface = unsafe { instance.create_surface(&window).unwrap() };
38+
let window = Arc::new(window);
39+
let surface = instance.create_surface(window.clone()).unwrap();
3740
let adapter = instance
3841
.request_adapter(&wgpu::RequestAdapterOptions {
3942
power_preference: wgpu::PowerPreference::default(),
@@ -46,15 +49,14 @@ impl Engine {
4649
.request_device(
4750
&wgpu::DeviceDescriptor {
4851
label: Some("Adapter"),
49-
features: adapter.features(),
50-
limits: wgpu::Limits::default(),
52+
required_features: adapter.features(),
53+
required_limits: wgpu::Limits::default(),
5154
},
5255
None,
5356
)
5457
.await
5558
.unwrap();
5659

57-
let texture_pool = TexturePool2D::new(&device);
5860
let surface_capabilities = surface.get_capabilities(&adapter);
5961
// Check this...may need to specifically set it to some sRGB value
6062
let surface_format = surface_capabilities.formats[0];
@@ -66,16 +68,39 @@ impl Engine {
6668
present_mode: wgpu::PresentMode::AutoNoVsync,
6769
alpha_mode: surface_capabilities.alpha_modes[0],
6870
view_formats: Vec::new(),
71+
desired_maximum_frame_latency: Default::default(),
6972
};
7073
surface.configure(&device, &surface_configuration);
7174

7275
let shader_module =
7376
device.create_shader_module(wgpu::include_wgsl!("../shaders/shader.wgsl"));
7477

78+
let texture_bgl = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
79+
entries: &[
80+
wgpu::BindGroupLayoutEntry {
81+
binding: 0,
82+
visibility: wgpu::ShaderStages::FRAGMENT,
83+
ty: wgpu::BindingType::Texture {
84+
multisampled: false,
85+
view_dimension: wgpu::TextureViewDimension::D2,
86+
sample_type: wgpu::TextureSampleType::Float { filterable: true },
87+
},
88+
count: None,
89+
},
90+
wgpu::BindGroupLayoutEntry {
91+
binding: 1,
92+
visibility: wgpu::ShaderStages::FRAGMENT,
93+
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
94+
count: None,
95+
},
96+
],
97+
label: Some("Bind group layout"),
98+
});
99+
75100
let render_pipeline_layout =
76101
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
77102
label: Some("Pipeline layout descriptor"),
78-
bind_group_layouts: &[texture_pool.bind_group_layout()],
103+
bind_group_layouts: &[&texture_bgl],
79104
push_constant_ranges: &[],
80105
});
81106

@@ -107,7 +132,7 @@ impl Engine {
107132
entry_point: "frg_main",
108133
targets: &[Some(wgpu::ColorTargetState {
109134
format: surface_configuration.format,
110-
blend: Some(wgpu::BlendState::REPLACE),
135+
blend: Some(wgpu::BlendState::PREMULTIPLIED_ALPHA_BLENDING),
111136
write_mask: wgpu::ColorWrites::ALL,
112137
})],
113138
}),
@@ -121,7 +146,7 @@ impl Engine {
121146
surface_configuration,
122147
window,
123148
render_pipeline,
124-
texture_pool,
149+
texture_bgl,
125150
}
126151
}
127152

@@ -147,11 +172,7 @@ impl Engine {
147172
// if accuracy is a problem, change to floats
148173
}
149174

150-
// Must be rendered in order. Maybe be no existent layers inbetween, needs to happen fast.
151-
// Vec can be sorted each time entities is appended to with a new entity2d and layerid.
152-
// probably a lot faster and space efficient than hashmap
153-
// entities managed by APP struct
154-
pub fn render(&mut self, entities: Vec<Vec<&Entity2D>>) -> Result<(), wgpu::SurfaceError> {
175+
pub fn render(&mut self, entities: &Vec<Layer2D>) -> Result<(), wgpu::SurfaceError> {
155176
let surface_texture = self.surface.get_current_texture()?;
156177
let texture_view = surface_texture
157178
.texture
@@ -169,8 +190,8 @@ impl Engine {
169190
ops: wgpu::Operations {
170191
load: wgpu::LoadOp::Clear(wgpu::Color {
171192
r: 0.0,
172-
g: 0.0,
173-
b: 0.0,
193+
g: 0.5,
194+
b: 0.5,
174195
a: 0.0,
175196
}),
176197
store: wgpu::StoreOp::Store,
@@ -180,17 +201,13 @@ impl Engine {
180201
timestamp_writes: None,
181202
occlusion_query_set: None,
182203
});
183-
184-
for (layer_id, layer) in self.texture_pool.get_layers() {
185-
render_pass.set_pipeline(&self.render_pipeline);
186-
render_pass.set_bind_group(
187-
0,
188-
self.texture_pool.get_layer(layer_id).unwrap().bind_group(),
189-
&[],
190-
);
191-
render_pass.set_vertex_buffer(0, layer.vertex_buffer().unwrap().slice(..));
192-
render_pass.set_index_buffer(layer.index_buffer().slice(..), wgpu::IndexFormat::Uint32);
193-
render_pass.draw_indexed(0..layer.index_count() as u32, 0, 0..1);
204+
render_pass.set_pipeline(&self.render_pipeline);
205+
for layer in entities {
206+
render_pass.set_bind_group(0, layer.bind_group(), &[]);
207+
render_pass.set_vertex_buffer(0, layer.vertex_buffer());
208+
render_pass.set_vertex_buffer(1, layer.entity_buffer().unwrap());
209+
render_pass.set_index_buffer(layer.index_buffer(), wgpu::IndexFormat::Uint16);
210+
render_pass.draw_indexed(0..6 as u32, 0, 0..layer.entity_count() as u32);
194211
}
195212

196213
drop(render_pass);
@@ -211,26 +228,33 @@ impl Engine {
211228
&self.window
212229
}
213230

214-
pub fn texture_pool(&mut self) -> &mut TexturePool2D {
215-
&mut self.texture_pool
216-
}
217-
218231
pub fn init_entity(
219232
&mut self,
220233
position: Vector3,
221-
texture: &Texture2D,
222-
layer: LayerID,
234+
texture: TextureID,
235+
layer: &mut Layer2D,
223236
) -> Entity2D {
224-
let dimensions = self.window().inner_size();
225-
Entity2D::new(
226-
position,
227-
&mut self.texture_pool,
228-
layer,
229-
texture.clone(),
230-
dimensions.width,
231-
dimensions.height,
237+
Entity2D::new(position, layer, texture)
238+
}
239+
240+
pub fn init_layer(
241+
&self,
242+
id: LayerID,
243+
textures: Vec<Texture2D>,
244+
texture_size: PhysicalSize<u32>,
245+
) -> Result<Layer2D> {
246+
Layer2D::new(
247+
id,
248+
self.window.inner_size(),
249+
textures,
232250
&self.device,
233251
&self.queue,
252+
&self.texture_bgl,
253+
texture_size,
234254
)
235255
}
256+
257+
pub fn set_entities(&self, layer: &mut Layer2D, entities: &[&Entity2D]) {
258+
Layer2DSystem::set_entities(layer, entities, &self.device, &self.queue)
259+
}
236260
}

0 commit comments

Comments
 (0)