41
41
#include " storage/config.h"
42
42
#include " storage/material_storage.h"
43
43
#include " storage/mesh_storage.h"
44
+ #include " storage/particles_storage.h"
44
45
#include " storage/texture_storage.h"
45
46
46
47
void RasterizerCanvasGLES3::_update_transform_2d_to_mat4 (const Transform2D &p_transform, float *p_mat4) {
@@ -578,7 +579,7 @@ void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_cou
578
579
579
580
GLES3::CanvasShaderData::BlendMode blend_mode = shader_data_cache ? shader_data_cache->blend_mode : GLES3::CanvasShaderData::BLEND_MODE_MIX;
580
581
581
- _record_item_commands (ci, p_canvas_transform_inverse, current_clip, blend_mode, p_lights, index , batch_broken);
582
+ _record_item_commands (ci, p_to_render_target, p_canvas_transform_inverse, current_clip, blend_mode, p_lights, index , batch_broken);
582
583
}
583
584
584
585
if (index == 0 ) {
@@ -623,7 +624,10 @@ void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_cou
623
624
uint64_t specialization = 0 ;
624
625
specialization |= uint64_t (state.canvas_instance_batches [i].lights_disabled );
625
626
specialization |= uint64_t (!GLES3::Config::get_singleton ()->float_texture_supported ) << 1 ;
626
- _bind_material (material_data, variant, specialization);
627
+ bool success = _bind_material (material_data, variant, specialization);
628
+ if (!success) {
629
+ continue ;
630
+ }
627
631
628
632
GLES3::CanvasShaderData::BlendMode blend_mode = state.canvas_instance_batches [i].blend_mode ;
629
633
@@ -707,7 +711,7 @@ void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_cou
707
711
r_last_index += index ;
708
712
}
709
713
710
- void RasterizerCanvasGLES3::_record_item_commands (const Item *p_item, const Transform2D &p_canvas_transform_inverse, Item *¤t_clip, GLES3::CanvasShaderData::BlendMode p_blend_mode, Light *p_lights, uint32_t &r_index, bool &r_batch_broken) {
714
+ void RasterizerCanvasGLES3::_record_item_commands (const Item *p_item, RID p_render_target, const Transform2D &p_canvas_transform_inverse, Item *¤t_clip, GLES3::CanvasShaderData::BlendMode p_blend_mode, Light *p_lights, uint32_t &r_index, bool &r_batch_broken) {
711
715
RenderingServer::CanvasItemTextureFilter texture_filter = p_item->texture_filter == RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT ? state.default_filter : p_item->texture_filter ;
712
716
713
717
if (texture_filter != state.canvas_instance_batches [state.current_batch_index ].filter ) {
@@ -1064,15 +1068,45 @@ void RasterizerCanvasGLES3::_record_item_commands(const Item *p_item, const Tran
1064
1068
state.canvas_instance_batches [state.current_batch_index ].tex = m->texture ;
1065
1069
_update_transform_2d_to_mat2x3 (base_transform * draw_transform * m->transform , state.instance_data_array [r_index].world );
1066
1070
modulate = m->modulate ;
1071
+
1067
1072
} else if (c->type == Item::Command::TYPE_MULTIMESH) {
1068
1073
const Item::CommandMultiMesh *mm = static_cast <const Item::CommandMultiMesh *>(c);
1069
1074
state.canvas_instance_batches [state.current_batch_index ].tex = mm->texture ;
1070
- uint32_t instance_count = GLES3::MeshStorage::get_singleton ()->multimesh_get_instances_to_draw (mm->multimesh );
1071
- if (instance_count > 1 ) {
1072
- state.canvas_instance_batches [state.current_batch_index ].shader_variant = CanvasShaderGLES3::MODE_INSTANCED;
1073
- }
1075
+ state.canvas_instance_batches [state.current_batch_index ].shader_variant = CanvasShaderGLES3::MODE_INSTANCED;
1076
+
1074
1077
} else if (c->type == Item::Command::TYPE_PARTICLES) {
1075
- WARN_PRINT_ONCE (" Particles not supported yet, sorry :(" );
1078
+ GLES3::ParticlesStorage *particles_storage = GLES3::ParticlesStorage::get_singleton ();
1079
+ GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton ();
1080
+
1081
+ const Item::CommandParticles *pt = static_cast <const Item::CommandParticles *>(c);
1082
+ RID particles = pt->particles ;
1083
+ state.canvas_instance_batches [state.current_batch_index ].tex = pt->texture ;
1084
+ state.canvas_instance_batches [state.current_batch_index ].shader_variant = CanvasShaderGLES3::MODE_INSTANCED;
1085
+ bool local_coords = particles_storage->particles_is_using_local_coords (particles);
1086
+
1087
+ if (particles_storage->particles_has_collision (particles) && texture_storage->render_target_is_sdf_enabled (p_render_target)) {
1088
+ // Pass collision information.
1089
+ Transform2D xform;
1090
+ if (local_coords) {
1091
+ xform = p_item->final_transform ;
1092
+ } else {
1093
+ xform = p_canvas_transform_inverse;
1094
+ }
1095
+
1096
+ GLuint sdf_texture = texture_storage->render_target_get_sdf_texture (p_render_target);
1097
+
1098
+ Rect2 to_screen;
1099
+ {
1100
+ Rect2 sdf_rect = texture_storage->render_target_get_sdf_rect (p_render_target);
1101
+
1102
+ to_screen.size = Vector2 (1.0 / sdf_rect.size .width , 1.0 / sdf_rect.size .height );
1103
+ to_screen.position = -sdf_rect.position * to_screen.size ;
1104
+ }
1105
+
1106
+ particles_storage->particles_set_canvas_sdf_collision (pt->particles , true , xform, to_screen, sdf_texture);
1107
+ } else {
1108
+ particles_storage->particles_set_canvas_sdf_collision (pt->particles , false , Transform2D (), Rect2 (), 0 );
1109
+ }
1076
1110
}
1077
1111
1078
1112
state.canvas_instance_batches [state.current_batch_index ].command = c;
@@ -1209,20 +1243,21 @@ void RasterizerCanvasGLES3::_render_batch(Light *p_lights, uint32_t p_index) {
1209
1243
case Item::Command::TYPE_MULTIMESH:
1210
1244
case Item::Command::TYPE_PARTICLES: {
1211
1245
GLES3::MeshStorage *mesh_storage = GLES3::MeshStorage::get_singleton ();
1246
+ GLES3::ParticlesStorage *particles_storage = GLES3::ParticlesStorage::get_singleton ();
1212
1247
RID mesh;
1213
1248
RID mesh_instance;
1214
- RID texture;
1215
1249
uint32_t instance_count = 1 ;
1216
- GLuint multimesh_buffer = 0 ;
1217
- uint32_t multimesh_stride = 0 ;
1218
- uint32_t multimesh_color_offset = 0 ;
1219
- bool multimesh_uses_color = false ;
1220
- bool multimesh_uses_custom_data = false ;
1250
+ GLuint instance_buffer = 0 ;
1251
+ uint32_t instance_stride = 0 ;
1252
+ uint32_t instance_color_offset = 0 ;
1253
+ bool instance_uses_color = false ;
1254
+ bool instance_uses_custom_data = false ;
1221
1255
1222
1256
if (state.canvas_instance_batches [p_index].command_type == Item::Command::TYPE_MESH) {
1223
1257
const Item::CommandMesh *m = static_cast <const Item::CommandMesh *>(state.canvas_instance_batches [p_index].command );
1224
1258
mesh = m->mesh ;
1225
1259
mesh_instance = m->mesh_instance ;
1260
+
1226
1261
} else if (state.canvas_instance_batches [p_index].command_type == Item::Command::TYPE_MULTIMESH) {
1227
1262
const Item::CommandMultiMesh *mm = static_cast <const Item::CommandMultiMesh *>(state.canvas_instance_batches [p_index].command );
1228
1263
RID multimesh = mm->multimesh ;
@@ -1238,13 +1273,41 @@ void RasterizerCanvasGLES3::_render_batch(Light *p_lights, uint32_t p_index) {
1238
1273
break ;
1239
1274
}
1240
1275
1241
- multimesh_buffer = mesh_storage->multimesh_get_gl_buffer (multimesh);
1242
- multimesh_stride = mesh_storage->multimesh_get_stride (multimesh);
1243
- multimesh_color_offset = mesh_storage->multimesh_get_color_offset (multimesh);
1244
- multimesh_uses_color = mesh_storage->multimesh_uses_colors (multimesh);
1245
- multimesh_uses_custom_data = mesh_storage->multimesh_uses_custom_data (multimesh);
1276
+ instance_buffer = mesh_storage->multimesh_get_gl_buffer (multimesh);
1277
+ instance_stride = mesh_storage->multimesh_get_stride (multimesh);
1278
+ instance_color_offset = mesh_storage->multimesh_get_color_offset (multimesh);
1279
+ instance_uses_color = mesh_storage->multimesh_uses_colors (multimesh);
1280
+ instance_uses_custom_data = mesh_storage->multimesh_uses_custom_data (multimesh);
1281
+
1246
1282
} else if (state.canvas_instance_batches [p_index].command_type == Item::Command::TYPE_PARTICLES) {
1247
- // Do nothing for now.
1283
+ const Item::CommandParticles *pt = static_cast <const Item::CommandParticles *>(state.canvas_instance_batches [p_index].command );
1284
+ RID particles = pt->particles ;
1285
+ mesh = particles_storage->particles_get_draw_pass_mesh (particles, 0 );
1286
+
1287
+ ERR_BREAK (particles_storage->particles_get_mode (particles) != RS::PARTICLES_MODE_2D);
1288
+ particles_storage->particles_request_process (particles);
1289
+
1290
+ if (particles_storage->particles_is_inactive (particles)) {
1291
+ break ;
1292
+ }
1293
+
1294
+ RenderingServerDefault::redraw_request (); // Active particles means redraw request.
1295
+
1296
+ int dpc = particles_storage->particles_get_draw_passes (particles);
1297
+ if (dpc == 0 ) {
1298
+ break ; // Nothing to draw.
1299
+ }
1300
+
1301
+ instance_count = particles_storage->particles_get_amount (particles);
1302
+ instance_buffer = particles_storage->particles_get_gl_buffer (particles);
1303
+ instance_stride = 12 ; // 8 bytes for instance transform and 4 bytes for packed color and custom.
1304
+ instance_color_offset = 8 ; // 8 bytes for instance transform.
1305
+ instance_uses_color = true ;
1306
+ instance_uses_custom_data = true ;
1307
+ }
1308
+
1309
+ if (instance_buffer == 0 ) {
1310
+ break ;
1248
1311
}
1249
1312
1250
1313
ERR_FAIL_COND (mesh.is_null ());
@@ -1277,17 +1340,17 @@ void RasterizerCanvasGLES3::_render_batch(Light *p_lights, uint32_t p_index) {
1277
1340
1278
1341
if (instance_count > 1 ) {
1279
1342
// Bind instance buffers.
1280
- glBindBuffer (GL_ARRAY_BUFFER, multimesh_buffer );
1343
+ glBindBuffer (GL_ARRAY_BUFFER, instance_buffer );
1281
1344
glEnableVertexAttribArray (1 );
1282
- glVertexAttribPointer (1 , 4 , GL_FLOAT, GL_FALSE, multimesh_stride * sizeof (float ), CAST_INT_TO_UCHAR_PTR (0 ));
1345
+ glVertexAttribPointer (1 , 4 , GL_FLOAT, GL_FALSE, instance_stride * sizeof (float ), CAST_INT_TO_UCHAR_PTR (0 ));
1283
1346
glVertexAttribDivisor (1 , 1 );
1284
1347
glEnableVertexAttribArray (2 );
1285
- glVertexAttribPointer (2 , 4 , GL_FLOAT, GL_FALSE, multimesh_stride * sizeof (float ), CAST_INT_TO_UCHAR_PTR (4 * 4 ));
1348
+ glVertexAttribPointer (2 , 4 , GL_FLOAT, GL_FALSE, instance_stride * sizeof (float ), CAST_INT_TO_UCHAR_PTR (4 * 4 ));
1286
1349
glVertexAttribDivisor (2 , 1 );
1287
1350
1288
- if (multimesh_uses_color || multimesh_uses_custom_data ) {
1351
+ if (instance_uses_color || instance_uses_custom_data ) {
1289
1352
glEnableVertexAttribArray (5 );
1290
- glVertexAttribIPointer (5 , 4 , GL_UNSIGNED_INT, multimesh_stride * sizeof (float ), CAST_INT_TO_UCHAR_PTR (multimesh_color_offset * sizeof (float )));
1353
+ glVertexAttribIPointer (5 , 4 , GL_UNSIGNED_INT, instance_stride * sizeof (float ), CAST_INT_TO_UCHAR_PTR (instance_color_offset * sizeof (float )));
1291
1354
glVertexAttribDivisor (5 , 1 );
1292
1355
}
1293
1356
}
@@ -1361,17 +1424,17 @@ void RasterizerCanvasGLES3::_new_batch(bool &r_batch_broken, uint32_t &r_index)
1361
1424
_align_instance_data_buffer (r_index);
1362
1425
}
1363
1426
1364
- void RasterizerCanvasGLES3::_bind_material (GLES3::CanvasMaterialData *p_material_data, CanvasShaderGLES3::ShaderVariant p_variant, uint64_t p_specialization) {
1427
+ bool RasterizerCanvasGLES3::_bind_material (GLES3::CanvasMaterialData *p_material_data, CanvasShaderGLES3::ShaderVariant p_variant, uint64_t p_specialization) {
1365
1428
if (p_material_data) {
1366
1429
if (p_material_data->shader_data ->version .is_valid () && p_material_data->shader_data ->valid ) {
1367
1430
// Bind uniform buffer and textures
1368
1431
p_material_data->bind_uniforms ();
1369
- GLES3::MaterialStorage::get_singleton ()->shaders .canvas_shader .version_bind_shader (p_material_data->shader_data ->version , p_variant, p_specialization);
1432
+ return GLES3::MaterialStorage::get_singleton ()->shaders .canvas_shader .version_bind_shader (p_material_data->shader_data ->version , p_variant, p_specialization);
1370
1433
} else {
1371
- GLES3::MaterialStorage::get_singleton ()->shaders .canvas_shader .version_bind_shader (data.canvas_shader_default_version , p_variant, p_specialization);
1434
+ return GLES3::MaterialStorage::get_singleton ()->shaders .canvas_shader .version_bind_shader (data.canvas_shader_default_version , p_variant, p_specialization);
1372
1435
}
1373
1436
} else {
1374
- GLES3::MaterialStorage::get_singleton ()->shaders .canvas_shader .version_bind_shader (data.canvas_shader_default_version , p_variant, p_specialization);
1437
+ return GLES3::MaterialStorage::get_singleton ()->shaders .canvas_shader .version_bind_shader (data.canvas_shader_default_version , p_variant, p_specialization);
1375
1438
}
1376
1439
}
1377
1440
@@ -1435,7 +1498,10 @@ void RasterizerCanvasGLES3::light_update_shadow(RID p_rid, int p_shadow_index, c
1435
1498
RS::CanvasOccluderPolygonCullMode cull_mode = RS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED;
1436
1499
1437
1500
CanvasOcclusionShaderGLES3::ShaderVariant variant = config->float_texture_supported ? CanvasOcclusionShaderGLES3::MODE_SHADOW : CanvasOcclusionShaderGLES3::MODE_SHADOW_RGBA;
1438
- shadow_render.shader .version_bind_shader (shadow_render.shader_version , variant);
1501
+ bool success = shadow_render.shader .version_bind_shader (shadow_render.shader_version , variant);
1502
+ if (!success) {
1503
+ return ;
1504
+ }
1439
1505
1440
1506
for (int i = 0 ; i < 4 ; i++) {
1441
1507
glViewport ((state.shadow_texture_size / 4 ) * i, p_shadow_index * 2 , (state.shadow_texture_size / 4 ), 2 );
@@ -1553,7 +1619,10 @@ void RasterizerCanvasGLES3::light_update_directional_shadow(RID p_rid, int p_sha
1553
1619
RS::CanvasOccluderPolygonCullMode cull_mode = RS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED;
1554
1620
1555
1621
CanvasOcclusionShaderGLES3::ShaderVariant variant = config->float_texture_supported ? CanvasOcclusionShaderGLES3::MODE_SHADOW : CanvasOcclusionShaderGLES3::MODE_SHADOW_RGBA;
1556
- shadow_render.shader .version_bind_shader (shadow_render.shader_version , variant);
1622
+ bool success = shadow_render.shader .version_bind_shader (shadow_render.shader_version , variant);
1623
+ if (!success) {
1624
+ return ;
1625
+ }
1557
1626
1558
1627
Projection projection;
1559
1628
projection.set_orthogonal (-half_size, half_size, -0.5 , 0.5 , 0.0 , distance);
@@ -1685,7 +1754,10 @@ void RasterizerCanvasGLES3::render_sdf(RID p_render_target, LightOccluderInstanc
1685
1754
glClear (GL_COLOR_BUFFER_BIT);
1686
1755
1687
1756
CanvasOcclusionShaderGLES3::ShaderVariant variant = CanvasOcclusionShaderGLES3::MODE_SDF;
1688
- shadow_render.shader .version_bind_shader (shadow_render.shader_version , variant);
1757
+ bool success = shadow_render.shader .version_bind_shader (shadow_render.shader_version , variant);
1758
+ if (!success) {
1759
+ return ;
1760
+ }
1689
1761
1690
1762
shadow_render.shader .version_set_uniform (CanvasOcclusionShaderGLES3::PROJECTION, Projection (), shadow_render.shader_version , variant);
1691
1763
shadow_render.shader .version_set_uniform (CanvasOcclusionShaderGLES3::DIRECTION, 0.0 , 0.0 , shadow_render.shader_version , variant);
@@ -2555,7 +2627,6 @@ RasterizerCanvasGLES3::RasterizerCanvasGLES3() {
2555
2627
2556
2628
GLES3::MaterialStorage::get_singleton ()->shaders .canvas_shader .initialize (global_defines);
2557
2629
data.canvas_shader_default_version = GLES3::MaterialStorage::get_singleton ()->shaders .canvas_shader .version_create ();
2558
- GLES3::MaterialStorage::get_singleton ()->shaders .canvas_shader .version_bind_shader (data.canvas_shader_default_version , CanvasShaderGLES3::MODE_QUAD);
2559
2630
2560
2631
shadow_render.shader .initialize ();
2561
2632
shadow_render.shader_version = shadow_render.shader .version_create ();
0 commit comments