mirror of
https://github.com/godotengine/godot.git
synced 2024-11-14 16:13:08 +00:00
Make 2D particles work OOTB (again)
This commit is contained in:
parent
7f347cc31a
commit
cbfb7bd613
@ -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;
|
||||
@ -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) {
|
||||
@ -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);
|
||||
|
@ -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
|
||||
|
||||
{
|
||||
|
@ -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";
|
||||
|
@ -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));
|
||||
@ -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 {
|
||||
@ -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;
|
||||
@ -1396,7 +1406,7 @@ CPUParticles2D::CPUParticles2D() {
|
||||
update_mutex = Mutex::create();
|
||||
#endif
|
||||
|
||||
_generate_mesh_texture();
|
||||
_update_mesh_texture();
|
||||
}
|
||||
|
||||
CPUParticles2D::~CPUParticles2D() {
|
||||
|
@ -177,7 +177,7 @@ private:
|
||||
|
||||
void _update_render_thread();
|
||||
|
||||
void _generate_mesh_texture();
|
||||
void _update_mesh_texture();
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
@ -222,15 +222,6 @@ public:
|
||||
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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@
|
||||
/*************************************************************************/
|
||||
|
||||
#include "particles.h"
|
||||
#include "scene/resources/particles_material.h"
|
||||
|
||||
#include "servers/visual_server.h"
|
||||
|
||||
@ -226,15 +227,27 @@ 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.");
|
||||
}
|
||||
|
||||
@ -242,6 +255,15 @@ String Particles::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 {
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user