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.cpp116
1 files changed, 110 insertions, 6 deletions
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index a38e149aff..24a57b772b 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -1072,6 +1072,14 @@ void RasterizerStorageGLES3::texture_set_detect_srgb_callback(RID p_texture, Vis
texture->detect_srgb_ud = p_userdata;
}
+void RasterizerStorageGLES3::texture_set_detect_normal_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata) {
+ Texture *texture = texture_owner.get(p_texture);
+ ERR_FAIL_COND(!texture);
+
+ texture->detect_normal = p_callback;
+ texture->detect_normal_ud = p_userdata;
+}
+
RID RasterizerStorageGLES3::texture_create_radiance_cubemap(RID p_source, int p_resolution) const {
Texture *texture = texture_owner.get(p_source);
@@ -1548,7 +1556,11 @@ void RasterizerStorageGLES3::shader_get_param_list(RID p_shader, List<PropertyIn
for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = shader->uniforms.front(); E; E = E->next()) {
- order[E->get().order] = E->key();
+ if (E->get().texture_order >= 0) {
+ order[E->get().texture_order + 100000] = E->key();
+ } else {
+ order[E->get().order] = E->key();
+ }
}
for (Map<int, StringName>::Element *E = order.front(); E; E = E->next()) {
@@ -2314,6 +2326,9 @@ void RasterizerStorageGLES3::_update_material(Material *material) {
if (E->get().order < 0)
continue; // texture, does not go here
+ //if (material->shader->mode == VS::SHADER_PARTICLES) {
+ // print_line("uniform " + String(E->key()) + " order " + itos(E->get().order) + " offset " + itos(material->shader->ubo_offsets[E->get().order]));
+ //}
//regular uniform
uint8_t *data = &local_ubo[material->shader->ubo_offsets[E->get().order]];
@@ -3107,6 +3122,7 @@ void RasterizerStorageGLES3::mesh_remove_surface(RID p_mesh, int p_surface) {
}
glDeleteVertexArrays(1, &surface->array_id);
+ glDeleteVertexArrays(1, &surface->instancing_array_id);
for (int i = 0; i < surface->blend_shapes.size(); i++) {
@@ -5052,6 +5068,14 @@ void RasterizerStorageGLES3::particles_set_lifetime(RID p_particles, float p_lif
ERR_FAIL_COND(!particles);
particles->lifetime = p_lifetime;
}
+
+void RasterizerStorageGLES3::particles_set_one_shot(RID p_particles, bool p_one_shot) {
+
+ Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND(!particles);
+ particles->one_shot = p_one_shot;
+}
+
void RasterizerStorageGLES3::particles_set_pre_process_time(RID p_particles, float p_time) {
Particles *particles = particles_owner.getornull(p_particles);
@@ -5183,6 +5207,14 @@ void RasterizerStorageGLES3::particles_set_draw_pass_mesh(RID p_particles, int p
particles->draw_passes[p_pass] = p_mesh;
}
+void RasterizerStorageGLES3::particles_restart(RID p_particles) {
+
+ Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND(!particles);
+
+ particles->restart_request = true;
+}
+
void RasterizerStorageGLES3::particles_request_process(RID p_particles) {
Particles *particles = particles_owner.getornull(p_particles);
@@ -5249,13 +5281,35 @@ void RasterizerStorageGLES3::particles_set_emission_transform(RID p_particles, c
particles->emission_transform = p_transform;
}
+int RasterizerStorageGLES3::particles_get_draw_passes(RID p_particles) const {
+
+ const Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND_V(!particles, 0);
+
+ return particles->draw_passes.size();
+}
+
+RID RasterizerStorageGLES3::particles_get_draw_pass_mesh(RID p_particles, int p_pass) const {
+
+ const Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND_V(!particles, RID());
+ ERR_FAIL_INDEX_V(p_pass, particles->draw_passes.size(), RID());
+
+ return particles->draw_passes[p_pass];
+}
+
void RasterizerStorageGLES3::_particles_process(Particles *particles, float p_delta) {
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;
+ particles->random_seed = Math::rand();
} else if (new_phase < particles->phase) {
+ if (particles->one_shot) {
+ particles->emitting = false;
+ shaders.particles.set_uniform(ParticlesShaderGLES3::EMITTING, false);
+ }
particles->cycle_number++;
}
@@ -5265,6 +5319,8 @@ void RasterizerStorageGLES3::_particles_process(Particles *particles, float p_de
shaders.particles.set_uniform(ParticlesShaderGLES3::DELTA, p_delta * particles->speed_scale);
shaders.particles.set_uniform(ParticlesShaderGLES3::CLEAR, particles->clear);
+ glUniform1ui(shaders.particles.get_uniform_location(ParticlesShaderGLES3::RANDOM_SEED), particles->random_seed);
+
if (particles->use_local_coords)
shaders.particles.set_uniform(ParticlesShaderGLES3::EMISSION_TRANSFORM, Transform());
else
@@ -5320,6 +5376,44 @@ void RasterizerStorageGLES3::update_particles() {
Particles *particles = particle_update_list.first()->self();
+ if (particles->restart_request) {
+ particles->emitting = true; //restart from zero
+ particles->prev_ticks = 0;
+ particles->phase = 0;
+ particles->prev_phase = 0;
+ particles->clear = true;
+ particles->particle_valid_histories[0] = false;
+ particles->particle_valid_histories[1] = false;
+ particles->restart_request = false;
+ }
+
+ if (particles->inactive && !particles->emitting) {
+
+ particle_update_list.remove(particle_update_list.first());
+ continue;
+ }
+
+ if (particles->emitting) {
+ if (particles->inactive) {
+ //restart system from scratch
+ particles->prev_ticks = 0;
+ particles->phase = 0;
+ particles->prev_phase = 0;
+ particles->clear = true;
+ particles->particle_valid_histories[0] = false;
+ particles->particle_valid_histories[1] = false;
+ }
+ particles->inactive = false;
+ particles->inactive_time = 0;
+ } else {
+ particles->inactive_time += particles->speed_scale * frame.delta;
+ if (particles->inactive_time > particles->lifetime * 1.2) {
+ particles->inactive = true;
+ particle_update_list.remove(particle_update_list.first());
+ continue;
+ }
+ }
+
Material *material = material_owner.getornull(particles->process_material);
if (!material || !material->shader || material->shader->mode != VS::SHADER_PARTICLES) {
@@ -5380,7 +5474,7 @@ void RasterizerStorageGLES3::update_particles() {
shaders.particles.bind();
shaders.particles.set_uniform(ParticlesShaderGLES3::TOTAL_PARTICLES, particles->amount);
- shaders.particles.set_uniform(ParticlesShaderGLES3::TIME, Color(frame.time[0], frame.time[1], frame.time[2], frame.time[3]));
+ shaders.particles.set_uniform(ParticlesShaderGLES3::TIME, frame.time[0]);
shaders.particles.set_uniform(ParticlesShaderGLES3::EXPLOSIVENESS, particles->explosiveness);
shaders.particles.set_uniform(ParticlesShaderGLES3::LIFETIME, particles->lifetime);
shaders.particles.set_uniform(ParticlesShaderGLES3::ATTRACTOR_COUNT, 0);
@@ -5443,11 +5537,11 @@ void RasterizerStorageGLES3::update_particles() {
particles->particle_valid_histories[0] = true;
}
+
+ particles->instance_change_notify(); //make sure shadows are updated
}
glDisable(GL_RASTERIZER_DISCARD);
-
-
}
////////
@@ -6034,10 +6128,20 @@ void RasterizerStorageGLES3::render_target_set_flag(RID p_render_target, RenderT
default: {}
}
}
+bool RasterizerStorageGLES3::render_target_was_used(RID p_render_target) {
-bool RasterizerStorageGLES3::render_target_renedered_in_frame(RID p_render_target) {
+ RenderTarget *rt = render_target_owner.getornull(p_render_target);
+ ERR_FAIL_COND_V(!rt, false);
- return false;
+ return rt->used_in_frame;
+}
+
+void RasterizerStorageGLES3::render_target_clear_used(RID p_render_target) {
+
+ RenderTarget *rt = render_target_owner.getornull(p_render_target);
+ ERR_FAIL_COND(!rt);
+
+ rt->used_in_frame = false;
}
void RasterizerStorageGLES3::render_target_set_msaa(RID p_render_target, VS::ViewportMSAA p_msaa) {