summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/egl/egl_manager.cpp1
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp17
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.h4
-rw-r--r--drivers/gles3/storage/mesh_storage.cpp24
-rw-r--r--drivers/gles3/storage/texture_storage.cpp22
5 files changed, 47 insertions, 21 deletions
diff --git a/drivers/egl/egl_manager.cpp b/drivers/egl/egl_manager.cpp
index 4c9d610935..c92cfea9af 100644
--- a/drivers/egl/egl_manager.cpp
+++ b/drivers/egl/egl_manager.cpp
@@ -34,6 +34,7 @@
#if defined(EGL_STATIC)
#define KHRONOS_STATIC 1
+#define GLAD_EGL_VERSION_1_5 true
extern "C" EGLAPI void EGLAPIENTRY eglSetBlobCacheFuncsANDROID(EGLDisplay dpy, EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get);
#undef KHRONOS_STATIC
#endif
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index 1f10f4b353..21e14c1ec9 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -1906,7 +1906,7 @@ void RasterizerSceneGLES3::_setup_lights(const RenderDataGLES3 *p_render_data, b
}
// Render shadows
-void RasterizerSceneGLES3::_render_shadows(const RenderDataGLES3 *p_render_data) {
+void RasterizerSceneGLES3::_render_shadows(const RenderDataGLES3 *p_render_data, const Size2i &p_viewport_size) {
GLES3::LightStorage *light_storage = GLES3::LightStorage::get_singleton();
LocalVector<int> cube_shadows;
@@ -1942,20 +1942,20 @@ void RasterizerSceneGLES3::_render_shadows(const RenderDataGLES3 *p_render_data)
// Render cubemap shadows.
for (const int &index : cube_shadows) {
- _render_shadow_pass(p_render_data->render_shadows[index].light, p_render_data->shadow_atlas, p_render_data->render_shadows[index].pass, p_render_data->render_shadows[index].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->render_info);
+ _render_shadow_pass(p_render_data->render_shadows[index].light, p_render_data->shadow_atlas, p_render_data->render_shadows[index].pass, p_render_data->render_shadows[index].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->render_info, p_viewport_size);
}
// Render directional shadows.
for (uint32_t i = 0; i < directional_shadows.size(); i++) {
- _render_shadow_pass(p_render_data->render_shadows[directional_shadows[i]].light, p_render_data->shadow_atlas, p_render_data->render_shadows[directional_shadows[i]].pass, p_render_data->render_shadows[directional_shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->render_info);
+ _render_shadow_pass(p_render_data->render_shadows[directional_shadows[i]].light, p_render_data->shadow_atlas, p_render_data->render_shadows[directional_shadows[i]].pass, p_render_data->render_shadows[directional_shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->render_info, p_viewport_size);
}
// Render positional shadows (Spotlight and Omnilight with dual-paraboloid).
for (uint32_t i = 0; i < shadows.size(); i++) {
- _render_shadow_pass(p_render_data->render_shadows[shadows[i]].light, p_render_data->shadow_atlas, p_render_data->render_shadows[shadows[i]].pass, p_render_data->render_shadows[shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->render_info);
+ _render_shadow_pass(p_render_data->render_shadows[shadows[i]].light, p_render_data->shadow_atlas, p_render_data->render_shadows[shadows[i]].pass, p_render_data->render_shadows[shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->render_info, p_viewport_size);
}
}
}
-void RasterizerSceneGLES3::_render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &p_instances, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, RenderingMethod::RenderInfo *p_render_info) {
+void RasterizerSceneGLES3::_render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &p_instances, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, RenderingMethod::RenderInfo *p_render_info, const Size2i &p_viewport_size) {
GLES3::LightStorage *light_storage = GLES3::LightStorage::get_singleton();
ERR_FAIL_COND(!light_storage->owns_light_instance(p_light));
@@ -2093,7 +2093,7 @@ void RasterizerSceneGLES3::_render_shadow_pass(RID p_light, RID p_shadow_atlas,
render_data.instances = &p_instances;
render_data.render_info = p_render_info;
- _setup_environment(&render_data, true, Vector2(1, 1), false, Color(), use_pancake, shadow_bias);
+ _setup_environment(&render_data, true, p_viewport_size, false, Color(), use_pancake, shadow_bias);
if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_DISABLE_LOD) {
render_data.screen_mesh_lod_threshold = 0.0;
@@ -2271,7 +2271,7 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_
// If we're rendering right-side up, then we need to change the winding order.
glFrontFace(GL_CW);
}
- _render_shadows(&render_data);
+ _render_shadows(&render_data, screen_size);
_setup_lights(&render_data, true, render_data.directional_light_count, render_data.omni_light_count, render_data.spot_light_count, render_data.directional_shadow_count);
_setup_environment(&render_data, render_data.reflection_probe.is_valid(), screen_size, flip_y, clear_color, false);
@@ -3289,6 +3289,9 @@ RasterizerSceneGLES3::RasterizerSceneGLES3() {
// Quality settings.
use_physical_light_units = GLOBAL_GET("rendering/lights_and_shadows/use_physical_light_units");
+ positional_soft_shadow_filter_set_quality((RS::ShadowQuality)(int)GLOBAL_GET("rendering/lights_and_shadows/positional_shadow/soft_shadow_filter_quality"));
+ directional_soft_shadow_filter_set_quality((RS::ShadowQuality)(int)GLOBAL_GET("rendering/lights_and_shadows/directional_shadow/soft_shadow_filter_quality"));
+
{
// Setup Lights
diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h
index da60d571bf..7d3c8896da 100644
--- a/drivers/gles3/rasterizer_scene_gles3.h
+++ b/drivers/gles3/rasterizer_scene_gles3.h
@@ -516,8 +516,8 @@ private:
void _setup_lights(const RenderDataGLES3 *p_render_data, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_omni_light_count, uint32_t &r_spot_light_count, uint32_t &r_directional_shadow_count);
void _setup_environment(const RenderDataGLES3 *p_render_data, bool p_no_fog, const Size2i &p_screen_size, bool p_flip_y, const Color &p_default_bg_color, bool p_pancake_shadows, float p_shadow_bias = 0.0);
void _fill_render_list(RenderListType p_render_list, const RenderDataGLES3 *p_render_data, PassMode p_pass_mode, bool p_append = false);
- void _render_shadows(const RenderDataGLES3 *p_render_data);
- void _render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_mesh_lod_threshold = 0.0, RenderingMethod::RenderInfo *p_render_info = nullptr);
+ void _render_shadows(const RenderDataGLES3 *p_render_data, const Size2i &p_viewport_size = Size2i(1, 1));
+ void _render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_mesh_lod_threshold = 0.0, RenderingMethod::RenderInfo *p_render_info = nullptr, const Size2i &p_viewport_size = Size2i(1, 1));
template <PassMode p_pass_mode>
_FORCE_INLINE_ void _render_list_template(RenderListParameters *p_params, const RenderDataGLES3 *p_render_data, uint32_t p_from_element, uint32_t p_to_element, bool p_alpha_pass = false);
diff --git a/drivers/gles3/storage/mesh_storage.cpp b/drivers/gles3/storage/mesh_storage.cpp
index 3213fa3775..88ee749ed6 100644
--- a/drivers/gles3/storage/mesh_storage.cpp
+++ b/drivers/gles3/storage/mesh_storage.cpp
@@ -217,8 +217,23 @@ void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface)
if (new_surface.vertex_data.size()) {
glGenBuffers(1, &s->vertex_buffer);
glBindBuffer(GL_ARRAY_BUFFER, s->vertex_buffer);
- GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, s->vertex_buffer, new_surface.vertex_data.size(), new_surface.vertex_data.ptr(), (s->format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW, "Mesh vertex buffer");
- s->vertex_buffer_size = new_surface.vertex_data.size();
+ // If we have an uncompressed surface that contains normals, but not tangents, we need to differentiate the array
+ // from a compressed array in the shader. To do so, we allow the the normal to read 4 components out of the buffer
+ // But only give it 2 components per normal. So essentially, each vertex reads the next normal in normal.zw.
+ // This allows us to avoid adding a shader permutation, and avoid passing dummy tangents. Since the stride is kept small
+ // this should still be a net win for bandwidth.
+ // If we do this, then the last normal will read past the end of the array. So we need to pad the array with dummy data.
+ if (!(new_surface.format & RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES) && (new_surface.format & RS::ARRAY_FORMAT_NORMAL) && !(new_surface.format & RS::ARRAY_FORMAT_TANGENT)) {
+ // Unfortunately, we need to copy the buffer, which is fine as doing a resize triggers a CoW anyway.
+ Vector<uint8_t> new_vertex_data;
+ new_vertex_data.resize_zeroed(new_surface.vertex_data.size() + sizeof(uint16_t) * 2);
+ memcpy(new_vertex_data.ptrw(), new_surface.vertex_data.ptr(), new_surface.vertex_data.size());
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, s->vertex_buffer, new_vertex_data.size(), new_vertex_data.ptr(), (s->format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW, "Mesh vertex buffer");
+ s->vertex_buffer_size = new_vertex_data.size();
+ } else {
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, s->vertex_buffer, new_surface.vertex_data.size(), new_surface.vertex_data.ptr(), (s->format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW, "Mesh vertex buffer");
+ s->vertex_buffer_size = new_surface.vertex_data.size();
+ }
}
if (new_surface.attribute_data.size()) {
@@ -461,6 +476,11 @@ RS::SurfaceData MeshStorage::mesh_get_surface(RID p_mesh, int p_surface) const {
sd.format = s.format;
if (s.vertex_buffer != 0) {
sd.vertex_data = Utilities::buffer_get_data(GL_ARRAY_BUFFER, s.vertex_buffer, s.vertex_buffer_size);
+
+ // When using an uncompressed buffer with normals, but without tangents, we have to trim the padding.
+ if (!(s.format & RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES) && (s.format & RS::ARRAY_FORMAT_NORMAL) && !(s.format & RS::ARRAY_FORMAT_TANGENT)) {
+ sd.vertex_data.resize(sd.vertex_data.size() - sizeof(uint16_t) * 2);
+ }
}
if (s.attribute_buffer != 0) {
diff --git a/drivers/gles3/storage/texture_storage.cpp b/drivers/gles3/storage/texture_storage.cpp
index b7b62d78a0..fcc1dee3e2 100644
--- a/drivers/gles3/storage/texture_storage.cpp
+++ b/drivers/gles3/storage/texture_storage.cpp
@@ -713,18 +713,20 @@ void TextureStorage::texture_free(RID p_texture) {
memdelete(t->canvas_texture);
}
- if (t->tex_id != 0) {
- if (!t->is_external) {
- GLES3::Utilities::get_singleton()->texture_free_data(t->tex_id);
+ bool must_free_data = false;
+ if (t->is_proxy) {
+ if (t->proxy_to.is_valid()) {
+ Texture *proxy_to = texture_owner.get_or_null(t->proxy_to);
+ if (proxy_to) {
+ proxy_to->proxies.erase(p_texture);
+ }
}
- t->tex_id = 0;
+ } else {
+ must_free_data = t->tex_id != 0 && !t->is_external;
}
-
- if (t->is_proxy && t->proxy_to.is_valid()) {
- Texture *proxy_to = texture_owner.get_or_null(t->proxy_to);
- if (proxy_to) {
- proxy_to->proxies.erase(p_texture);
- }
+ if (must_free_data) {
+ GLES3::Utilities::get_singleton()->texture_free_data(t->tex_id);
+ t->tex_id = 0;
}
texture_atlas_remove_texture(p_texture);