summaryrefslogtreecommitdiffstats
path: root/drivers/gles3/rasterizer_canvas_gles3.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gles3/rasterizer_canvas_gles3.cpp')
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp156
1 files changed, 114 insertions, 42 deletions
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index 86405fa3f0..80daa9a907 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -33,6 +33,7 @@
#ifdef GLES3_ENABLED
#include "core/os/os.h"
+#include "rasterizer_gles3.h"
#include "rasterizer_scene_gles3.h"
#include "core/config/project_settings.h"
@@ -103,7 +104,7 @@ void RasterizerCanvasGLES3::_update_transform_to_mat4(const Transform3D &p_trans
p_mat4[15] = 1;
}
-void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_light_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, bool &r_sdf_used) {
+void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_light_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, bool &r_sdf_used, RenderingMethod::RenderInfo *r_render_info) {
GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();
GLES3::MeshStorage *mesh_storage = GLES3::MeshStorage::get_singleton();
@@ -458,7 +459,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_
update_skeletons = false;
}
// Canvas group begins here, render until before this item
- _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, r_sdf_used);
+ _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, r_sdf_used, false, r_render_info);
item_count = 0;
if (ci->canvas_group_owner->canvas_group->mode != RS::CANVAS_GROUP_MODE_TRANSPARENT) {
@@ -489,7 +490,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_
mesh_storage->update_mesh_instances();
update_skeletons = false;
}
- _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, r_sdf_used, true);
+ _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, r_sdf_used, true, r_render_info);
item_count = 0;
if (ci->canvas_group->blur_mipmaps) {
@@ -513,7 +514,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_
}
//render anything pending, including clearing if no items
- _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, r_sdf_used);
+ _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, r_sdf_used, false, r_render_info);
item_count = 0;
texture_storage->render_target_copy_to_back_buffer(p_to_render_target, back_buffer_rect, backbuffer_gen_mipmaps);
@@ -543,7 +544,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_
mesh_storage->update_mesh_instances();
update_skeletons = false;
}
- _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, r_sdf_used, canvas_group_owner != nullptr);
+ _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, r_sdf_used, canvas_group_owner != nullptr, r_render_info);
//then reset
item_count = 0;
}
@@ -563,7 +564,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_
state.current_instance_buffer_index = 0;
}
-void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool &r_sdf_used, bool p_to_backbuffer) {
+void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool &r_sdf_used, bool p_to_backbuffer, RenderingMethod::RenderInfo *r_render_info) {
GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();
canvas_begin(p_to_render_target, p_to_backbuffer);
@@ -626,6 +627,11 @@ void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_cou
state.canvas_instance_batches[state.current_batch_index].material = material;
state.canvas_instance_batches[state.current_batch_index].material_data = material_data;
+ if (shader_data_cache) {
+ state.canvas_instance_batches[state.current_batch_index].vertex_input_mask = shader_data_cache->vertex_input_mask;
+ } else {
+ state.canvas_instance_batches[state.current_batch_index].vertex_input_mask = RS::ARRAY_FORMAT_VERTEX | RS::ARRAY_COLOR | RS::ARRAY_TEX_UV;
+ }
}
GLES3::CanvasShaderData::BlendMode blend_mode = shader_data_cache ? shader_data_cache->blend_mode : GLES3::CanvasShaderData::BLEND_MODE_MIX;
@@ -660,6 +666,11 @@ void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_cou
state.current_tex = RID();
for (uint32_t i = 0; i <= state.current_batch_index; i++) {
+ // Skipping when there is no instances.
+ if (state.canvas_instance_batches[i].instance_count == 0) {
+ continue;
+ }
+
//setup clip
if (current_clip != state.canvas_instance_batches[i].clip) {
current_clip = state.canvas_instance_batches[i].clip;
@@ -766,9 +777,10 @@ void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_cou
last_blend_color = blend_color;
}
- _render_batch(p_lights, i);
+ _render_batch(p_lights, i, r_render_info);
}
+ glDisable(GL_SCISSOR_TEST);
state.current_batch_index = 0;
state.canvas_instance_batches.clear();
state.last_item_index += index;
@@ -865,7 +877,7 @@ void RasterizerCanvasGLES3::_record_item_commands(const Item *p_item, RID p_rend
state.instance_data_array[r_index].lights[2] = lights[2];
state.instance_data_array[r_index].lights[3] = lights[3];
- state.instance_data_array[r_index].flags = base_flags | (state.instance_data_array[r_index == 0 ? 0 : r_index - 1].flags & (FLAGS_DEFAULT_NORMAL_MAP_USED | FLAGS_DEFAULT_SPECULAR_MAP_USED)); //reset on each command for sanity, keep canvastexture binding config
+ state.instance_data_array[r_index].flags = base_flags | (state.instance_data_array[r_index == 0 ? 0 : r_index - 1].flags & (FLAGS_DEFAULT_NORMAL_MAP_USED | FLAGS_DEFAULT_SPECULAR_MAP_USED)); // Reset on each command for safety, keep canvastexture binding config.
Color blend_color = base_color;
GLES3::CanvasShaderData::BlendMode blend_mode = p_blend_mode;
@@ -1234,8 +1246,14 @@ void RasterizerCanvasGLES3::_record_item_commands(const Item *p_item, RID p_rend
}
}
-void RasterizerCanvasGLES3::_render_batch(Light *p_lights, uint32_t p_index) {
- ERR_FAIL_COND(!state.canvas_instance_batches[state.current_batch_index].command);
+_FORCE_INLINE_ static uint32_t _indices_to_primitives(RS::PrimitiveType p_primitive, uint32_t p_indices) {
+ static const uint32_t divisor[RS::PRIMITIVE_MAX] = { 1, 2, 1, 3, 1 };
+ static const uint32_t subtractor[RS::PRIMITIVE_MAX] = { 0, 0, 1, 0, 1 };
+ return (p_indices - subtractor[p_primitive]) / divisor[p_primitive];
+}
+
+void RasterizerCanvasGLES3::_render_batch(Light *p_lights, uint32_t p_index, RenderingMethod::RenderInfo *r_render_info) {
+ ERR_FAIL_NULL(state.canvas_instance_batches[state.current_batch_index].command);
// Used by Polygon and Mesh.
static const GLenum prim[5] = { GL_POINTS, GL_LINES, GL_LINE_STRIP, GL_TRIANGLES, GL_TRIANGLE_STRIP };
@@ -1253,13 +1271,19 @@ void RasterizerCanvasGLES3::_render_batch(Light *p_lights, uint32_t p_index) {
glDrawElementsInstanced(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0, state.canvas_instance_batches[p_index].instance_count);
glBindVertexArray(0);
+ if (r_render_info) {
+ r_render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_CANVAS][RS::VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME] += state.canvas_instance_batches[p_index].instance_count;
+ r_render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_CANVAS][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += 2 * state.canvas_instance_batches[p_index].instance_count;
+ r_render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_CANVAS][RS::VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME]++;
+ }
+
} break;
case Item::Command::TYPE_POLYGON: {
const Item::CommandPolygon *polygon = static_cast<const Item::CommandPolygon *>(state.canvas_instance_batches[p_index].command);
PolygonBuffers *pb = polygon_buffers.polygons.getptr(polygon->polygon.polygon_id);
- ERR_FAIL_COND(!pb);
+ ERR_FAIL_NULL(pb);
glBindVertexArray(pb->vertex_array);
glBindBuffer(GL_ARRAY_BUFFER, state.canvas_instance_data_buffers[state.current_data_buffer_index].instance_buffers[state.canvas_instance_batches[p_index].instance_buffer_index]);
@@ -1282,6 +1306,12 @@ void RasterizerCanvasGLES3::_render_batch(Light *p_lights, uint32_t p_index) {
// Reset so this doesn't pollute other draw calls.
glVertexAttrib4f(RS::ARRAY_COLOR, 1.0, 1.0, 1.0, 1.0);
}
+
+ if (r_render_info) {
+ r_render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_CANVAS][RS::VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME]++;
+ r_render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_CANVAS][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += _indices_to_primitives(polygon->primitive, pb->count);
+ r_render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_CANVAS][RS::VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME]++;
+ }
} break;
case Item::Command::TYPE_PRIMITIVE: {
@@ -1296,6 +1326,12 @@ void RasterizerCanvasGLES3::_render_batch(Light *p_lights, uint32_t p_index) {
if (instance_count >= 1) {
glDrawArraysInstanced(primitive[state.canvas_instance_batches[p_index].primitive_points], 0, state.canvas_instance_batches[p_index].primitive_points, instance_count);
}
+ if (r_render_info) {
+ const RenderingServer::PrimitiveType rs_primitive[5] = { RS::PRIMITIVE_POINTS, RS::PRIMITIVE_POINTS, RS::PRIMITIVE_LINES, RS::PRIMITIVE_TRIANGLES, RS::PRIMITIVE_TRIANGLES };
+ r_render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_CANVAS][RS::VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME] += instance_count;
+ r_render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_CANVAS][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += _indices_to_primitives(rs_primitive[state.canvas_instance_batches[p_index].primitive_points], state.canvas_instance_batches[p_index].primitive_points) * instance_count;
+ r_render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_CANVAS][RS::VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME]++;
+ }
} break;
@@ -1382,11 +1418,12 @@ void RasterizerCanvasGLES3::_render_batch(Light *p_lights, uint32_t p_index) {
GLuint vertex_array_gl = 0;
GLuint index_array_gl = 0;
- uint32_t input_mask = 0; // 2D meshes always use the same vertex format
+ uint64_t vertex_input_mask = state.canvas_instance_batches[p_index].vertex_input_mask;
+
if (mesh_instance.is_valid()) {
- mesh_storage->mesh_instance_surface_get_vertex_arrays_and_format(mesh_instance, j, input_mask, vertex_array_gl);
+ mesh_storage->mesh_instance_surface_get_vertex_arrays_and_format(mesh_instance, j, vertex_input_mask, vertex_array_gl);
} else {
- mesh_storage->mesh_surface_get_vertex_arrays_and_format(surface, input_mask, vertex_array_gl);
+ mesh_storage->mesh_surface_get_vertex_arrays_and_format(surface, vertex_input_mask, vertex_array_gl);
}
index_array_gl = mesh_storage->mesh_surface_get_index_buffer(surface, 0);
@@ -1419,23 +1456,38 @@ void RasterizerCanvasGLES3::_render_batch(Light *p_lights, uint32_t p_index) {
glEnableVertexAttribArray(5);
glVertexAttribIPointer(5, 4, GL_UNSIGNED_INT, instance_stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(instance_color_offset * sizeof(float)));
glVertexAttribDivisor(5, 1);
+ } else {
+ // Set all default instance color and custom data values to 1.0 or 0.0 using a compressed format.
+ uint16_t zero = Math::make_half_float(0.0f);
+ uint16_t one = Math::make_half_float(1.0f);
+ GLuint default_color = (uint32_t(one) << 16) | one;
+ GLuint default_custom = (uint32_t(zero) << 16) | zero;
+ glVertexAttribI4ui(5, default_color, default_color, default_custom, default_custom);
}
}
GLenum primitive_gl = prim[int(primitive)];
+ uint32_t vertex_count = mesh_storage->mesh_surface_get_vertices_drawn_count(surface);
+
if (use_index_buffer) {
- glDrawElementsInstanced(primitive_gl, mesh_storage->mesh_surface_get_vertices_drawn_count(surface), mesh_storage->mesh_surface_get_index_type(surface), 0, instance_count);
+ glDrawElementsInstanced(primitive_gl, vertex_count, mesh_storage->mesh_surface_get_index_type(surface), 0, instance_count);
} else {
- glDrawArraysInstanced(primitive_gl, 0, mesh_storage->mesh_surface_get_vertices_drawn_count(surface), instance_count);
+ glDrawArraysInstanced(primitive_gl, 0, vertex_count, instance_count);
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
if (use_instancing) {
glDisableVertexAttribArray(5);
- glDisableVertexAttribArray(6);
- glDisableVertexAttribArray(7);
glDisableVertexAttribArray(8);
+ glDisableVertexAttribArray(9);
+ glDisableVertexAttribArray(10);
+ }
+ if (r_render_info) {
+ // Meshes, Particles, and MultiMesh are always just one object with one draw call.
+ r_render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_CANVAS][RS::VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME]++;
+ r_render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_CANVAS][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += _indices_to_primitives(primitive, vertex_count) * instance_count;
+ r_render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_CANVAS][RS::VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME]++;
}
}
@@ -1451,7 +1503,7 @@ void RasterizerCanvasGLES3::_render_batch(Light *p_lights, uint32_t p_index) {
void RasterizerCanvasGLES3::_add_to_batch(uint32_t &r_index, bool &r_batch_broken) {
state.canvas_instance_batches[state.current_batch_index].instance_count++;
r_index++;
- if (r_index >= data.max_instances_per_buffer) {
+ if (r_index + state.last_item_index >= data.max_instances_per_buffer) {
// Copy over all data needed for rendering right away
// then go back to recording item commands.
glBindBuffer(GL_ARRAY_BUFFER, state.canvas_instance_data_buffers[state.current_data_buffer_index].instance_buffers[state.current_instance_buffer_index]);
@@ -1494,15 +1546,15 @@ void RasterizerCanvasGLES3::_new_batch(bool &r_batch_broken) {
}
void RasterizerCanvasGLES3::_enable_attributes(uint32_t p_start, bool p_primitive, uint32_t p_rate) {
- uint32_t split = p_primitive ? 11 : 12;
- for (uint32_t i = 6; i < split; i++) {
+ uint32_t split = p_primitive ? 13 : 14;
+ for (uint32_t i = 8; i < split; i++) {
glEnableVertexAttribArray(i);
- glVertexAttribPointer(i, 4, GL_FLOAT, GL_FALSE, sizeof(InstanceData), CAST_INT_TO_UCHAR_PTR(p_start + (i - 6) * 4 * sizeof(float)));
+ glVertexAttribPointer(i, 4, GL_FLOAT, GL_FALSE, sizeof(InstanceData), CAST_INT_TO_UCHAR_PTR(p_start + (i - 8) * 4 * sizeof(float)));
glVertexAttribDivisor(i, p_rate);
}
- for (uint32_t i = split; i <= 13; i++) {
+ for (uint32_t i = split; i <= 15; i++) {
glEnableVertexAttribArray(i);
- glVertexAttribIPointer(i, 4, GL_UNSIGNED_INT, sizeof(InstanceData), CAST_INT_TO_UCHAR_PTR(p_start + (i - 6) * 4 * sizeof(float)));
+ glVertexAttribIPointer(i, 4, GL_UNSIGNED_INT, sizeof(InstanceData), CAST_INT_TO_UCHAR_PTR(p_start + (i - 8) * 4 * sizeof(float)));
glVertexAttribDivisor(i, p_rate);
}
}
@@ -1515,7 +1567,7 @@ void RasterizerCanvasGLES3::light_set_texture(RID p_rid, RID p_texture) {
GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
CanvasLight *cl = canvas_light_owner.get_or_null(p_rid);
- ERR_FAIL_COND(!cl);
+ ERR_FAIL_NULL(cl);
if (cl->texture == p_texture) {
return;
}
@@ -1534,7 +1586,7 @@ void RasterizerCanvasGLES3::light_set_texture(RID p_rid, RID p_texture) {
void RasterizerCanvasGLES3::light_set_use_shadow(RID p_rid, bool p_enable) {
CanvasLight *cl = canvas_light_owner.get_or_null(p_rid);
- ERR_FAIL_COND(!cl);
+ ERR_FAIL_NULL(cl);
cl->shadow.enabled = p_enable;
}
@@ -1561,7 +1613,8 @@ void RasterizerCanvasGLES3::light_update_shadow(RID p_rid, int p_shadow_index, c
glEnable(GL_SCISSOR_TEST);
glScissor(0, p_shadow_index * 2, state.shadow_texture_size, 2);
glClearColor(p_far, p_far, p_far, 1.0);
- glClearDepth(1.0);
+ RasterizerGLES3::clear_depth(1.0);
+
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glCullFace(GL_BACK);
@@ -1682,7 +1735,8 @@ void RasterizerCanvasGLES3::light_update_directional_shadow(RID p_rid, int p_sha
glEnable(GL_SCISSOR_TEST);
glScissor(0, p_shadow_index * 2, state.shadow_texture_size, 2);
glClearColor(1.0, 1.0, 1.0, 1.0);
- glClearDepth(1.0);
+ RasterizerGLES3::clear_depth(1.0);
+
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glCullFace(GL_BACK);
@@ -1868,7 +1922,7 @@ RID RasterizerCanvasGLES3::occluder_polygon_create() {
void RasterizerCanvasGLES3::occluder_polygon_set_shape(RID p_occluder, const Vector<Vector2> &p_points, bool p_closed) {
OccluderPolygon *oc = occluder_polygon_owner.get_or_null(p_occluder);
- ERR_FAIL_COND(!oc);
+ ERR_FAIL_NULL(oc);
Vector<Vector2> lines;
@@ -2041,29 +2095,39 @@ void RasterizerCanvasGLES3::occluder_polygon_set_shape(RID p_occluder, const Vec
void RasterizerCanvasGLES3::occluder_polygon_set_cull_mode(RID p_occluder, RS::CanvasOccluderPolygonCullMode p_mode) {
OccluderPolygon *oc = occluder_polygon_owner.get_or_null(p_occluder);
- ERR_FAIL_COND(!oc);
+ ERR_FAIL_NULL(oc);
oc->cull_mode = p_mode;
}
void RasterizerCanvasGLES3::set_shadow_texture_size(int p_size) {
GLES3::Config *config = GLES3::Config::get_singleton();
p_size = nearest_power_of_2_templated(p_size);
- if (p_size == state.shadow_texture_size) {
- return;
- }
if (p_size > config->max_texture_size) {
p_size = config->max_texture_size;
WARN_PRINT("Attempting to set CanvasItem shadow atlas size to " + itos(p_size) + " which is beyond limit of " + itos(config->max_texture_size) + "supported by hardware.");
}
+ if (p_size == state.shadow_texture_size) {
+ return;
+ }
state.shadow_texture_size = p_size;
+
+ if (state.shadow_fb != 0) {
+ glDeleteFramebuffers(1, &state.shadow_fb);
+ GLES3::Utilities::get_singleton()->texture_free_data(state.shadow_texture);
+ glDeleteRenderbuffers(1, &state.shadow_depth_buffer);
+ state.shadow_fb = 0;
+ state.shadow_texture = 0;
+ state.shadow_depth_buffer = 0;
+ }
+ _update_shadow_atlas();
}
bool RasterizerCanvasGLES3::free(RID p_rid) {
if (canvas_light_owner.owns(p_rid)) {
CanvasLight *cl = canvas_light_owner.get_or_null(p_rid);
- ERR_FAIL_COND_V(!cl, false);
+ ERR_FAIL_NULL_V(cl, false);
canvas_light_owner.free(p_rid);
} else if (occluder_polygon_owner.owns(p_rid)) {
occluder_polygon_set_shape(p_rid, Vector<Vector2>(), false);
@@ -2105,7 +2169,7 @@ void RasterizerCanvasGLES3::canvas_begin(RID p_to_render_target, bool p_to_backb
if (render_target && render_target->clear_requested) {
const Color &col = render_target->clear_color;
- glClearColor(col.r, col.g, col.b, col.a);
+ glClearColor(col.r, col.g, col.b, render_target->is_transparent ? col.a : 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
render_target->clear_requested = false;
@@ -2137,7 +2201,7 @@ void RasterizerCanvasGLES3::_bind_canvas_texture(RID p_texture, RS::CanvasItemTe
GLES3::Texture *t = texture_storage->get_texture(p_texture);
if (t) {
- ERR_FAIL_COND(!t->canvas_texture);
+ ERR_FAIL_NULL(t->canvas_texture);
ct = t->canvas_texture;
if (t->render_target) {
t->render_target->used_in_frame = true;
@@ -2238,14 +2302,18 @@ void RasterizerCanvasGLES3::_prepare_canvas_texture(RID p_texture, RS::CanvasIte
GLES3::Texture *texture = texture_storage->get_texture(ct->diffuse);
Size2i size_cache;
+
+ // Cache default white resource ID.
+ const RID default_texture_id = texture_storage->texture_gl_get_default(GLES3::DEFAULT_GL_TEXTURE_WHITE);
+
+ // If no texture is assigned, assign default white.
if (!texture) {
- ct->diffuse = texture_storage->texture_gl_get_default(GLES3::DEFAULT_GL_TEXTURE_WHITE);
- GLES3::Texture *tex = texture_storage->get_texture(ct->diffuse);
- size_cache = Size2i(tex->width, tex->height);
- } else {
- size_cache = Size2i(texture->width, texture->height);
+ ct->diffuse = default_texture_id;
}
+ // Enforce a 1x1 size if default white texture.
+ size_cache = ct->diffuse == default_texture_id ? Size2i(1, 1) : Size2i(texture->width, texture->height);
+
GLES3::Texture *normal_map = texture_storage->get_texture(ct->normal_map);
if (ct->specular_color.a < 0.999) {
@@ -2442,9 +2510,10 @@ RendererCanvasRender::PolygonID RasterizerCanvasGLES3::request_polygon(const Vec
return id;
}
+
void RasterizerCanvasGLES3::free_polygon(PolygonID p_polygon) {
PolygonBuffers *pb_ptr = polygon_buffers.polygons.getptr(p_polygon);
- ERR_FAIL_COND(!pb_ptr);
+ ERR_FAIL_NULL(pb_ptr);
PolygonBuffers &pb = *pb_ptr;
@@ -2521,6 +2590,8 @@ RasterizerCanvasGLES3::RasterizerCanvasGLES3() {
GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();
GLES3::Config *config = GLES3::Config::get_singleton();
+ glVertexAttrib4f(RS::ARRAY_COLOR, 1.0, 1.0, 1.0, 1.0);
+
polygon_buffers.last_id = 1;
// quad buffer
{
@@ -2700,6 +2771,7 @@ RasterizerCanvasGLES3::RasterizerCanvasGLES3() {
GLES3::MaterialStorage::get_singleton()->shaders.canvas_shader.initialize(global_defines, 1);
data.canvas_shader_default_version = GLES3::MaterialStorage::get_singleton()->shaders.canvas_shader.version_create();
+ state.shadow_texture_size = GLOBAL_GET("rendering/2d/shadow_atlas/size");
shadow_render.shader.initialize();
shadow_render.shader_version = shadow_render.shader.version_create();