diff options
Diffstat (limited to 'drivers/gles3')
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; |