Particles file added
This commit is contained in:
160
core/particles.jai
Normal file
160
core/particles.jai
Normal file
@@ -0,0 +1,160 @@
|
||||
MAX_PARTICLES :: 2048;
|
||||
|
||||
Particle :: struct {
|
||||
velocity: Vector3;
|
||||
position: Vector3;
|
||||
color: Vector4;
|
||||
|
||||
initial_lifetime: float;
|
||||
lifetime: float;
|
||||
|
||||
initial_size: float;
|
||||
size: float;
|
||||
}
|
||||
|
||||
Particle_Vertex :: struct {
|
||||
position: Vector3;
|
||||
color: Vector4;
|
||||
uv: Vector2;
|
||||
}
|
||||
|
||||
Particle_System :: struct {
|
||||
active: bool;
|
||||
particles: [..] Particle;
|
||||
pipeline: Pipeline_State_Handle;
|
||||
|
||||
owning_entity: *Entity;
|
||||
|
||||
time: float;
|
||||
position: Vector3;
|
||||
|
||||
vertex_buffer: Buffer_Handle;
|
||||
|
||||
_locator: Bucket_Locator;
|
||||
|
||||
on_particle_update: (*Particle_System, float);
|
||||
}
|
||||
|
||||
create_particle_system :: (pipeline: Pipeline_State_Handle, update_func: (*Particle_System, float), owning_entity: *Entity = null, scene: *Scene = null) -> *Particle_System {
|
||||
lvl := ifx scene == null then game_state.current_scene else scene;
|
||||
particle_system, locator := find_and_occupy_empty_slot(*scene.particle_systems);
|
||||
particle_system._locator = locator;
|
||||
particle_system.vertex_buffer = create_vertex_buffer(renderer, null, size_of(Particle_Vertex) * MAX_PARTICLES, stride=size_of(Particle_Vertex), mappable=true);
|
||||
particle_system.pipeline = pipeline;
|
||||
particle_system.on_particle_update = update_func;
|
||||
particle_system.owning_entity = owning_entity;
|
||||
return particle_system;
|
||||
}
|
||||
|
||||
spawn_particle :: (system: *Particle_System, position: Vector3, velocity: Vector3 = .{0,0,0}, size: float = 1.0, lifetime: float = 1.0, color: Vector4 = .{1,1,1,1}) {
|
||||
particle: Particle;
|
||||
particle.position = position;
|
||||
particle.velocity = velocity;
|
||||
particle.size = size;
|
||||
particle.initial_size = size;
|
||||
particle.lifetime = lifetime;
|
||||
particle.initial_lifetime = lifetime;
|
||||
particle.color = color;
|
||||
|
||||
array_add(*system.particles, particle);
|
||||
}
|
||||
|
||||
update_particle_systems :: (dt: float) {
|
||||
for *system: game_state.current_scene.particle_systems {
|
||||
if system.on_particle_update != null {
|
||||
system.on_particle_update(system, dt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
update_particle_system :: (system: *Particle_System, dt: float) {
|
||||
}
|
||||
|
||||
prepare_particle_system_for_rendering :: (system: Particle_System) {
|
||||
up := game_state.camera.up;
|
||||
right := game_state.camera.right;
|
||||
forward := game_state.camera.forward;
|
||||
|
||||
rendering_data : [..] Particle_Vertex;
|
||||
rendering_data.allocator = temp;
|
||||
|
||||
for p: system.particles {
|
||||
//alpha := sin((p.lifetime / p.max_lifetime) * PI);
|
||||
//color.w = alpha;
|
||||
//size := p.size * alpha;
|
||||
|
||||
size := p.size;
|
||||
color := p.color;
|
||||
position := p.position - forward * (cast(float)it_index) * 0.01;
|
||||
|
||||
// Tri 0
|
||||
{
|
||||
v : Particle_Vertex;
|
||||
v.uv = .{1, 1};
|
||||
v.position = position + up * size + right * size;
|
||||
v.color = color;
|
||||
array_add(*rendering_data, v);
|
||||
}
|
||||
{
|
||||
v : Particle_Vertex;
|
||||
v.uv = .{1, 0};
|
||||
v.position = position - up * size + right * size;
|
||||
v.color = color;
|
||||
array_add(*rendering_data, v);
|
||||
}
|
||||
{
|
||||
v : Particle_Vertex;
|
||||
v.uv = .{0, 0};
|
||||
v.position = position - up * size - right * size;
|
||||
v.color = color;
|
||||
array_add(*rendering_data, v);
|
||||
}
|
||||
|
||||
// Tri 1
|
||||
{
|
||||
v : Particle_Vertex;
|
||||
v.uv = .{0, 0};
|
||||
v.position = position - up * size - right * size;
|
||||
v.color = color;
|
||||
array_add(*rendering_data, v);
|
||||
}
|
||||
{
|
||||
v : Particle_Vertex;
|
||||
v.uv = .{1, 0};
|
||||
v.position = position + up * size - right * size;
|
||||
v.color = color;
|
||||
array_add(*rendering_data, v);
|
||||
}
|
||||
{
|
||||
v : Particle_Vertex;
|
||||
v.uv = .{1, 1};
|
||||
v.position = position + up * size + right * size;
|
||||
v.color = color;
|
||||
array_add(*rendering_data, v);
|
||||
}
|
||||
}
|
||||
|
||||
if rendering_data.count > 0 {
|
||||
upload_data_to_buffer(renderer, system.vertex_buffer, rendering_data.data, size_of(Particle_Vertex) * rendering_data.count);
|
||||
}
|
||||
}
|
||||
|
||||
render_particle_systems :: () {
|
||||
for system: game_state.current_scene.particle_systems {
|
||||
prepare_particle_system_for_rendering(system);
|
||||
|
||||
if system.particles.count > 0 {
|
||||
push_cmd_set_draw_mode(renderer, .FILL);
|
||||
push_cmd_set_depth_write(renderer, true);
|
||||
push_cmd_set_cull_face(renderer, .BACK);
|
||||
push_cmd_set_pipeline_state(renderer, system.pipeline);
|
||||
|
||||
push_cmd_set_constant_buffer(renderer, 0, camera_buffer, .VERTEX);
|
||||
|
||||
push_cmd_set_vertex_buffer(renderer, system.vertex_buffer);
|
||||
|
||||
push_cmd_draw(renderer, system.particles.count * 6);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user