summaryrefslogtreecommitdiffstats
path: root/drivers/gles3
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gles3')
-rw-r--r--drivers/gles3/effects/feed_effects.cpp128
-rw-r--r--drivers/gles3/effects/feed_effects.h68
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp45
-rw-r--r--drivers/gles3/rasterizer_gles3.cpp2
-rw-r--r--drivers/gles3/rasterizer_gles3.h2
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp39
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.h1
-rw-r--r--drivers/gles3/shader_gles3.cpp4
-rw-r--r--drivers/gles3/shaders/SCsub1
-rw-r--r--drivers/gles3/shaders/feed.glsl39
-rw-r--r--drivers/gles3/shaders/stdlib_inc.glsl40
-rw-r--r--drivers/gles3/storage/config.cpp7
-rw-r--r--drivers/gles3/storage/config.h11
-rw-r--r--drivers/gles3/storage/light_storage.cpp17
-rw-r--r--drivers/gles3/storage/light_storage.h25
-rw-r--r--drivers/gles3/storage/material_storage.cpp4
-rw-r--r--drivers/gles3/storage/material_storage.h8
-rw-r--r--drivers/gles3/storage/mesh_storage.h16
-rw-r--r--drivers/gles3/storage/particles_storage.h2
-rw-r--r--drivers/gles3/storage/texture_storage.cpp2
-rw-r--r--drivers/gles3/storage/texture_storage.h12
-rw-r--r--drivers/gles3/storage/utilities.h4
22 files changed, 403 insertions, 74 deletions
diff --git a/drivers/gles3/effects/feed_effects.cpp b/drivers/gles3/effects/feed_effects.cpp
new file mode 100644
index 0000000000..8ca88da662
--- /dev/null
+++ b/drivers/gles3/effects/feed_effects.cpp
@@ -0,0 +1,128 @@
+/**************************************************************************/
+/* feed_effects.cpp */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#ifdef GLES3_ENABLED
+
+#include "feed_effects.h"
+
+#ifdef ANDROID_ENABLED
+#include <GLES3/gl3ext.h>
+#endif
+
+#define GL_PROGRAM_POINT_SIZE 0x8642
+
+using namespace GLES3;
+
+FeedEffects *FeedEffects::singleton = nullptr;
+
+FeedEffects *FeedEffects::get_singleton() {
+ return singleton;
+}
+
+FeedEffects::FeedEffects() {
+ singleton = this;
+
+ feed.shader.initialize();
+ feed.shader_version = feed.shader.version_create();
+ feed.shader.version_bind_shader(feed.shader_version, FeedShaderGLES3::MODE_DEFAULT);
+
+ { // Screen Triangle.
+ glGenBuffers(1, &screen_triangle);
+ glBindBuffer(GL_ARRAY_BUFFER, screen_triangle);
+
+ const float qv[6] = {
+ -1.0f,
+ -1.0f,
+ 3.0f,
+ -1.0f,
+ -1.0f,
+ 3.0f,
+ };
+
+ glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 6, qv, GL_STATIC_DRAW);
+ glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
+
+ glGenVertexArrays(1, &screen_triangle_array);
+ glBindVertexArray(screen_triangle_array);
+ glBindBuffer(GL_ARRAY_BUFFER, screen_triangle);
+ glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, nullptr);
+ glEnableVertexAttribArray(RS::ARRAY_VERTEX);
+ glBindVertexArray(0);
+ glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
+ }
+}
+
+FeedEffects::~FeedEffects() {
+ singleton = nullptr;
+ glDeleteBuffers(1, &screen_triangle);
+ glDeleteVertexArrays(1, &screen_triangle_array);
+ feed.shader.version_free(feed.shader_version);
+}
+
+Transform3D transform3D_from_mat4(const float *p_mat4) {
+ Transform3D res;
+
+ res.basis.rows[0][0] = p_mat4[0];
+ res.basis.rows[1][0] = p_mat4[1];
+ res.basis.rows[2][0] = p_mat4[2];
+ // p_mat4[3] = 0;
+ res.basis.rows[0][1] = p_mat4[4];
+ res.basis.rows[1][1] = p_mat4[5];
+ res.basis.rows[2][1] = p_mat4[6];
+ // p_mat4[7] = 0;
+ res.basis.rows[0][2] = p_mat4[8];
+ res.basis.rows[1][2] = p_mat4[9];
+ res.basis.rows[2][2] = p_mat4[10];
+ // p_mat4[11] = 0;
+ res.origin.x = p_mat4[12];
+ res.origin.y = p_mat4[13];
+ res.origin.z = p_mat4[14];
+ // p_mat4[15] = 1;
+
+ return res;
+}
+
+void FeedEffects::draw() {
+ bool success = feed.shader.version_bind_shader(feed.shader_version, FeedShaderGLES3::MODE_DEFAULT, FeedShaderGLES3::USE_EXTERNAL_SAMPLER);
+ if (!success) {
+ OS::get_singleton()->print("Godot : FeedShaderGLES3 Could not bind version_bind_shader USE_EXTERNAL_SAMPLER");
+ return;
+ }
+
+ draw_screen_triangle();
+}
+
+void FeedEffects::draw_screen_triangle() {
+ glBindVertexArray(screen_triangle_array);
+ glDrawArrays(GL_TRIANGLES, 0, 3);
+ glBindVertexArray(0);
+}
+
+#endif // GLES3_ENABLED
diff --git a/drivers/gles3/effects/feed_effects.h b/drivers/gles3/effects/feed_effects.h
new file mode 100644
index 0000000000..5856a3e04b
--- /dev/null
+++ b/drivers/gles3/effects/feed_effects.h
@@ -0,0 +1,68 @@
+/**************************************************************************/
+/* feed_effects.h */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#ifndef FEED_EFFECTS_GLES3_H
+#define FEED_EFFECTS_GLES3_H
+
+#ifdef GLES3_ENABLED
+
+#include "drivers/gles3/shaders/feed.glsl.gen.h"
+
+namespace GLES3 {
+
+class FeedEffects {
+private:
+ struct Feed {
+ FeedShaderGLES3 shader;
+ RID shader_version;
+ } feed;
+
+ static FeedEffects *singleton;
+
+ GLuint screen_triangle = 0;
+ GLuint screen_triangle_array = 0;
+
+public:
+ static FeedEffects *get_singleton();
+
+ FeedEffects();
+ ~FeedEffects();
+
+ void draw();
+
+private:
+ void draw_screen_triangle();
+};
+
+} // namespace GLES3
+
+#endif // GLES3_ENABLED
+
+#endif // FEED_EFFECTS_GLES3_H
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index 3c959f0143..0138f99d50 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -1654,28 +1654,39 @@ void RasterizerCanvasGLES3::light_update_shadow(RID p_rid, int p_shadow_index, c
return;
}
- for (int i = 0; i < 4; i++) {
- glViewport((state.shadow_texture_size / 4) * i, p_shadow_index * 2, (state.shadow_texture_size / 4), 2);
+ Projection projection;
+ {
+ real_t fov = 90;
+ real_t nearp = p_near;
+ real_t farp = p_far;
+ real_t aspect = 1.0;
- Projection projection;
- {
- real_t fov = 90;
- real_t nearp = p_near;
- real_t farp = p_far;
- real_t aspect = 1.0;
+ real_t ymax = nearp * Math::tan(Math::deg_to_rad(fov * 0.5));
+ real_t ymin = -ymax;
+ real_t xmin = ymin * aspect;
+ real_t xmax = ymax * aspect;
- real_t ymax = nearp * Math::tan(Math::deg_to_rad(fov * 0.5));
- real_t ymin = -ymax;
- real_t xmin = ymin * aspect;
- real_t xmax = ymax * aspect;
+ projection.set_frustum(xmin, xmax, ymin, ymax, nearp, farp);
+ }
- projection.set_frustum(xmin, xmax, ymin, ymax, nearp, farp);
- }
+ // Precomputed:
+ // Vector3 cam_target = Basis::from_euler(Vector3(0, 0, Math_TAU * ((i + 3) / 4.0))).xform(Vector3(0, 1, 0));
+ // projection = projection * Projection(Transform3D().looking_at(cam_targets[i], Vector3(0, 0, -1)).affine_inverse());
+ const Projection projections[4] = {
+ projection * Projection(Vector4(0, 0, -1, 0), Vector4(1, 0, 0, 0), Vector4(0, -1, 0, 0), Vector4(0, 0, 0, 1)),
- Vector3 cam_target = Basis::from_euler(Vector3(0, 0, Math_TAU * ((i + 3) / 4.0))).xform(Vector3(0, 1, 0));
+ projection * Projection(Vector4(-1, 0, 0, 0), Vector4(0, 0, -1, 0), Vector4(0, -1, 0, 0), Vector4(0, 0, 0, 1)),
+
+ projection * Projection(Vector4(0, 0, 1, 0), Vector4(-1, 0, 0, 0), Vector4(0, -1, 0, 0), Vector4(0, 0, 0, 1)),
+
+ projection * Projection(Vector4(1, 0, 0, 0), Vector4(0, 0, 1, 0), Vector4(0, -1, 0, 0), Vector4(0, 0, 0, 1))
+
+ };
+
+ for (int i = 0; i < 4; i++) {
+ glViewport((state.shadow_texture_size / 4) * i, p_shadow_index * 2, (state.shadow_texture_size / 4), 2);
- projection = projection * Projection(Transform3D().looking_at(cam_target, Vector3(0, 0, -1)).affine_inverse());
- shadow_render.shader.version_set_uniform(CanvasOcclusionShaderGLES3::PROJECTION, projection, shadow_render.shader_version, variant);
+ shadow_render.shader.version_set_uniform(CanvasOcclusionShaderGLES3::PROJECTION, projections[i], shadow_render.shader_version, variant);
static const Vector2 directions[4] = { Vector2(1, 0), Vector2(0, 1), Vector2(-1, 0), Vector2(0, -1) };
shadow_render.shader.version_set_uniform(CanvasOcclusionShaderGLES3::DIRECTION, directions[i].x, directions[i].y, shadow_render.shader_version, variant);
diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp
index 843b6eac05..0fda42979f 100644
--- a/drivers/gles3/rasterizer_gles3.cpp
+++ b/drivers/gles3/rasterizer_gles3.cpp
@@ -218,6 +218,7 @@ void RasterizerGLES3::finalize() {
memdelete(glow);
memdelete(cubemap_filter);
memdelete(copy_effects);
+ memdelete(feed_effects);
memdelete(light_storage);
memdelete(particles_storage);
memdelete(mesh_storage);
@@ -366,6 +367,7 @@ RasterizerGLES3::RasterizerGLES3() {
cubemap_filter = memnew(GLES3::CubemapFilter);
glow = memnew(GLES3::Glow);
post_effects = memnew(GLES3::PostEffects);
+ feed_effects = memnew(GLES3::FeedEffects);
gi = memnew(GLES3::GI);
fog = memnew(GLES3::Fog);
canvas = memnew(RasterizerCanvasGLES3());
diff --git a/drivers/gles3/rasterizer_gles3.h b/drivers/gles3/rasterizer_gles3.h
index 6765d8b4d5..abda2a5e06 100644
--- a/drivers/gles3/rasterizer_gles3.h
+++ b/drivers/gles3/rasterizer_gles3.h
@@ -35,6 +35,7 @@
#include "effects/copy_effects.h"
#include "effects/cubemap_filter.h"
+#include "effects/feed_effects.h"
#include "effects/glow.h"
#include "effects/post_effects.h"
#include "environment/fog.h"
@@ -78,6 +79,7 @@ protected:
GLES3::CubemapFilter *cubemap_filter = nullptr;
GLES3::Glow *glow = nullptr;
GLES3::PostEffects *post_effects = nullptr;
+ GLES3::FeedEffects *feed_effects = nullptr;
RasterizerCanvasGLES3 *canvas = nullptr;
RasterizerSceneGLES3 *scene = nullptr;
static RasterizerGLES3 *singleton;
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index a73f14c796..537076d4ed 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -31,6 +31,7 @@
#include "rasterizer_scene_gles3.h"
#include "drivers/gles3/effects/copy_effects.h"
+#include "drivers/gles3/effects/feed_effects.h"
#include "rasterizer_gles3.h"
#include "storage/config.h"
#include "storage/mesh_storage.h"
@@ -39,6 +40,8 @@
#include "core/config/project_settings.h"
#include "core/templates/sort_array.h"
+#include "servers/camera/camera_feed.h"
+#include "servers/camera_server.h"
#include "servers/rendering/rendering_server_default.h"
#include "servers/rendering/rendering_server_globals.h"
@@ -2259,6 +2262,7 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_
render_data.inv_cam_transform = render_data.cam_transform.affine_inverse();
render_data.cam_projection = p_camera_data->main_projection;
render_data.cam_orthogonal = p_camera_data->is_orthogonal;
+ render_data.cam_frustum = p_camera_data->is_frustum;
render_data.camera_visible_layers = p_camera_data->visible_layers;
render_data.main_cam_transform = p_camera_data->main_transform;
@@ -2382,7 +2386,9 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_
bool draw_sky = false;
bool draw_sky_fog_only = false;
bool keep_color = false;
+ bool draw_feed = false;
float sky_energy_multiplier = 1.0;
+ int camera_feed_id = -1;
if (unlikely(get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW)) {
clear_color = Color(0, 0, 0, 1); //in overdraw mode, BG should always be black
@@ -2427,6 +2433,8 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_
keep_color = true;
} break;
case RS::ENV_BG_CAMERA_FEED: {
+ camera_feed_id = environment_get_camera_feed_id(render_data.environment);
+ draw_feed = true;
} break;
default: {
}
@@ -2538,7 +2546,7 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_
glClear(GL_DEPTH_BUFFER_BIT);
}
- if (!keep_color) {
+ if (!keep_color && !draw_feed) {
clear_color.a = render_data.transparent_bg ? 0.0f : 1.0f;
glClearBufferfv(GL_COLOR, 0, clear_color.components);
} else if (fbo != rt->fbo) {
@@ -2578,6 +2586,29 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_
spec_constant_base_flags |= SceneShaderGLES3::APPLY_TONEMAPPING;
}
}
+
+ if (draw_feed && camera_feed_id > -1) {
+ RENDER_TIMESTAMP("Render Camera feed");
+
+ scene_state.enable_gl_depth_draw(false);
+ scene_state.enable_gl_depth_test(false);
+ scene_state.enable_gl_blend(false);
+ scene_state.set_gl_cull_mode(GLES3::SceneShaderData::CULL_BACK);
+
+ Ref<CameraFeed> feed = CameraServer::get_singleton()->get_feed_by_id(camera_feed_id);
+
+ if (feed.is_valid()) {
+ RID camera_YCBCR = feed->get_texture(CameraServer::FEED_YCBCR_IMAGE);
+ GLES3::TextureStorage::get_singleton()->texture_bind(camera_YCBCR, 0);
+
+ GLES3::FeedEffects *feed_effects = GLES3::FeedEffects::get_singleton();
+ feed_effects->draw();
+ }
+ scene_state.enable_gl_depth_draw(true);
+ scene_state.enable_gl_depth_test(true);
+ scene_state.enable_gl_blend(true);
+ }
+
// Render Opaque Objects.
RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, spec_constant_base_flags, use_wireframe);
@@ -2592,14 +2623,18 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_
scene_state.enable_gl_blend(false);
scene_state.set_gl_cull_mode(GLES3::SceneShaderData::CULL_BACK);
+ Transform3D transform = render_data.cam_transform;
Projection projection = render_data.cam_projection;
if (is_reflection_probe) {
Projection correction;
correction.columns[1][1] = -1.0;
projection = correction * render_data.cam_projection;
+ } else if (render_data.cam_frustum) {
+ // Sky is drawn upside down, the frustum offset doesn't know the image is upside down so needs a flip.
+ projection[2].y = -projection[2].y;
}
- _draw_sky(render_data.environment, projection, render_data.cam_transform, sky_energy_multiplier, render_data.luminance_multiplier, p_camera_data->view_count > 1, flip_y, apply_color_adjustments_in_post);
+ _draw_sky(render_data.environment, projection, transform, sky_energy_multiplier, render_data.luminance_multiplier, p_camera_data->view_count > 1, flip_y, apply_color_adjustments_in_post);
}
if (rt && (scene_state.used_screen_texture || scene_state.used_depth_texture)) {
diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h
index 06371b2b7f..4f088a0e7d 100644
--- a/drivers/gles3/rasterizer_scene_gles3.h
+++ b/drivers/gles3/rasterizer_scene_gles3.h
@@ -103,6 +103,7 @@ struct RenderDataGLES3 {
Transform3D inv_cam_transform;
Projection cam_projection;
bool cam_orthogonal = false;
+ bool cam_frustum = false;
uint32_t camera_visible_layers = 0xFFFFFFFF;
// For billboards to cast correct shadows.
diff --git a/drivers/gles3/shader_gles3.cpp b/drivers/gles3/shader_gles3.cpp
index b73debf04a..83f74865f6 100644
--- a/drivers/gles3/shader_gles3.cpp
+++ b/drivers/gles3/shader_gles3.cpp
@@ -168,6 +168,10 @@ void ShaderGLES3::_build_variant_code(StringBuilder &builder, uint32_t p_variant
builder.append("#version 300 es\n");
}
+ if (GLES3::Config::get_singleton()->polyfill_half2float) {
+ builder.append("#define USE_HALF2FLOAT\n");
+ }
+
for (int i = 0; i < specialization_count; i++) {
if (p_specialization & (uint64_t(1) << uint64_t(i))) {
builder.append("#define " + String(specializations[i].name) + "\n");
diff --git a/drivers/gles3/shaders/SCsub b/drivers/gles3/shaders/SCsub
index df2c515035..0207ba12b7 100644
--- a/drivers/gles3/shaders/SCsub
+++ b/drivers/gles3/shaders/SCsub
@@ -17,6 +17,7 @@ if "GLES3_GLSL" in env["BUILDERS"]:
# as we have a few, not yet, converted files we name the ones we want to include:
env.GLES3_GLSL("canvas.glsl")
+ env.GLES3_GLSL("feed.glsl")
env.GLES3_GLSL("scene.glsl")
env.GLES3_GLSL("sky.glsl")
env.GLES3_GLSL("canvas_occlusion.glsl")
diff --git a/drivers/gles3/shaders/feed.glsl b/drivers/gles3/shaders/feed.glsl
new file mode 100644
index 0000000000..9d89fc699d
--- /dev/null
+++ b/drivers/gles3/shaders/feed.glsl
@@ -0,0 +1,39 @@
+/* clang-format off */
+#[modes]
+
+mode_default =
+
+#[specializations]
+
+USE_EXTERNAL_SAMPLER = false
+
+#[vertex]
+
+layout(location = 0) in vec2 vertex_attrib;
+
+out vec2 uv_interp;
+
+
+void main() {
+ uv_interp = vertex_attrib * 0.5 + 0.5;
+ gl_Position = vec4(vertex_attrib, 1.0, 1.0);
+}
+
+/* clang-format off */
+#[fragment]
+
+layout(location = 0) out vec4 frag_color;
+in vec2 uv_interp;
+
+/* clang-format on */
+#ifdef USE_EXTERNAL_SAMPLER
+uniform samplerExternalOES sourceFeed; // texunit:0
+#else
+uniform sampler2D sourceFeed; // texunit:0
+#endif
+
+void main() {
+ vec4 color = texture(sourceFeed, uv_interp);
+
+ frag_color = color;
+}
diff --git a/drivers/gles3/shaders/stdlib_inc.glsl b/drivers/gles3/shaders/stdlib_inc.glsl
index f88c218506..004db9e5d0 100644
--- a/drivers/gles3/shaders/stdlib_inc.glsl
+++ b/drivers/gles3/shaders/stdlib_inc.glsl
@@ -1,25 +1,28 @@
-
// Compatibility renames. These are exposed with the "godot_" prefix
// to work around two distinct Adreno bugs:
// 1. Some Adreno devices expose ES310 functions in ES300 shaders.
// Internally, we must use the "godot_" prefix, but user shaders
// will be mapped automatically.
// 2. Adreno 3XX devices have poor implementations of the other packing
-// functions, so we just use our own everywhere to keep it simple.
+// functions, so we just use our own there to keep it simple.
+#ifdef USE_HALF2FLOAT
// Floating point pack/unpack functions are part of the GLSL ES 300 specification used by web and mobile.
+// It appears to be safe to expose these on mobile, but when running through ANGLE this appears to break.
uint float2half(uint f) {
- uint b = f + uint(0x00001000);
- uint e = (b & uint(0x7F800000)) >> 23;
- uint m = b & uint(0x007FFFFF);
- return (b & uint(0x80000000)) >> uint(16) | uint(e > uint(112)) * ((((e - uint(112)) << uint(10)) & uint(0x7C00)) | m >> uint(13)) | (uint(e < uint(113)) & uint(e > uint(101))) * ((((uint(0x007FF000) + m) >> (uint(125) - e)) + uint(1)) >> uint(1)) | uint(e > uint(143)) * uint(0x7FFF);
+ uint e = f & uint(0x7f800000);
+ if (e <= uint(0x38000000)) {
+ return uint(0);
+ } else {
+ return ((f >> uint(16)) & uint(0x8000)) |
+ (((e - uint(0x38000000)) >> uint(13)) & uint(0x7c00)) |
+ ((f >> uint(13)) & uint(0x03ff));
+ }
}
uint half2float(uint h) {
- uint e = (h & uint(0x7C00)) >> uint(10);
- uint m = (h & uint(0x03FF)) << uint(13);
- uint v = m >> uint(23);
- return (h & uint(0x8000)) << uint(16) | uint(e != uint(0)) * ((e + uint(112)) << uint(23) | m) | (uint(e == uint(0)) & uint(m != uint(0))) * ((v - uint(37)) << uint(23) | ((m << (uint(150) - v)) & uint(0x007FE000)));
+ uint h_e = h & uint(0x7c00);
+ return ((h & uint(0x8000)) << uint(16)) | uint((h_e >> uint(10)) != uint(0)) * (((h_e + uint(0x1c000)) << uint(13)) | ((h & uint(0x03ff)) << uint(13)));
}
uint godot_packHalf2x16(vec2 v) {
@@ -50,6 +53,17 @@ vec2 godot_unpackSnorm2x16(uint p) {
return clamp((v - 32767.0) * vec2(0.00003051851), vec2(-1.0), vec2(1.0));
}
+#define packHalf2x16 godot_packHalf2x16
+#define unpackHalf2x16 godot_unpackHalf2x16
+#define packUnorm2x16 godot_packUnorm2x16
+#define unpackUnorm2x16 godot_unpackUnorm2x16
+#define packSnorm2x16 godot_packSnorm2x16
+#define unpackSnorm2x16 godot_unpackSnorm2x16
+
+#endif // USE_HALF2FLOAT
+
+// Always expose these as they are ES310 functions and not available in ES300 or GLSL 330.
+
uint godot_packUnorm4x8(vec4 v) {
uvec4 uv = uvec4(round(clamp(v, vec4(0.0), vec4(1.0)) * 255.0));
return uv.x | (uv.y << uint(8)) | (uv.z << uint(16)) | (uv.w << uint(24));
@@ -73,9 +87,3 @@ vec4 godot_unpackSnorm4x8(uint p) {
#define unpackUnorm4x8 godot_unpackUnorm4x8
#define packSnorm4x8 godot_packSnorm4x8
#define unpackSnorm4x8 godot_unpackSnorm4x8
-#define packHalf2x16 godot_packHalf2x16
-#define unpackHalf2x16 godot_unpackHalf2x16
-#define packUnorm2x16 godot_packUnorm2x16
-#define unpackUnorm2x16 godot_unpackUnorm2x16
-#define packSnorm2x16 godot_packSnorm2x16
-#define unpackSnorm2x16 godot_unpackSnorm2x16
diff --git a/drivers/gles3/storage/config.cpp b/drivers/gles3/storage/config.cpp
index 209b7dd7d2..07dd5f58c1 100644
--- a/drivers/gles3/storage/config.cpp
+++ b/drivers/gles3/storage/config.cpp
@@ -231,6 +231,13 @@ Config::Config() {
} else if (rendering_device_name == "PowerVR Rogue GE8320") {
disable_transform_feedback_shader_cache = true;
}
+
+ if (OS::get_singleton()->get_current_rendering_driver_name() == "opengl3_angle") {
+ polyfill_half2float = false;
+ }
+#ifdef WEB_ENABLED
+ polyfill_half2float = false;
+#endif
}
Config::~Config() {
diff --git a/drivers/gles3/storage/config.h b/drivers/gles3/storage/config.h
index d60f295d66..51f6714320 100644
--- a/drivers/gles3/storage/config.h
+++ b/drivers/gles3/storage/config.h
@@ -95,13 +95,16 @@ public:
bool multiview_supported = false;
bool external_texture_supported = false;
- // Adreno 3XX compatibility
- bool disable_particles_workaround = false; // set to 'true' to disable 'GPUParticles'
+ // Adreno 3XX compatibility.
+ bool disable_particles_workaround = false; // Set to 'true' to disable 'GPUParticles'.
bool flip_xy_workaround = false;
- // PowerVR GE 8320 workaround
+ // PowerVR GE 8320 workaround.
bool disable_transform_feedback_shader_cache = false;
+ // ANGLE shader workaround.
+ bool polyfill_half2float = true;
+
#ifdef ANDROID_ENABLED
PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC eglFramebufferTextureMultiviewOVR = nullptr;
PFNGLTEXSTORAGE3DMULTISAMPLEPROC eglTexStorage3DMultisample = nullptr;
@@ -110,7 +113,7 @@ public:
PFNEGLIMAGETARGETTEXTURE2DOESPROC eglEGLImageTargetTexture2DOES = nullptr;
#endif
- static Config *get_singleton() { return singleton; };
+ static Config *get_singleton() { return singleton; }
Config();
~Config();
diff --git a/drivers/gles3/storage/light_storage.cpp b/drivers/gles3/storage/light_storage.cpp
index 9b976c2206..9b81430d45 100644
--- a/drivers/gles3/storage/light_storage.cpp
+++ b/drivers/gles3/storage/light_storage.cpp
@@ -213,6 +213,23 @@ void LightStorage::light_set_cull_mask(RID p_light, uint32_t p_mask) {
light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
}
+void LightStorage::light_set_shadow_caster_mask(RID p_light, uint32_t p_caster_mask) {
+ Light *light = light_owner.get_or_null(p_light);
+ ERR_FAIL_NULL(light);
+
+ light->shadow_caster_mask = p_caster_mask;
+
+ light->version++;
+ light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
+}
+
+uint32_t LightStorage::light_get_shadow_caster_mask(RID p_light) const {
+ Light *light = light_owner.get_or_null(p_light);
+ ERR_FAIL_NULL_V(light, 0);
+
+ return light->shadow_caster_mask;
+}
+
void LightStorage::light_set_distance_fade(RID p_light, bool p_enabled, float p_begin, float p_shadow, float p_length) {
Light *light = light_owner.get_or_null(p_light);
ERR_FAIL_NULL(light);
diff --git a/drivers/gles3/storage/light_storage.h b/drivers/gles3/storage/light_storage.h
index ed00dd235f..0695102640 100644
--- a/drivers/gles3/storage/light_storage.h
+++ b/drivers/gles3/storage/light_storage.h
@@ -59,6 +59,7 @@ struct Light {
RS::LightBakeMode bake_mode = RS::LIGHT_BAKE_DYNAMIC;
uint32_t max_sdfgi_cascade = 2;
uint32_t cull_mask = 0xFFFFFFFF;
+ uint32_t shadow_caster_mask = 0xFFFFFFFF;
bool distance_fade = false;
real_t distance_fade_begin = 40.0;
real_t distance_fade_shadow = 50.0;
@@ -305,8 +306,8 @@ public:
/* Light API */
- Light *get_light(RID p_rid) { return light_owner.get_or_null(p_rid); };
- bool owns_light(RID p_rid) { return light_owner.owns(p_rid); };
+ Light *get_light(RID p_rid) { return light_owner.get_or_null(p_rid); }
+ bool owns_light(RID p_rid) { return light_owner.owns(p_rid); }
void _light_initialize(RID p_rid, RS::LightType p_type);
@@ -327,6 +328,8 @@ public:
virtual void light_set_cull_mask(RID p_light, uint32_t p_mask) override;
virtual void light_set_distance_fade(RID p_light, bool p_enabled, float p_begin, float p_shadow, float p_length) override;
virtual void light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) override;
+ virtual void light_set_shadow_caster_mask(RID p_light, uint32_t p_caster_mask) override;
+ virtual uint32_t light_get_shadow_caster_mask(RID p_light) const override;
virtual void light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode) override;
virtual void light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) override {}
@@ -431,8 +434,8 @@ public:
/* LIGHT INSTANCE API */
- LightInstance *get_light_instance(RID p_rid) { return light_instance_owner.get_or_null(p_rid); };
- bool owns_light_instance(RID p_rid) { return light_instance_owner.owns(p_rid); };
+ LightInstance *get_light_instance(RID p_rid) { return light_instance_owner.get_or_null(p_rid); }
+ bool owns_light_instance(RID p_rid) { return light_instance_owner.owns(p_rid); }
virtual RID light_instance_create(RID p_light) override;
virtual void light_instance_free(RID p_light_instance) override;
@@ -630,8 +633,8 @@ public:
/* PROBE API */
- ReflectionProbe *get_reflection_probe(RID p_rid) { return reflection_probe_owner.get_or_null(p_rid); };
- bool owns_reflection_probe(RID p_rid) { return reflection_probe_owner.owns(p_rid); };
+ ReflectionProbe *get_reflection_probe(RID p_rid) { return reflection_probe_owner.get_or_null(p_rid); }
+ bool owns_reflection_probe(RID p_rid) { return reflection_probe_owner.owns(p_rid); }
virtual RID reflection_probe_allocate() override;
virtual void reflection_probe_initialize(RID p_rid) override;
@@ -712,8 +715,8 @@ public:
/* LIGHTMAP CAPTURE */
- Lightmap *get_lightmap(RID p_rid) { return lightmap_owner.get_or_null(p_rid); };
- bool owns_lightmap(RID p_rid) { return lightmap_owner.owns(p_rid); };
+ Lightmap *get_lightmap(RID p_rid) { return lightmap_owner.get_or_null(p_rid); }
+ bool owns_lightmap(RID p_rid) { return lightmap_owner.owns(p_rid); }
virtual RID lightmap_allocate() override;
virtual void lightmap_initialize(RID p_rid) override;
@@ -736,15 +739,15 @@ public:
/* LIGHTMAP INSTANCE */
- LightmapInstance *get_lightmap_instance(RID p_rid) { return lightmap_instance_owner.get_or_null(p_rid); };
- bool owns_lightmap_instance(RID p_rid) { return lightmap_instance_owner.owns(p_rid); };
+ LightmapInstance *get_lightmap_instance(RID p_rid) { return lightmap_instance_owner.get_or_null(p_rid); }
+ bool owns_lightmap_instance(RID p_rid) { return lightmap_instance_owner.owns(p_rid); }
virtual RID lightmap_instance_create(RID p_lightmap) override;
virtual void lightmap_instance_free(RID p_lightmap) override;
virtual void lightmap_instance_set_transform(RID p_lightmap, const Transform3D &p_transform) override;
/* SHADOW ATLAS API */
- bool owns_shadow_atlas(RID p_rid) { return shadow_atlas_owner.owns(p_rid); };
+ bool owns_shadow_atlas(RID p_rid) { return shadow_atlas_owner.owns(p_rid); }
virtual RID shadow_atlas_create() override;
virtual void shadow_atlas_free(RID p_atlas) override;
diff --git a/drivers/gles3/storage/material_storage.cpp b/drivers/gles3/storage/material_storage.cpp
index 684f179492..04cbf7f2cd 100644
--- a/drivers/gles3/storage/material_storage.cpp
+++ b/drivers/gles3/storage/material_storage.cpp
@@ -1237,6 +1237,8 @@ MaterialStorage::MaterialStorage() {
actions.renames["PI"] = _MKSTR(Math_PI);
actions.renames["TAU"] = _MKSTR(Math_TAU);
actions.renames["E"] = _MKSTR(Math_E);
+ actions.renames["OUTPUT_IS_SRGB"] = "SHADER_IS_SRGB";
+ actions.renames["CLIP_SPACE_FAR"] = "SHADER_SPACE_FAR";
actions.renames["VIEWPORT_SIZE"] = "scene_data.viewport_size";
actions.renames["FRAGCOORD"] = "gl_FragCoord";
@@ -1276,8 +1278,6 @@ MaterialStorage::MaterialStorage() {
actions.renames["CUSTOM1"] = "custom1_attrib";
actions.renames["CUSTOM2"] = "custom2_attrib";
actions.renames["CUSTOM3"] = "custom3_attrib";
- actions.renames["OUTPUT_IS_SRGB"] = "SHADER_IS_SRGB";
- actions.renames["CLIP_SPACE_FAR"] = "SHADER_SPACE_FAR";
actions.renames["LIGHT_VERTEX"] = "light_vertex";
actions.renames["NODE_POSITION_WORLD"] = "model_matrix[3].xyz";
diff --git a/drivers/gles3/storage/material_storage.h b/drivers/gles3/storage/material_storage.h
index 392ebcc570..6c21abc276 100644
--- a/drivers/gles3/storage/material_storage.h
+++ b/drivers/gles3/storage/material_storage.h
@@ -576,8 +576,8 @@ public:
/* SHADER API */
- Shader *get_shader(RID p_rid) { return shader_owner.get_or_null(p_rid); };
- bool owns_shader(RID p_rid) { return shader_owner.owns(p_rid); };
+ Shader *get_shader(RID p_rid) { return shader_owner.get_or_null(p_rid); }
+ bool owns_shader(RID p_rid) { return shader_owner.owns(p_rid); }
void _shader_make_dirty(Shader *p_shader);
@@ -598,8 +598,8 @@ public:
/* MATERIAL API */
- Material *get_material(RID p_rid) { return material_owner.get_or_null(p_rid); };
- bool owns_material(RID p_rid) { return material_owner.owns(p_rid); };
+ Material *get_material(RID p_rid) { return material_owner.get_or_null(p_rid); }
+ bool owns_material(RID p_rid) { return material_owner.owns(p_rid); }
void _material_queue_update(Material *material, bool p_uniform, bool p_texture);
void _update_queued_materials();
diff --git a/drivers/gles3/storage/mesh_storage.h b/drivers/gles3/storage/mesh_storage.h
index 8615b89a30..0bb20bd369 100644
--- a/drivers/gles3/storage/mesh_storage.h
+++ b/drivers/gles3/storage/mesh_storage.h
@@ -280,8 +280,8 @@ public:
/* MESH API */
- Mesh *get_mesh(RID p_rid) { return mesh_owner.get_or_null(p_rid); };
- bool owns_mesh(RID p_rid) { return mesh_owner.owns(p_rid); };
+ Mesh *get_mesh(RID p_rid) { return mesh_owner.get_or_null(p_rid); }
+ bool owns_mesh(RID p_rid) { return mesh_owner.owns(p_rid); }
virtual RID mesh_allocate() override;
virtual void mesh_initialize(RID p_rid) override;
@@ -443,8 +443,8 @@ public:
/* MESH INSTANCE API */
- MeshInstance *get_mesh_instance(RID p_rid) { return mesh_instance_owner.get_or_null(p_rid); };
- bool owns_mesh_instance(RID p_rid) { return mesh_instance_owner.owns(p_rid); };
+ MeshInstance *get_mesh_instance(RID p_rid) { return mesh_instance_owner.get_or_null(p_rid); }
+ bool owns_mesh_instance(RID p_rid) { return mesh_instance_owner.owns(p_rid); }
virtual RID mesh_instance_create(RID p_base) override;
virtual void mesh_instance_free(RID p_rid) override;
@@ -492,8 +492,8 @@ public:
/* MULTIMESH API */
- MultiMesh *get_multimesh(RID p_rid) { return multimesh_owner.get_or_null(p_rid); };
- bool owns_multimesh(RID p_rid) { return multimesh_owner.owns(p_rid); };
+ MultiMesh *get_multimesh(RID p_rid) { return multimesh_owner.get_or_null(p_rid); }
+ bool owns_multimesh(RID p_rid) { return multimesh_owner.owns(p_rid); }
virtual RID _multimesh_allocate() override;
virtual void _multimesh_initialize(RID p_rid) override;
@@ -571,8 +571,8 @@ public:
/* SKELETON API */
- Skeleton *get_skeleton(RID p_rid) { return skeleton_owner.get_or_null(p_rid); };
- bool owns_skeleton(RID p_rid) { return skeleton_owner.owns(p_rid); };
+ Skeleton *get_skeleton(RID p_rid) { return skeleton_owner.get_or_null(p_rid); }
+ bool owns_skeleton(RID p_rid) { return skeleton_owner.owns(p_rid); }
virtual RID skeleton_allocate() override;
virtual void skeleton_initialize(RID p_rid) override;
diff --git a/drivers/gles3/storage/particles_storage.h b/drivers/gles3/storage/particles_storage.h
index 086f5f7936..0552a5324f 100644
--- a/drivers/gles3/storage/particles_storage.h
+++ b/drivers/gles3/storage/particles_storage.h
@@ -396,7 +396,7 @@ public:
_FORCE_INLINE_ bool particles_has_collision(RID p_particles) {
Particles *particles = particles_owner.get_or_null(p_particles);
- ERR_FAIL_NULL_V(particles, 0);
+ ERR_FAIL_NULL_V(particles, false);
return particles->has_collision_cache;
}
diff --git a/drivers/gles3/storage/texture_storage.cpp b/drivers/gles3/storage/texture_storage.cpp
index 5f49a84fe8..14bbe635a4 100644
--- a/drivers/gles3/storage/texture_storage.cpp
+++ b/drivers/gles3/storage/texture_storage.cpp
@@ -2452,7 +2452,7 @@ Point2i TextureStorage::render_target_get_position(RID p_render_target) const {
ERR_FAIL_NULL_V(rt, Point2i());
return rt->position;
-};
+}
void TextureStorage::render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) {
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
diff --git a/drivers/gles3/storage/texture_storage.h b/drivers/gles3/storage/texture_storage.h
index d85d10e235..916662dcd6 100644
--- a/drivers/gles3/storage/texture_storage.h
+++ b/drivers/gles3/storage/texture_storage.h
@@ -478,8 +478,8 @@ public:
/* Canvas Texture API */
- CanvasTexture *get_canvas_texture(RID p_rid) { return canvas_texture_owner.get_or_null(p_rid); };
- bool owns_canvas_texture(RID p_rid) { return canvas_texture_owner.owns(p_rid); };
+ CanvasTexture *get_canvas_texture(RID p_rid) { return canvas_texture_owner.get_or_null(p_rid); }
+ bool owns_canvas_texture(RID p_rid) { return canvas_texture_owner.owns(p_rid); }
virtual RID canvas_texture_allocate() override;
virtual void canvas_texture_initialize(RID p_rid) override;
@@ -499,8 +499,8 @@ public:
return texture_owner.get_or_null(texture->proxy_to);
}
return texture;
- };
- bool owns_texture(RID p_rid) { return texture_owner.owns(p_rid); };
+ }
+ bool owns_texture(RID p_rid) { return texture_owner.owns(p_rid); }
void texture_2d_initialize_from_texture(RID p_texture, Texture &p_tex) {
texture_owner.initialize_rid(p_texture, p_tex);
@@ -618,8 +618,8 @@ public:
static GLuint system_fbo;
- RenderTarget *get_render_target(RID p_rid) { return render_target_owner.get_or_null(p_rid); };
- bool owns_render_target(RID p_rid) { return render_target_owner.owns(p_rid); };
+ RenderTarget *get_render_target(RID p_rid) { return render_target_owner.get_or_null(p_rid); }
+ bool owns_render_target(RID p_rid) { return render_target_owner.owns(p_rid); }
void check_backbuffer(RenderTarget *rt, const bool uses_screen_texture, const bool uses_depth_texture);
diff --git a/drivers/gles3/storage/utilities.h b/drivers/gles3/storage/utilities.h
index 7c3b08717e..88ac802018 100644
--- a/drivers/gles3/storage/utilities.h
+++ b/drivers/gles3/storage/utilities.h
@@ -165,8 +165,8 @@ public:
/* VISIBILITY NOTIFIER */
- VisibilityNotifier *get_visibility_notifier(RID p_rid) { return visibility_notifier_owner.get_or_null(p_rid); };
- bool owns_visibility_notifier(RID p_rid) const { return visibility_notifier_owner.owns(p_rid); };
+ VisibilityNotifier *get_visibility_notifier(RID p_rid) { return visibility_notifier_owner.get_or_null(p_rid); }
+ bool owns_visibility_notifier(RID p_rid) const { return visibility_notifier_owner.owns(p_rid); }
virtual RID visibility_notifier_allocate() override;
virtual void visibility_notifier_initialize(RID p_notifier) override;