Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make 2D particles work OOTB (again) #23702

Merged
merged 1 commit into from
Nov 14, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions drivers/gles3/rasterizer_canvas_gles3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -967,6 +967,7 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur
//enable instancing

state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_INSTANCE_CUSTOM, true);
state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_PARTICLES, true);
state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_INSTANCING, true);
//reset shader and force rebind
state.using_texture_rect = true;
Expand All @@ -977,6 +978,8 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur
if (texture) {
Size2 texpixel_size(1.0 / texture->width, 1.0 / texture->height);
state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size);
} else {
state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, Vector2(1.0, 1.0));
}

if (!particles->use_local_coords) {
Expand Down Expand Up @@ -1066,6 +1069,7 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur
glBindVertexArray(0);

state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_INSTANCE_CUSTOM, false);
state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_PARTICLES, false);
state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_INSTANCING, false);
state.using_texture_rect = true;
_set_texture_rect_mode(false);
Expand Down
5 changes: 5 additions & 0 deletions drivers/gles3/shaders/canvas.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,11 @@ void main() {
highp vec4 outvec = vec4(vertex, 0.0, 1.0);
#endif

#ifdef USE_PARTICLES
//scale by texture size
outvec.xy /= color_texpixel_size;
#endif

#define extra_matrix extra_matrix_instance

{
Expand Down
2 changes: 0 additions & 2 deletions scene/2d/canvas_item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,6 @@ void CanvasItemMaterial::_update_shader() {
code += "\tfloat h_frames = float(particles_anim_h_frames);\n";
code += "\tfloat v_frames = float(particles_anim_v_frames);\n";

code += "\tVERTEX.xy /= TEXTURE_PIXEL_SIZE * vec2(h_frames, v_frames);\n";

code += "\tint total_frames = particles_anim_h_frames * particles_anim_v_frames;\n";
code += "\tint frame = int(float(total_frames) * INSTANCE_CUSTOM.z);\n";
code += "\tif (particles_anim_loop) {\n";
Expand Down
28 changes: 19 additions & 9 deletions scene/2d/cpu_particles_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,13 +153,19 @@ CPUParticles2D::DrawOrder CPUParticles2D::get_draw_order() const {
return draw_order;
}

void CPUParticles2D::_generate_mesh_texture() {
void CPUParticles2D::_update_mesh_texture() {

Size2 tex_size;
if (texture.is_valid()) {
tex_size = texture->get_size();
} else {
tex_size = Size2(1, 1);
}
PoolVector<Vector2> vertices;
vertices.push_back(Vector2(-0.5, -0.5));
vertices.push_back(Vector2(0.5, -0.5));
vertices.push_back(Vector2(0.5, 0.5));
vertices.push_back(Vector2(-0.5, 0.5));
vertices.push_back(-tex_size * 0.5);
vertices.push_back(-tex_size * 0.5 + Vector2(tex_size.x, 0));
vertices.push_back(-tex_size * 0.5 + Vector2(tex_size.x, tex_size.y));
vertices.push_back(-tex_size * 0.5 + Vector2(0, tex_size.y));
PoolVector<Vector2> uvs;
uvs.push_back(Vector2(0, 0));
uvs.push_back(Vector2(1, 0));
Expand Down Expand Up @@ -193,6 +199,7 @@ void CPUParticles2D::set_texture(const Ref<Texture> &p_texture) {

texture = p_texture;
update();
_update_mesh_texture();
}

Ref<Texture> CPUParticles2D::get_texture() const {
Expand Down Expand Up @@ -234,9 +241,12 @@ String CPUParticles2D::get_configuration_warning() const {
CanvasItemMaterial *mat = Object::cast_to<CanvasItemMaterial>(get_material().ptr());

if (get_material().is_null() || (mat && !mat->get_particles_animation())) {
if (warnings != String())
warnings += "\n";
warnings += "- " + TTR("CPUParticles2D animation requires the usage of a CanvasItemMaterial with \"Particles Animation\" enabled.");
if (get_param(PARAM_ANIM_SPEED) != 0.0 || get_param(PARAM_ANIM_OFFSET) != 0.0 ||
get_param_curve(PARAM_ANIM_SPEED).is_valid() || get_param_curve(PARAM_ANIM_OFFSET).is_valid()) {
if (warnings != String())
warnings += "\n";
warnings += "- " + TTR("CPUParticles2D animation requires the usage of a CanvasItemMaterial with \"Particles Animation\" enabled.");
}
}

return warnings;
Expand Down Expand Up @@ -1396,7 +1406,7 @@ CPUParticles2D::CPUParticles2D() {
update_mutex = Mutex::create();
#endif

_generate_mesh_texture();
_update_mesh_texture();
}

CPUParticles2D::~CPUParticles2D() {
Expand Down
11 changes: 1 addition & 10 deletions scene/2d/cpu_particles_2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ class CPUParticles2D : public Node2D {

void _update_render_thread();

void _generate_mesh_texture();
void _update_mesh_texture();

protected:
static void _bind_methods();
Expand Down Expand Up @@ -222,15 +222,6 @@ class CPUParticles2D : public Node2D {
void set_texture(const Ref<Texture> &p_texture);
Ref<Texture> get_texture() const;

void set_h_frames(int p_frames);
int get_h_frames();

void set_v_frames(int p_frames);
int get_v_frames();

void set_loop_animation(bool p_loop);
bool get_loop_animation() const;

void set_normalmap(const Ref<Texture> &p_normalmap);
Ref<Texture> get_normalmap() const;

Expand Down
14 changes: 14 additions & 0 deletions scene/2d/particles_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,20 @@ String Particles2D::get_configuration_warning() const {
if (warnings != String())
warnings += "\n";
warnings += "- " + TTR("A material to process the particles is not assigned, so no behavior is imprinted.");
} else {

CanvasItemMaterial *mat = Object::cast_to<CanvasItemMaterial>(get_material().ptr());

if (get_material().is_null() || (mat && !mat->get_particles_animation())) {
const ParticlesMaterial *process = Object::cast_to<ParticlesMaterial>(process_material.ptr());
if (process &&
(process->get_param(ParticlesMaterial::PARAM_ANIM_SPEED) != 0.0 || process->get_param(ParticlesMaterial::PARAM_ANIM_OFFSET) != 0.0 ||
process->get_param_texture(ParticlesMaterial::PARAM_ANIM_SPEED).is_valid() || process->get_param_texture(ParticlesMaterial::PARAM_ANIM_OFFSET).is_valid())) {
if (warnings != String())
warnings += "\n";
warnings += "- " + TTR("Particles2D animation requires the usage of a CanvasItemMaterial with \"Particles Animation\" enabled.");
}
}
}

return warnings;
Expand Down
29 changes: 29 additions & 0 deletions scene/3d/cpu_particles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,35 @@ String CPUParticles::get_configuration_warning() const {

String warnings;

bool mesh_found = false;
bool anim_material_found = false;

if (get_mesh().is_valid()) {
mesh_found = true;
for (int j = 0; j < get_mesh()->get_surface_count(); j++) {
anim_material_found = Object::cast_to<ShaderMaterial>(get_mesh()->surface_get_material(j).ptr()) != NULL;
SpatialMaterial *spat = Object::cast_to<SpatialMaterial>(get_mesh()->surface_get_material(j).ptr());
anim_material_found = anim_material_found || (spat && spat->get_billboard_mode() == SpatialMaterial::BILLBOARD_PARTICLES);
}
}

anim_material_found = anim_material_found || Object::cast_to<ShaderMaterial>(get_material_override().ptr()) != NULL;
SpatialMaterial *spat = Object::cast_to<SpatialMaterial>(get_material_override().ptr());
anim_material_found = anim_material_found || (spat && spat->get_billboard_mode() == SpatialMaterial::BILLBOARD_PARTICLES);

if (!mesh_found) {
if (warnings != String())
warnings += "\n";
warnings += "- " + TTR("Nothing is visible because no mesh has not been assigned.");
}

if (!anim_material_found && (get_param(PARAM_ANIM_SPEED) != 0.0 || get_param(PARAM_ANIM_OFFSET) != 0.0 ||
get_param_curve(PARAM_ANIM_SPEED).is_valid() || get_param_curve(PARAM_ANIM_OFFSET).is_valid())) {
if (warnings != String())
warnings += "\n";
warnings += "- " + TTR("CPUParticles animation requires the usage of a SpatialMaterial with \"Billboard Particles\" enabled.");
}

return warnings;
}

Expand Down
24 changes: 23 additions & 1 deletion scene/3d/particles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
/*************************************************************************/

#include "particles.h"
#include "scene/resources/particles_material.h"

#include "servers/visual_server.h"

Expand Down Expand Up @@ -226,22 +227,43 @@ String Particles::get_configuration_warning() const {
String warnings;

bool meshes_found = false;
bool anim_material_found = false;

for (int i = 0; i < draw_passes.size(); i++) {
if (draw_passes[i].is_valid()) {
meshes_found = true;
break;
for (int j = 0; j < draw_passes[i]->get_surface_count(); j++) {
anim_material_found = Object::cast_to<ShaderMaterial>(draw_passes[i]->surface_get_material(j).ptr()) != NULL;
SpatialMaterial *spat = Object::cast_to<SpatialMaterial>(draw_passes[i]->surface_get_material(j).ptr());
anim_material_found = anim_material_found || (spat && spat->get_billboard_mode() == SpatialMaterial::BILLBOARD_PARTICLES);
}
if (meshes_found && anim_material_found) break;
}
}

anim_material_found = anim_material_found || Object::cast_to<ShaderMaterial>(get_material_override().ptr()) != NULL;
SpatialMaterial *spat = Object::cast_to<SpatialMaterial>(get_material_override().ptr());
anim_material_found = anim_material_found || (spat && spat->get_billboard_mode() == SpatialMaterial::BILLBOARD_PARTICLES);

if (!meshes_found) {
if (warnings != String())
warnings += "\n";
warnings += "- " + TTR("Nothing is visible because meshes have not been assigned to draw passes.");
}

if (process_material.is_null()) {
if (warnings != String())
warnings += "\n";
warnings += "- " + TTR("A material to process the particles is not assigned, so no behavior is imprinted.");
} else {
const ParticlesMaterial *process = Object::cast_to<ParticlesMaterial>(process_material.ptr());
if (!anim_material_found && process &&
(process->get_param(ParticlesMaterial::PARAM_ANIM_SPEED) != 0.0 || process->get_param(ParticlesMaterial::PARAM_ANIM_OFFSET) != 0.0 ||
process->get_param_texture(ParticlesMaterial::PARAM_ANIM_SPEED).is_valid() || process->get_param_texture(ParticlesMaterial::PARAM_ANIM_OFFSET).is_valid())) {
if (warnings != String())
warnings += "\n";
warnings += "- " + TTR("Particles animation requires the usage of a SpatialMaterial with \"Billboard Particles\" enabled.");
}
}

return warnings;
Expand Down