diff options
Diffstat (limited to 'drivers/gles3/storage/particles_storage.cpp')
-rw-r--r-- | drivers/gles3/storage/particles_storage.cpp | 50 |
1 files changed, 39 insertions, 11 deletions
diff --git a/drivers/gles3/storage/particles_storage.cpp b/drivers/gles3/storage/particles_storage.cpp index 0a6f02511c..1caa3bbe35 100644 --- a/drivers/gles3/storage/particles_storage.cpp +++ b/drivers/gles3/storage/particles_storage.cpp @@ -94,13 +94,15 @@ RID ParticlesStorage::particles_allocate() { } void ParticlesStorage::particles_initialize(RID p_rid) { - particles_owner.initialize_rid(p_rid, Particles()); + particles_owner.initialize_rid(p_rid); } void ParticlesStorage::particles_free(RID p_rid) { - update_particles(); Particles *particles = particles_owner.get_or_null(p_rid); + particles->dependency.deleted_notify(p_rid); + particles->update_list.remove_from_list(); + _particles_free_data(particles); particles_owner.free(p_rid); } @@ -190,6 +192,13 @@ void ParticlesStorage::particles_set_amount(RID p_particles, int p_amount) { particles->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_PARTICLES); } +void ParticlesStorage::particles_set_amount_ratio(RID p_particles, float p_amount_ratio) { + Particles *particles = particles_owner.get_or_null(p_particles); + ERR_FAIL_NULL(particles); + + particles->amount_ratio = p_amount_ratio; +} + void ParticlesStorage::particles_set_lifetime(RID p_particles, double p_lifetime) { Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_NULL(particles); @@ -355,8 +364,10 @@ void ParticlesStorage::particles_request_process(RID p_particles) { if (!particles->dirty) { particles->dirty = true; - particles->update_list = particle_update_list; - particle_update_list = particles; + + if (!particles->update_list.in_list()) { + particle_update_list.add(&particles->update_list); + } } } @@ -431,6 +442,20 @@ void ParticlesStorage::particles_set_emission_transform(RID p_particles, const T particles->emission_transform = p_transform; } +void ParticlesStorage::particles_set_emitter_velocity(RID p_particles, const Vector3 &p_velocity) { + Particles *particles = particles_owner.get_or_null(p_particles); + ERR_FAIL_NULL(particles); + + particles->emitter_velocity = p_velocity; +} + +void ParticlesStorage::particles_set_interp_to_end(RID p_particles, float p_interp) { + Particles *particles = particles_owner.get_or_null(p_particles); + ERR_FAIL_NULL(particles); + + particles->interp_to_end = p_interp; +} + int ParticlesStorage::particles_get_draw_passes(RID p_particles) const { const Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_NULL_V(particles, 0); @@ -507,9 +532,13 @@ void ParticlesStorage::_particles_process(Particles *p_particles, double p_delta frame_params.cycle = p_particles->cycle_number; frame_params.frame = p_particles->frame_counter++; - frame_params.pad0 = 0; + frame_params.amount_ratio = p_particles->amount_ratio; frame_params.pad1 = 0; frame_params.pad2 = 0; + frame_params.interp_to_end = p_particles->interp_to_end; + frame_params.emitter_velocity[0] = p_particles->emitter_velocity.x; + frame_params.emitter_velocity[1] = p_particles->emitter_velocity.y; + frame_params.emitter_velocity[2] = p_particles->emitter_velocity.z; { //collision and attractors @@ -775,7 +804,7 @@ void ParticlesStorage::particles_set_view_axis(RID p_particles, const Vector3 &p LocalVector<ParticleInstanceData3D> particle_vector; particle_vector.resize(particles->amount); particle_array = particle_vector.ptr(); - glGetBufferSubData(GL_ARRAY_BUFFER, 0, particles->amount * sizeof(ParticleInstanceData3D), particle_array); + godot_webgl2_glGetBufferSubData(GL_ARRAY_BUFFER, 0, particles->amount * sizeof(ParticleInstanceData3D), particle_array); #endif SortArray<ParticleInstanceData3D, ParticlesViewSort> sorter; sorter.compare.z_dir = axis; @@ -978,13 +1007,12 @@ void ParticlesStorage::update_particles() { glBindBufferBase(GL_UNIFORM_BUFFER, PARTICLES_GLOBALS_UNIFORM_LOCATION, global_buffer); glBindBuffer(GL_UNIFORM_BUFFER, 0); - while (particle_update_list) { + while (particle_update_list.first()) { // Use transform feedback to process particles. - Particles *particles = particle_update_list; + Particles *particles = particle_update_list.first()->self(); - particle_update_list = particles->update_list; - particles->update_list = nullptr; + particles->update_list.remove_from_list(); particles->dirty = false; _particles_update_buffers(particles); @@ -1133,7 +1161,7 @@ void ParticlesStorage::_particles_reverse_lifetime_sort(Particles *particles) { LocalVector<ParticleInstanceData> particle_vector; particle_vector.resize(particles->amount); particle_array = particle_vector.ptr(); - glGetBufferSubData(GL_ARRAY_BUFFER, 0, buffer_size, particle_array); + godot_webgl2_glGetBufferSubData(GL_ARRAY_BUFFER, 0, buffer_size, particle_array); #endif uint32_t lifetime_split = (MIN(int(particles->amount * particles->sort_buffer_phase), particles->amount - 1) + 1) % particles->amount; |