summaryrefslogtreecommitdiff
path: root/drivers/gles3/rasterizer_storage_gles3.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gles3/rasterizer_storage_gles3.cpp')
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp125
1 files changed, 116 insertions, 9 deletions
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index 7fc2185e9a..9316b025eb 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -3005,6 +3005,7 @@ void RasterizerStorageGLES3::mesh_set_custom_aabb(RID p_mesh, const Rect3 &p_aab
mesh->custom_aabb = p_aabb;
}
+
Rect3 RasterizerStorageGLES3::mesh_get_custom_aabb(RID p_mesh) const {
const Mesh *mesh = mesh_owner.getornull(p_mesh);
@@ -4883,6 +4884,22 @@ void RasterizerStorageGLES3::particles_set_amount(RID p_particles, int p_amount)
}
}
+ if (particles->histories_enabled) {
+
+ for (int i = 0; i < 2; i++) {
+ glBindVertexArray(particles->particle_vao_histories[i]);
+
+ glBindBuffer(GL_ARRAY_BUFFER, particles->particle_buffer_histories[i]);
+ glBufferData(GL_ARRAY_BUFFER, floats * sizeof(float), data, GL_DYNAMIC_COPY);
+
+ for (int j = 0; j < 6; j++) {
+ glEnableVertexAttribArray(j);
+ glVertexAttribPointer(j, 4, GL_FLOAT, GL_FALSE, sizeof(float) * 4 * 6, ((uint8_t *)0) + (j * 16));
+ }
+ particles->particle_valid_histories[i] = false;
+ }
+ }
+
glBindVertexArray(0);
particles->prev_ticks = 0;
@@ -4917,18 +4934,61 @@ void RasterizerStorageGLES3::particles_set_randomness_ratio(RID p_particles, flo
ERR_FAIL_COND(!particles);
particles->randomness = p_ratio;
}
+
+void RasterizerStorageGLES3::_particles_update_histories(Particles *particles) {
+
+ bool needs_histories = particles->draw_order == VS::PARTICLES_DRAW_ORDER_VIEW_DEPTH;
+
+ if (needs_histories == particles->histories_enabled)
+ return;
+
+ particles->histories_enabled = needs_histories;
+
+ int floats = particles->amount * 24;
+
+ if (!needs_histories) {
+
+ glDeleteBuffers(2, particles->particle_buffer_histories);
+ glDeleteVertexArrays(2, particles->particle_vao_histories);
+
+ } else {
+
+ glGenBuffers(2, particles->particle_buffer_histories);
+ glGenVertexArrays(2, particles->particle_vao_histories);
+
+ for (int i = 0; i < 2; i++) {
+ glBindVertexArray(particles->particle_vao_histories[i]);
+
+ glBindBuffer(GL_ARRAY_BUFFER, particles->particle_buffer_histories[i]);
+ glBufferData(GL_ARRAY_BUFFER, floats * sizeof(float), NULL, GL_DYNAMIC_COPY);
+
+ for (int j = 0; j < 6; j++) {
+ glEnableVertexAttribArray(j);
+ glVertexAttribPointer(j, 4, GL_FLOAT, GL_FALSE, sizeof(float) * 4 * 6, ((uint8_t *)0) + (j * 16));
+ }
+
+ particles->particle_valid_histories[i] = false;
+ }
+ }
+
+ particles->clear = true;
+}
+
void RasterizerStorageGLES3::particles_set_custom_aabb(RID p_particles, const Rect3 &p_aabb) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
particles->custom_aabb = p_aabb;
+ _particles_update_histories(particles);
+ particles->instance_change_notify();
}
-void RasterizerStorageGLES3::particles_set_gravity(RID p_particles, const Vector3 &p_gravity) {
+
+void RasterizerStorageGLES3::particles_set_speed_scale(RID p_particles, float p_scale) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
- particles->gravity = p_gravity;
+ particles->speed_scale = p_scale;
}
void RasterizerStorageGLES3::particles_set_use_local_coordinates(RID p_particles, bool p_enable) {
@@ -4968,6 +5028,7 @@ void RasterizerStorageGLES3::particles_set_draw_order(RID p_particles, VS::Parti
ERR_FAIL_COND(!particles);
particles->draw_order = p_order;
+ _particles_update_histories(particles);
}
void RasterizerStorageGLES3::particles_set_draw_passes(RID p_particles, int p_passes) {
@@ -5001,7 +5062,39 @@ Rect3 RasterizerStorageGLES3::particles_get_current_aabb(RID p_particles) {
const Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND_V(!particles, Rect3());
- return particles->computed_aabb;
+ glBindBuffer(GL_ARRAY_BUFFER, particles->particle_buffers[0]);
+
+ float *data = (float *)glMapBufferRange(GL_ARRAY_BUFFER, 0, particles->amount * 16 * 6, GL_MAP_READ_BIT);
+ Rect3 aabb;
+
+ Transform inv = particles->emission_transform.affine_inverse();
+
+ for (int i = 0; i < particles->amount; i++) {
+ int ofs = i * 24;
+ Vector3 pos = Vector3(data[ofs + 15], data[ofs + 19], data[ofs + 23]);
+ if (!particles->use_local_coords) {
+ pos = inv.xform(pos);
+ }
+ if (i == 0)
+ aabb.pos = pos;
+ else
+ aabb.expand_to(pos);
+ }
+
+ glUnmapBuffer(GL_ARRAY_BUFFER);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ float longest_axis = 0;
+ for (int i = 0; i < particles->draw_passes.size(); i++) {
+ if (particles->draw_passes[i].is_valid()) {
+ Rect3 maabb = mesh_get_aabb(particles->draw_passes[i], RID());
+ longest_axis = MAX(maabb.get_longest_axis_size(), longest_axis);
+ }
+ }
+
+ aabb.grow_by(longest_axis);
+
+ return aabb;
}
Rect3 RasterizerStorageGLES3::particles_get_aabb(RID p_particles) const {
@@ -5009,7 +5102,7 @@ Rect3 RasterizerStorageGLES3::particles_get_aabb(RID p_particles) const {
const Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND_V(!particles, Rect3());
- return Rect3(Vector3(-1, -1, -1), Vector3(2, 2, 2));
+ return particles->custom_aabb;
}
void RasterizerStorageGLES3::particles_set_emission_transform(RID p_particles, const Transform &p_transform) {
@@ -5022,7 +5115,7 @@ void RasterizerStorageGLES3::particles_set_emission_transform(RID p_particles, c
void RasterizerStorageGLES3::_particles_process(Particles *particles, float p_delta) {
- float new_phase = Math::fmod((float)particles->phase + (p_delta / particles->lifetime), (float)1.0);
+ float new_phase = Math::fmod((float)particles->phase + (p_delta / particles->lifetime) * particles->speed_scale, (float)1.0);
if (particles->clear) {
particles->cycle_number = 0;
@@ -5034,7 +5127,7 @@ void RasterizerStorageGLES3::_particles_process(Particles *particles, float p_de
shaders.particles.set_uniform(ParticlesShaderGLES3::PREV_SYSTEM_PHASE, particles->phase);
particles->phase = new_phase;
- shaders.particles.set_uniform(ParticlesShaderGLES3::DELTA, p_delta);
+ shaders.particles.set_uniform(ParticlesShaderGLES3::DELTA, p_delta * particles->speed_scale);
shaders.particles.set_uniform(ParticlesShaderGLES3::CLEAR, particles->clear);
if (particles->use_local_coords)
shaders.particles.set_uniform(ParticlesShaderGLES3::EMISSION_TRANSFORM, Transform());
@@ -5154,7 +5247,6 @@ void RasterizerStorageGLES3::update_particles() {
shaders.particles.set_uniform(ParticlesShaderGLES3::TIME, Color(frame.time[0], frame.time[1], frame.time[2], frame.time[3]));
shaders.particles.set_uniform(ParticlesShaderGLES3::EXPLOSIVENESS, particles->explosiveness);
shaders.particles.set_uniform(ParticlesShaderGLES3::LIFETIME, particles->lifetime);
- shaders.particles.set_uniform(ParticlesShaderGLES3::GRAVITY, particles->gravity);
shaders.particles.set_uniform(ParticlesShaderGLES3::ATTRACTOR_COUNT, 0);
shaders.particles.set_uniform(ParticlesShaderGLES3::EMITTING, particles->emitting);
shaders.particles.set_uniform(ParticlesShaderGLES3::RANDOMNESS, particles->randomness);
@@ -5201,6 +5293,20 @@ void RasterizerStorageGLES3::update_particles() {
}
particle_update_list.remove(particle_update_list.first());
+
+ if (particles->histories_enabled) {
+
+ SWAP(particles->particle_buffer_histories[0], particles->particle_buffer_histories[1]);
+ SWAP(particles->particle_vao_histories[0], particles->particle_vao_histories[1]);
+ SWAP(particles->particle_valid_histories[0], particles->particle_valid_histories[1]);
+
+ //copy
+ glBindBuffer(GL_COPY_READ_BUFFER, particles->particle_buffers[0]);
+ glBindBuffer(GL_COPY_WRITE_BUFFER, particles->particle_buffer_histories[0]);
+ glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, particles->amount * 24 * sizeof(float));
+
+ particles->particle_valid_histories[0] = true;
+ }
}
glDisable(GL_RASTERIZER_DISCARD);
@@ -5427,8 +5533,8 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) {
glGenTextures(1, &rt->depth);
glBindTexture(GL_TEXTURE_2D, rt->depth);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, rt->width, rt->height, 0,
- GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, rt->width, rt->height, 0,
+ GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
@@ -6394,6 +6500,7 @@ void RasterizerStorageGLES3::initialize() {
frame.count = 0;
frame.prev_tick = 0;
frame.delta = 0;
+ frame.current_rt = NULL;
config.keep_original_textures = false;
}