diff options
Diffstat (limited to 'drivers/gles3/rasterizer_canvas_gles3.cpp')
-rw-r--r-- | drivers/gles3/rasterizer_canvas_gles3.cpp | 156 |
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(); |