summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gles3/rasterizer_gles3.cpp56
-rw-r--r--drivers/gles3/rasterizer_gles3.h2
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp164
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.h2
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp123
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.h22
-rw-r--r--drivers/gles3/shaders/particles.glsl17
-rw-r--r--drivers/unix/os_unix.h2
8 files changed, 347 insertions, 41 deletions
diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp
index a7349695db..4214ee5a6d 100644
--- a/drivers/gles3/rasterizer_gles3.cpp
+++ b/drivers/gles3/rasterizer_gles3.cpp
@@ -271,6 +271,62 @@ void RasterizerGLES3::clear_render_target(const Color &p_color) {
storage->frame.clear_request_color = p_color;
}
+void RasterizerGLES3::set_boot_image(const Image &p_image, const Color &p_color, bool p_scale) {
+
+ if (p_image.empty())
+ return;
+
+ begin_frame();
+
+ int window_w = OS::get_singleton()->get_video_mode(0).width;
+ int window_h = OS::get_singleton()->get_video_mode(0).height;
+
+ glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES3::system_fbo);
+ glViewport(0, 0, window_w, window_h);
+ glDisable(GL_BLEND);
+ glDepthMask(GL_FALSE);
+ glClearColor(p_color.r, p_color.g, p_color.b, 1.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+ canvas->canvas_begin();
+
+ RID texture = storage->texture_create();
+ storage->texture_allocate(texture, p_image.get_width(), p_image.get_height(), p_image.get_format(), VS::TEXTURE_FLAG_FILTER);
+ storage->texture_set_data(texture, p_image);
+
+ Rect2 imgrect(0, 0, p_image.get_width(), p_image.get_height());
+ Rect2 screenrect;
+ if (p_scale) {
+
+ if (window_w > window_h) {
+ //scale horizontally
+ screenrect.size.y = window_h;
+ screenrect.size.x = imgrect.size.x * window_h / imgrect.size.y;
+ screenrect.pos.x = (window_w - screenrect.size.x) / 2;
+
+ } else {
+ //scale vertically
+ screenrect.size.x = window_w;
+ screenrect.size.y = imgrect.size.y * window_w / imgrect.size.x;
+ screenrect.pos.y = (window_h - screenrect.size.y) / 2;
+ }
+ } else {
+
+ screenrect = imgrect;
+ screenrect.pos += ((Size2(window_w, window_h) - screenrect.size) / 2.0).floor();
+ }
+
+ RasterizerStorageGLES3::Texture *t = storage->texture_owner.get(texture);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, t->tex_id);
+ canvas->draw_generic_textured_rect(screenrect, Rect2(0, 0, 1, 1));
+ glBindTexture(GL_TEXTURE_2D, 0);
+ canvas->canvas_end();
+
+ storage->free(texture); // free since it's only one frame that stays there
+
+ OS::get_singleton()->swap_buffers();
+}
+
void RasterizerGLES3::blit_render_target_to_screen(RID p_render_target, const Rect2 &p_screen_rect, int p_screen) {
ERR_FAIL_COND(storage->frame.current_rt);
diff --git a/drivers/gles3/rasterizer_gles3.h b/drivers/gles3/rasterizer_gles3.h
index ba3715b805..12014cd814 100644
--- a/drivers/gles3/rasterizer_gles3.h
+++ b/drivers/gles3/rasterizer_gles3.h
@@ -48,6 +48,8 @@ public:
virtual RasterizerCanvas *get_canvas();
virtual RasterizerScene *get_scene();
+ virtual void set_boot_image(const Image &p_image, const Color &p_color, bool p_scale);
+
virtual void initialize();
virtual void begin_frame();
virtual void set_current_render_target(RID p_render_target);
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index 0e97e2d459..9cb44349bf 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -1216,7 +1216,26 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material *p_m
return rebind;
}
-void RasterizerSceneGLES3::_setup_geometry(RenderList::Element *e) {
+struct RasterizerGLES3Particle {
+
+ float color[4];
+ float velocity_active[4];
+ float custom[4];
+ float xform_1[4];
+ float xform_2[4];
+ float xform_3[4];
+};
+
+struct RasterizerGLES3ParticleSort {
+
+ Vector3 z_dir;
+ bool operator()(const RasterizerGLES3Particle &p_a, const RasterizerGLES3Particle &p_b) const {
+
+ return z_dir.dot(Vector3(p_a.xform_1[3], p_a.xform_2[3], p_a.xform_3[3])) < z_dir.dot(Vector3(p_b.xform_1[3], p_b.xform_2[3], p_b.xform_3[3]));
+ }
+};
+
+void RasterizerSceneGLES3::_setup_geometry(RenderList::Element *e, const Transform &p_view_transform) {
switch (e->instance->base_type) {
@@ -1289,28 +1308,54 @@ void RasterizerSceneGLES3::_setup_geometry(RenderList::Element *e) {
RasterizerStorageGLES3::Particles *particles = static_cast<RasterizerStorageGLES3::Particles *>(e->owner);
RasterizerStorageGLES3::Surface *s = static_cast<RasterizerStorageGLES3::Surface *>(e->geometry);
- glBindVertexArray(s->instancing_array_id); // use the instancing array ID
- glBindBuffer(GL_ARRAY_BUFFER, particles->particle_buffers[0]); //modify the buffer
+ if (particles->draw_order == VS::PARTICLES_DRAW_ORDER_VIEW_DEPTH && particles->particle_valid_histories[1]) {
+
+ glBindBuffer(GL_ARRAY_BUFFER, particles->particle_buffer_histories[1]); //modify the buffer, this was used 2 frames ago so it should be good enough for flushing
+ RasterizerGLES3Particle *particle_array = (RasterizerGLES3Particle *)glMapBufferRange(GL_ARRAY_BUFFER, 0, particles->amount * 24 * sizeof(float), GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);
+
+ SortArray<RasterizerGLES3Particle, RasterizerGLES3ParticleSort> sorter;
+
+ if (particles->use_local_coords) {
+ sorter.compare.z_dir = e->instance->transform.affine_inverse().xform(p_view_transform.basis.get_axis(2)).normalized();
+ } else {
+ sorter.compare.z_dir = p_view_transform.basis.get_axis(2).normalized();
+ }
+
+ sorter.sort(particle_array, particles->amount);
+
+ glUnmapBuffer(GL_ARRAY_BUFFER);
+
+ glBindVertexArray(s->instancing_array_id); // use the instancing array ID
+ glBindBuffer(GL_ARRAY_BUFFER, particles->particle_buffer_histories[1]); //modify the buffer
+
+ } else {
+
+ glBindVertexArray(s->instancing_array_id); // use the instancing array ID
+ glBindBuffer(GL_ARRAY_BUFFER, particles->particle_buffers[0]); //modify the buffer
+ }
int stride = sizeof(float) * 4 * 6;
//transform
- glEnableVertexAttribArray(8); //xform x
- glVertexAttribPointer(8, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + sizeof(float) * 4 * 3);
- glVertexAttribDivisor(8, 1);
- glEnableVertexAttribArray(9); //xform y
- glVertexAttribPointer(9, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + sizeof(float) * 4 * 4);
- glVertexAttribDivisor(9, 1);
- glEnableVertexAttribArray(10); //xform z
- glVertexAttribPointer(10, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + sizeof(float) * 4 * 5);
- glVertexAttribDivisor(10, 1);
- glEnableVertexAttribArray(11); //color
- glVertexAttribPointer(11, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + 0);
- glVertexAttribDivisor(11, 1);
- glEnableVertexAttribArray(12); //custom
- glVertexAttribPointer(12, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + sizeof(float) * 4 * 2);
- glVertexAttribDivisor(12, 1);
+ if (particles->draw_order != VS::PARTICLES_DRAW_ORDER_LIFETIME) {
+
+ glEnableVertexAttribArray(8); //xform x
+ glVertexAttribPointer(8, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + sizeof(float) * 4 * 3);
+ glVertexAttribDivisor(8, 1);
+ glEnableVertexAttribArray(9); //xform y
+ glVertexAttribPointer(9, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + sizeof(float) * 4 * 4);
+ glVertexAttribDivisor(9, 1);
+ glEnableVertexAttribArray(10); //xform z
+ glVertexAttribPointer(10, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + sizeof(float) * 4 * 5);
+ glVertexAttribDivisor(10, 1);
+ glEnableVertexAttribArray(11); //color
+ glVertexAttribPointer(11, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + 0);
+ glVertexAttribDivisor(11, 1);
+ glEnableVertexAttribArray(12); //custom
+ glVertexAttribPointer(12, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + sizeof(float) * 4 * 2);
+ glVertexAttribDivisor(12, 1);
+ }
} break;
}
@@ -1491,17 +1536,88 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) {
int amount = particles->amount;
- if (s->index_array_len > 0) {
+ if (particles->draw_order == VS::PARTICLES_DRAW_ORDER_LIFETIME) {
+ //split
+
+ int stride = sizeof(float) * 4 * 6;
+ int split = int(Math::ceil(particles->phase * particles->amount));
+
+ if (amount - split > 0) {
+ glEnableVertexAttribArray(8); //xform x
+ glVertexAttribPointer(8, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + stride * split + sizeof(float) * 4 * 3);
+ glVertexAttribDivisor(8, 1);
+ glEnableVertexAttribArray(9); //xform y
+ glVertexAttribPointer(9, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + stride * split + sizeof(float) * 4 * 4);
+ glVertexAttribDivisor(9, 1);
+ glEnableVertexAttribArray(10); //xform z
+ glVertexAttribPointer(10, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + stride * split + sizeof(float) * 4 * 5);
+ glVertexAttribDivisor(10, 1);
+ glEnableVertexAttribArray(11); //color
+ glVertexAttribPointer(11, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + stride * split + 0);
+ glVertexAttribDivisor(11, 1);
+ glEnableVertexAttribArray(12); //custom
+ glVertexAttribPointer(12, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + stride * split + sizeof(float) * 4 * 2);
+ glVertexAttribDivisor(12, 1);
- glDrawElementsInstanced(gl_primitive[s->primitive], s->index_array_len, (s->array_len >= (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0, amount);
+ if (s->index_array_len > 0) {
- storage->info.render_vertices_count += s->index_array_len * amount;
+ glDrawElementsInstanced(gl_primitive[s->primitive], s->index_array_len, (s->array_len >= (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0, amount - split);
+
+ storage->info.render_vertices_count += s->index_array_len * (amount - split);
+
+ } else {
+
+ glDrawArraysInstanced(gl_primitive[s->primitive], 0, s->array_len, amount - split);
+
+ storage->info.render_vertices_count += s->array_len * (amount - split);
+ }
+ }
+
+ if (split > 0) {
+ glEnableVertexAttribArray(8); //xform x
+ glVertexAttribPointer(8, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + sizeof(float) * 4 * 3);
+ glVertexAttribDivisor(8, 1);
+ glEnableVertexAttribArray(9); //xform y
+ glVertexAttribPointer(9, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + sizeof(float) * 4 * 4);
+ glVertexAttribDivisor(9, 1);
+ glEnableVertexAttribArray(10); //xform z
+ glVertexAttribPointer(10, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + sizeof(float) * 4 * 5);
+ glVertexAttribDivisor(10, 1);
+ glEnableVertexAttribArray(11); //color
+ glVertexAttribPointer(11, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + 0);
+ glVertexAttribDivisor(11, 1);
+ glEnableVertexAttribArray(12); //custom
+ glVertexAttribPointer(12, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + sizeof(float) * 4 * 2);
+ glVertexAttribDivisor(12, 1);
+
+ if (s->index_array_len > 0) {
+
+ glDrawElementsInstanced(gl_primitive[s->primitive], s->index_array_len, (s->array_len >= (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0, split);
+
+ storage->info.render_vertices_count += s->index_array_len * split;
+
+ } else {
+
+ glDrawArraysInstanced(gl_primitive[s->primitive], 0, s->array_len, split);
+
+ storage->info.render_vertices_count += s->array_len * split;
+ }
+ }
} else {
- glDrawArraysInstanced(gl_primitive[s->primitive], 0, s->array_len, amount);
+ if (s->index_array_len > 0) {
- storage->info.render_vertices_count += s->array_len * amount;
+ glDrawElementsInstanced(gl_primitive[s->primitive], s->index_array_len, (s->array_len >= (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0, amount);
+
+ storage->info.render_vertices_count += s->index_array_len * amount;
+
+ } else {
+
+ glDrawArraysInstanced(gl_primitive[s->primitive], 0, s->array_len, amount);
+
+ storage->info.render_vertices_count += s->array_len * amount;
+ }
}
} break;
@@ -1841,7 +1957,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
if (e->owner != prev_owner || prev_base_type != e->instance->base_type || prev_geometry != e->geometry) {
- _setup_geometry(e);
+ _setup_geometry(e, p_view_transform);
storage->info.render_surface_switch_count++;
}
diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h
index 10136ff8d7..33698fc267 100644
--- a/drivers/gles3/rasterizer_scene_gles3.h
+++ b/drivers/gles3/rasterizer_scene_gles3.h
@@ -692,7 +692,7 @@ public:
_FORCE_INLINE_ void _set_cull(bool p_front, bool p_reverse_cull);
_FORCE_INLINE_ bool _setup_material(RasterizerStorageGLES3::Material *p_material, bool p_alpha_pass);
- _FORCE_INLINE_ void _setup_geometry(RenderList::Element *e);
+ _FORCE_INLINE_ void _setup_geometry(RenderList::Element *e, const Transform &p_view_transform);
_FORCE_INLINE_ void _render_geometry(RenderList::Element *e);
_FORCE_INLINE_ void _setup_light(RenderList::Element *e, const Transform &p_view_transform);
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index 7fc2185e9a..beed923a58 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,7 +5533,7 @@ 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,
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, rt->width, rt->height, 0,
GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
@@ -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;
}
diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h
index 6ae9fd18a2..bb4a7e23a1 100644
--- a/drivers/gles3/rasterizer_storage_gles3.h
+++ b/drivers/gles3/rasterizer_storage_gles3.h
@@ -995,7 +995,6 @@ public:
float explosiveness;
float randomness;
Rect3 custom_aabb;
- Vector3 gravity;
bool use_local_coords;
RID process_material;
@@ -1003,11 +1002,14 @@ public:
Vector<RID> draw_passes;
- Rect3 computed_aabb;
-
GLuint particle_buffers[2];
GLuint particle_vaos[2];
+ GLuint particle_buffer_histories[2];
+ GLuint particle_vao_histories[2];
+ bool particle_valid_histories[2];
+ bool histories_enabled;
+
SelfList<Particles> particle_element;
float phase;
@@ -1016,6 +1018,8 @@ public:
uint32_t cycle_number;
+ float speed_scale;
+
int fixed_fps;
bool fractional_delta;
float frame_remainder;
@@ -1037,6 +1041,10 @@ public:
fixed_fps = 0;
fractional_delta = false;
frame_remainder = 0;
+ histories_enabled = false;
+ speed_scale = 1.0;
+
+ custom_aabb = Rect3(Vector3(-4, -4, -4), Vector3(8, 8, 8));
draw_order = VS::PARTICLES_DRAW_ORDER_INDEX;
particle_buffers[0] = 0;
@@ -1054,6 +1062,10 @@ public:
glDeleteBuffers(2, particle_buffers);
glDeleteVertexArrays(2, particle_vaos);
+ if (histories_enabled) {
+ glDeleteBuffers(2, particle_buffer_histories);
+ glDeleteVertexArrays(2, particle_vao_histories);
+ }
}
};
@@ -1072,7 +1084,7 @@ public:
virtual void particles_set_explosiveness_ratio(RID p_particles, float p_ratio);
virtual void particles_set_randomness_ratio(RID p_particles, float p_ratio);
virtual void particles_set_custom_aabb(RID p_particles, const Rect3 &p_aabb);
- virtual void particles_set_gravity(RID p_particles, const Vector3 &p_gravity);
+ virtual void particles_set_speed_scale(RID p_particles, float p_scale);
virtual void particles_set_use_local_coordinates(RID p_particles, bool p_enable);
virtual void particles_set_process_material(RID p_particles, RID p_material);
virtual void particles_set_fixed_fps(RID p_particles, int p_fps);
@@ -1087,6 +1099,8 @@ public:
virtual Rect3 particles_get_current_aabb(RID p_particles);
virtual Rect3 particles_get_aabb(RID p_particles) const;
+ virtual void _particles_update_histories(Particles *particles);
+
virtual void particles_set_emission_transform(RID p_particles, const Transform &p_transform);
void _particles_process(Particles *p_particles, float p_delta);
diff --git a/drivers/gles3/shaders/particles.glsl b/drivers/gles3/shaders/particles.glsl
index 347b15d639..f789be24cf 100644
--- a/drivers/gles3/shaders/particles.glsl
+++ b/drivers/gles3/shaders/particles.glsl
@@ -30,7 +30,7 @@ uniform float explosiveness;
uniform float randomness;
uniform vec4 time;
uniform float delta;
-uniform vec3 gravity;
+
uniform int attractor_count;
uniform Attractor attractors[MAX_ATTRACTORS];
uniform bool clear;
@@ -69,9 +69,19 @@ uint hash(uint x) {
void main() {
+#ifdef PARTICLES_COPY
+
+ out_color=color;
+ out_velocity_active=velocity_active;
+ out_custom = custom;
+ out_xform_1 = xform_1;
+ out_xform_2 = xform_2;
+ out_xform_3 = xform_3;
+
+#else
+
bool apply_forces=true;
bool apply_velocity=true;
- vec3 current_gravity = gravity;
float local_delta=delta;
float mass = 1.0;
@@ -164,7 +174,7 @@ VERTEX_SHADER_CODE
if (true) {
- vec3 force = current_gravity;
+ vec3 force = vec3(0.0);
for(int i=0;i<attractor_count;i++) {
vec3 rel_vec = xform[3].xyz - attractors[i].pos;
@@ -211,6 +221,7 @@ VERTEX_SHADER_CODE
out_xform_2 = xform[1];
out_xform_3 = xform[2];
+#endif //PARTICLES_COPY
}
diff --git a/drivers/unix/os_unix.h b/drivers/unix/os_unix.h
index 206559ab3d..67eb5cefdf 100644
--- a/drivers/unix/os_unix.h
+++ b/drivers/unix/os_unix.h
@@ -76,7 +76,7 @@ public:
//virtual void set_mouse_show(bool p_show);
//virtual void set_mouse_grab(bool p_grab);
//virtual bool is_mouse_grab_enabled() const = 0;
- //virtual void get_mouse_pos(int &x, int &y) const;
+ //virtual void get_mouse_position(int &x, int &y) const;
//virtual void set_window_title(const String& p_title);
//virtual void set_video_mode(const VideoMode& p_video_mode);