diff options
Diffstat (limited to 'drivers')
26 files changed, 568 insertions, 144 deletions
diff --git a/drivers/dummy/rasterizer_dummy.h b/drivers/dummy/rasterizer_dummy.h index c0e07e0b8d..3b31da1dd7 100644 --- a/drivers/dummy/rasterizer_dummy.h +++ b/drivers/dummy/rasterizer_dummy.h @@ -484,6 +484,7 @@ public: void light_set_negative(RID p_light, bool p_enable) {} void light_set_cull_mask(RID p_light, uint32_t p_mask) {} void light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) {} + void light_set_use_gi(RID p_light, bool p_enabled) {} void light_omni_set_shadow_mode(RID p_light, VS::LightOmniShadowMode p_mode) {} void light_omni_set_shadow_detail(RID p_light, VS::LightOmniShadowDetail p_detail) {} @@ -503,6 +504,7 @@ public: AABB light_get_aabb(RID p_light) const { return AABB(); } float light_get_param(RID p_light, VS::LightParam p_param) { return 0.0; } Color light_get_color(RID p_light) { return Color(); } + bool light_get_use_gi(RID p_light) { return false; } uint64_t light_get_version(RID p_light) const { return 0; } /* PROBE API */ diff --git a/drivers/gl_context/SCsub b/drivers/gl_context/SCsub index efb26a7908..ef5b57a0cc 100644 --- a/drivers/gl_context/SCsub +++ b/drivers/gl_context/SCsub @@ -10,7 +10,7 @@ if (env["platform"] in ["haiku", "osx", "windows", "x11"]): ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - env.Append(CPPPATH=[thirdparty_dir]) + env.Prepend(CPPPATH=[thirdparty_dir]) env.Append(CPPFLAGS=['-DGLAD_ENABLED']) env.Append(CPPFLAGS=['-DGLES_OVER_GL']) diff --git a/drivers/gles2/rasterizer_canvas_gles2.cpp b/drivers/gles2/rasterizer_canvas_gles2.cpp index 9eb159cb31..7232d2d95a 100644 --- a/drivers/gles2/rasterizer_canvas_gles2.cpp +++ b/drivers/gles2/rasterizer_canvas_gles2.cpp @@ -943,7 +943,8 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1); } break; - default: {} + default: { + } } } } @@ -1032,7 +1033,8 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1); } break; - default: {} + default: { + } } } } diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index d3c6b041a8..f49f52e47b 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.cpp @@ -202,6 +202,10 @@ Error RasterizerGLES2::is_viable() { return ERR_UNAVAILABLE; } } + + if (GLAD_GL_EXT_framebuffer_multisample) { + glRenderbufferStorageMultisample = glRenderbufferStorageMultisampleEXT; + } #endif // GLES_OVER_GL #endif // GLAD_ENABLED diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp index c996078ba6..55257ab1c5 100644 --- a/drivers/gles2/rasterizer_scene_gles2.cpp +++ b/drivers/gles2/rasterizer_scene_gles2.cpp @@ -42,6 +42,16 @@ #define glClearDepth glClearDepthf #endif +#ifndef GLES_OVER_GL +#ifdef IPHONE_ENABLED +#include <OpenGLES/ES2/glext.h> +//void *glResolveMultisampleFramebufferAPPLE; + +#define GL_READ_FRAMEBUFFER 0x8CA8 +#define GL_DRAW_FRAMEBUFFER 0x8CA9 +#endif +#endif + static const GLenum _cube_side_enum[6] = { GL_TEXTURE_CUBE_MAP_NEGATIVE_X, @@ -480,7 +490,6 @@ RID RasterizerSceneGLES2::reflection_probe_instance_create(RID p_probe) { rpi->current_resolution = 0; rpi->dirty = true; - rpi->last_pass = 0; rpi->index = 0; for (int i = 0; i < 6; i++) { @@ -1149,6 +1158,30 @@ void RasterizerSceneGLES2::_add_geometry_with_material(RasterizerStorageGLES2::G } } +void RasterizerSceneGLES2::_copy_texture_to_front_buffer(GLuint p_texture) { + + //copy to front buffer + glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->fbo); + + glDepthMask(GL_FALSE); + glDisable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); + glDisable(GL_BLEND); + glDepthFunc(GL_LEQUAL); + glColorMask(1, 1, 1, 1); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, p_texture); + + glViewport(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height); + + storage->shaders.copy.bind(); + + storage->bind_quad_array(); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + glBindBuffer(GL_ARRAY_BUFFER, 0); +} + void RasterizerSceneGLES2::_fill_render_list(InstanceBase **p_cull_result, int p_cull_count, bool p_depth_pass, bool p_shadow_pass) { render_pass++; @@ -1208,7 +1241,8 @@ void RasterizerSceneGLES2::_fill_render_list(InstanceBase **p_cull_result, int p } break; - default: {} + default: { + } } } } @@ -1369,7 +1403,8 @@ void RasterizerSceneGLES2::_setup_geometry(RenderList::Element *p_element, Raste glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1); } break; - default: {} + default: { + } } } } @@ -1530,7 +1565,8 @@ void RasterizerSceneGLES2::_setup_geometry(RenderList::Element *p_element, Raste glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1); } break; - default: {} + default: { + } } } } @@ -1550,7 +1586,8 @@ void RasterizerSceneGLES2::_setup_geometry(RenderList::Element *p_element, Raste case VS::INSTANCE_IMMEDIATE: { } break; - default: {} + default: { + } } } @@ -1758,7 +1795,8 @@ void RasterizerSceneGLES2::_render_geometry(RenderList::Element *p_element) { } } break; - default: {} + default: { + } } } @@ -2074,7 +2112,8 @@ void RasterizerSceneGLES2::_setup_light(LightInstance *light, ShadowAtlas *shado } } break; - default: {} + default: { + } } } @@ -2684,7 +2723,11 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const if (storage->frame.current_rt->external.fbo != 0) { current_fb = storage->frame.current_rt->external.fbo; } else { - current_fb = storage->frame.current_rt->fbo; + if (storage->frame.current_rt->multisample_active) { + current_fb = storage->frame.current_rt->multisample_fbo; + } else { + current_fb = storage->frame.current_rt->fbo; + } } env = environment_owner.getornull(p_environment); @@ -2833,19 +2876,66 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const if (storage->frame.current_rt && state.used_screen_texture) { //copy screen texture + + if (storage->frame.current_rt && storage->frame.current_rt->multisample_active) { + // Resolve framebuffer to front buffer before copying +#ifdef GLES_OVER_GL + + glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->multisample_fbo); + glReadBuffer(GL_COLOR_ATTACHMENT0); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, storage->frame.current_rt->fbo); + glBlitFramebuffer(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, 0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST); + + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); +#elif IPHONE_ENABLED + glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->multisample_fbo); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, storage->frame.current_rt->fbo); + glResolveMultisampleFramebufferAPPLE(); + + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); +#else + // In GLES2 Blit is not available, so just copy color texture manually + _copy_texture_to_front_buffer(storage->frame.current_rt->multisample_color); +#endif + } + storage->canvas->_copy_screen(Rect2()); + + if (storage->frame.current_rt && storage->frame.current_rt->multisample_active) { + // Rebind the current framebuffer + glBindFramebuffer(GL_FRAMEBUFFER, current_fb); + glViewport(0, 0, viewport_width, viewport_height); + } } // alpha pass glBlendEquation(GL_FUNC_ADD); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - render_list.sort_by_depth(true); + render_list.sort_by_reverse_depth_and_priority(true); _render_render_list(&render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, cam_transform, p_cam_projection, p_shadow_atlas, env, env_radiance_tex, 0.0, 0.0, reverse_cull, true, false); glDisable(GL_DEPTH_TEST); + if (storage->frame.current_rt && storage->frame.current_rt->multisample_active) { +#ifdef GLES_OVER_GL + + glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->multisample_fbo); + glReadBuffer(GL_COLOR_ATTACHMENT0); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, storage->frame.current_rt->fbo); + glBlitFramebuffer(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, 0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST); + + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); +#else + // In GLES2 Blit is not available, so just copy color texture manually + _copy_texture_to_front_buffer(storage->frame.current_rt->multisample_color); +#endif + } + //#define GLES2_SHADOW_ATLAS_DEBUG_VIEW #ifdef GLES2_SHADOW_ATLAS_DEBUG_VIEW diff --git a/drivers/gles2/rasterizer_scene_gles2.h b/drivers/gles2/rasterizer_scene_gles2.h index f23e45b52f..e5f0bbcbbb 100644 --- a/drivers/gles2/rasterizer_scene_gles2.h +++ b/drivers/gles2/rasterizer_scene_gles2.h @@ -502,7 +502,8 @@ public: enum { MAX_LIGHTS = 255, MAX_REFLECTION_PROBES = 255, - DEFAULT_MAX_ELEMENTS = 65536 + DEFAULT_MAX_ELEMENTS = 65536, + SORT_KEY_PRIORITY_SHIFT = 56 }; int max_elements; @@ -598,6 +599,29 @@ public: } } + struct SortByReverseDepthAndPriority { + + _FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const { + uint32_t layer_A = uint32_t(A->sort_key >> SORT_KEY_PRIORITY_SHIFT); + uint32_t layer_B = uint32_t(B->sort_key >> SORT_KEY_PRIORITY_SHIFT); + if (layer_A == layer_B) { + return A->instance->depth > B->instance->depth; + } else { + return layer_A < layer_B; + } + } + }; + + void sort_by_reverse_depth_and_priority(bool p_alpha) { //used for alpha + + SortArray<Element *, SortByReverseDepthAndPriority> sorter; + if (p_alpha) { + sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count); + } else { + sorter.sort(elements, element_count); + } + } + // element adding and stuff _FORCE_INLINE_ Element *add_element() { @@ -646,6 +670,7 @@ public: void _add_geometry(RasterizerStorageGLES2::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES2::GeometryOwner *p_owner, int p_material, bool p_depth_pass, bool p_shadow_pass); void _add_geometry_with_material(RasterizerStorageGLES2::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES2::GeometryOwner *p_owner, RasterizerStorageGLES2::Material *p_material, bool p_depth_pass, bool p_shadow_pass); + void _copy_texture_to_front_buffer(GLuint texture); void _fill_render_list(InstanceBase **p_cull_result, int p_cull_count, bool p_depth_pass, bool p_shadow_pass); void _render_render_list(RenderList::Element **p_elements, int p_element_count, const Transform &p_view_transform, diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp index b051c7d811..d709056709 100644 --- a/drivers/gles2/rasterizer_storage_gles2.cpp +++ b/drivers/gles2/rasterizer_storage_gles2.cpp @@ -81,6 +81,28 @@ GLuint RasterizerStorageGLES2::system_fbo = 0; #define _DEPTH_COMPONENT24_OES 0x81A6 +#ifndef GLES_OVER_GL +// enable extensions manually for android and ios +#include <dlfcn.h> // needed to load extensions + +#ifdef IPHONE_ENABLED + +#include <OpenGLES/ES2/glext.h> +//void *glRenderbufferStorageMultisampleAPPLE; +//void *glResolveMultisampleFramebufferAPPLE; +#define glRenderbufferStorageMultisample glRenderbufferStorageMultisampleAPPLE +#else + +#include <GLES2/gl2ext.h> +PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT; +PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC glFramebufferTexture2DMultisampleEXT; +#define glRenderbufferStorageMultisample glRenderbufferStorageMultisampleEXT +#define glFramebufferTexture2DMultisample glFramebufferTexture2DMultisampleEXT +#endif + +#define GL_MAX_SAMPLES 0x8D57 +#endif //!GLES_OVER_GL + void RasterizerStorageGLES2::bind_quad_array() const { glBindBuffer(GL_ARRAY_BUFFER, resources.quadie); glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, 0); @@ -774,10 +796,7 @@ Ref<Image> RasterizerStorageGLES2::texture_get_data(RID p_texture, int p_layer) for (int i = 0; i < texture->mipmaps; i++) { - int ofs = 0; - if (i > 0) { - ofs = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, real_format, i - 1); - } + int ofs = Image::get_image_mipmap_offset(texture->alloc_width, texture->alloc_height, real_format, i); if (texture->compressed) { glPixelStorei(GL_PACK_ALIGNMENT, 4); @@ -1557,6 +1576,10 @@ void RasterizerStorageGLES2::shader_get_param_list(RID p_shader, List<PropertyIn case ShaderLanguage::TYPE_FLOAT: { pi.type = Variant::REAL; + if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_RANGE) { + pi.hint = PROPERTY_HINT_RANGE; + pi.hint_string = rtos(u.hint_range[0]) + "," + rtos(u.hint_range[1]) + "," + rtos(u.hint_range[2]); + } } break; case ShaderLanguage::TYPE_VEC2: { @@ -3708,6 +3731,7 @@ RID RasterizerStorageGLES2::light_create(VS::LightType p_type) { light->directional_blend_splits = false; light->directional_range_mode = VS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE; light->reverse_cull = false; + light->use_gi = true; light->version = 0; return light_owner.make_rid(light); @@ -3737,7 +3761,8 @@ void RasterizerStorageGLES2::light_set_param(RID p_light, VS::LightParam p_param light->version++; light->instance_change_notify(true, false); } break; - default: {} + default: { + } } light->param[p_param] = p_value; @@ -3794,6 +3819,16 @@ void RasterizerStorageGLES2::light_set_reverse_cull_face_mode(RID p_light, bool light->instance_change_notify(true, false); } +void RasterizerStorageGLES2::light_set_use_gi(RID p_light, bool p_enabled) { + Light *light = light_owner.getornull(p_light); + ERR_FAIL_COND(!light); + + light->use_gi = p_enabled; + + light->version++; + light->instance_change_notify(true, false); +} + void RasterizerStorageGLES2::light_omni_set_shadow_mode(RID p_light, VS::LightOmniShadowMode p_mode) { Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); @@ -3889,6 +3924,13 @@ Color RasterizerStorageGLES2::light_get_color(RID p_light) { return light->color; } +bool RasterizerStorageGLES2::light_get_use_gi(RID p_light) { + Light *light = light_owner.getornull(p_light); + ERR_FAIL_COND_V(!light, false); + + return light->use_gi; +} + bool RasterizerStorageGLES2::light_has_shadow(RID p_light) const { Light *light = light_owner.getornull(p_light); ERR_FAIL_COND_V(!light, false); @@ -4529,95 +4571,174 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) { if (rt->width <= 0 || rt->height <= 0) return; - Texture *texture = texture_owner.getornull(rt->texture); - ERR_FAIL_COND(!texture); - - // create fbo - - glGenFramebuffers(1, &rt->fbo); - glBindFramebuffer(GL_FRAMEBUFFER, rt->fbo); - - // color - - glGenTextures(1, &rt->color); - glBindTexture(GL_TEXTURE_2D, rt->color); + GLuint color_internal_format; + GLuint color_format; + GLuint color_type = GL_UNSIGNED_BYTE; if (rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rt->width, rt->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + color_internal_format = GL_RGBA; + color_format = GL_RGBA; } else { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, rt->width, rt->height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); + color_internal_format = GL_RGB; + color_format = GL_RGB; } - if (texture->flags & VS::TEXTURE_FLAG_FILTER) { + { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - } else { + /* Front FBO */ - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - } - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + Texture *texture = texture_owner.getornull(rt->texture); + ERR_FAIL_COND(!texture); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->color, 0); + // framebuffer + glGenFramebuffers(1, &rt->fbo); + glBindFramebuffer(GL_FRAMEBUFFER, rt->fbo); - // depth + // color + glGenTextures(1, &rt->color); + glBindTexture(GL_TEXTURE_2D, rt->color); - if (config.support_depth_texture) { - glGenTextures(1, &rt->depth); - glBindTexture(GL_TEXTURE_2D, rt->depth); - glTexImage2D(GL_TEXTURE_2D, 0, config.depth_internalformat, rt->width, rt->height, 0, GL_DEPTH_COMPONENT, config.depth_type, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, color_internal_format, rt->width, rt->height, 0, color_format, color_type, NULL); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + if (texture->flags & VS::TEXTURE_FLAG_FILTER) { - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->depth, 0); - } else { - glGenRenderbuffers(1, &rt->depth); - glBindRenderbuffer(GL_RENDERBUFFER, rt->depth); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } else { - glRenderbufferStorage(GL_RENDERBUFFER, config.depth_internalformat, rt->width, rt->height); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + } - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth); - } + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->color, 0); - if (status != GL_FRAMEBUFFER_COMPLETE) { + // depth - glDeleteFramebuffers(1, &rt->fbo); if (config.support_depth_texture) { - glDeleteTextures(1, &rt->depth); + + glGenTextures(1, &rt->depth); + glBindTexture(GL_TEXTURE_2D, rt->depth); + glTexImage2D(GL_TEXTURE_2D, 0, config.depth_internalformat, rt->width, rt->height, 0, GL_DEPTH_COMPONENT, config.depth_type, NULL); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->depth, 0); } else { - glDeleteRenderbuffers(1, &rt->depth); + + glGenRenderbuffers(1, &rt->depth); + glBindRenderbuffer(GL_RENDERBUFFER, rt->depth); + + glRenderbufferStorage(GL_RENDERBUFFER, config.depth_internalformat, rt->width, rt->height); + + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth); } - glDeleteTextures(1, &rt->color); - rt->fbo = 0; - rt->width = 0; - rt->height = 0; - rt->color = 0; - rt->depth = 0; - texture->tex_id = 0; - texture->active = false; - WARN_PRINT("Could not create framebuffer!!"); - return; + + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + + if (status != GL_FRAMEBUFFER_COMPLETE) { + + glDeleteFramebuffers(1, &rt->fbo); + if (config.support_depth_texture) { + + glDeleteTextures(1, &rt->depth); + } else { + + glDeleteRenderbuffers(1, &rt->depth); + } + + glDeleteTextures(1, &rt->color); + rt->fbo = 0; + rt->width = 0; + rt->height = 0; + rt->color = 0; + rt->depth = 0; + texture->tex_id = 0; + texture->active = false; + WARN_PRINT("Could not create framebuffer!!"); + return; + } + + texture->format = Image::FORMAT_RGBA8; + texture->gl_format_cache = GL_RGBA; + texture->gl_type_cache = GL_UNSIGNED_BYTE; + texture->gl_internal_format_cache = GL_RGBA; + texture->tex_id = rt->color; + texture->width = rt->width; + texture->alloc_width = rt->width; + texture->height = rt->height; + texture->alloc_height = rt->height; + texture->active = true; + + texture_set_flags(rt->texture, texture->flags); } - texture->format = Image::FORMAT_RGBA8; - texture->gl_format_cache = GL_RGBA; - texture->gl_type_cache = GL_UNSIGNED_BYTE; - texture->gl_internal_format_cache = GL_RGBA; - texture->tex_id = rt->color; - texture->width = rt->width; - texture->alloc_width = rt->width; - texture->height = rt->height; - texture->alloc_height = rt->height; - texture->active = true; + /* BACK FBO */ + /* For MSAA */ + + if (rt->msaa != VS::VIEWPORT_MSAA_DISABLED && config.multisample_supported) { + + rt->multisample_active = true; + + static const int msaa_value[] = { 0, 2, 4, 8, 16 }; + int msaa = msaa_value[rt->msaa]; + + int max_samples = 0; + glGetIntegerv(GL_MAX_SAMPLES, &max_samples); + if (msaa > max_samples) { + WARN_PRINTS("MSAA must be <= GL_MAX_SAMPLES, falling-back to GL_MAX_SAMPLES = " + itos(max_samples)); + msaa = max_samples; + } + + //regular fbo + glGenFramebuffers(1, &rt->multisample_fbo); + glBindFramebuffer(GL_FRAMEBUFFER, rt->multisample_fbo); + + glGenRenderbuffers(1, &rt->multisample_depth); + glBindRenderbuffer(GL_RENDERBUFFER, rt->multisample_depth); + glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, config.depth_internalformat, rt->width, rt->height); + + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->multisample_depth); - texture_set_flags(rt->texture, texture->flags); +#if defined(GLES_OVER_GL) || defined(IPHONE_ENABLED) + + glGenRenderbuffers(1, &rt->multisample_color); + glBindRenderbuffer(GL_RENDERBUFFER, rt->multisample_color); + glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, color_internal_format, rt->width, rt->height); + + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rt->multisample_color); +#else + // Render to a texture in android + glGenTextures(1, &rt->multisample_color); + glBindTexture(GL_TEXTURE_2D, rt->multisample_color); + + glTexImage2D(GL_TEXTURE_2D, 0, color_internal_format, rt->width, rt->height, 0, color_format, color_type, NULL); + + // multisample buffer is same size as front buffer, so just use nearest + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + glFramebufferTexture2DMultisample(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->color, 0, msaa); +#endif + + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + + if (status != GL_FRAMEBUFFER_COMPLETE) { + printf("err status: %x\n", status); + _render_target_clear(rt); + ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE); + } + + glBindRenderbuffer(GL_RENDERBUFFER, 0); + + } else { + rt->multisample_active = false; + } glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -4646,7 +4767,7 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) { glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT); - status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) { _render_target_clear(rt); ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE); @@ -4705,6 +4826,20 @@ void RasterizerStorageGLES2::_render_target_clear(RenderTarget *rt) { glDeleteTextures(1, &rt->copy_screen_effect.color); rt->copy_screen_effect.color = 0; } + + if (rt->multisample_active) { + glDeleteFramebuffers(1, &rt->multisample_fbo); + rt->multisample_fbo = 0; + + glDeleteRenderbuffers(1, &rt->multisample_depth); + rt->multisample_depth = 0; +#ifdef GLES_OVER_GL + glDeleteRenderbuffers(1, &rt->multisample_color); +#else + glDeleteTextures(1, &rt->multisample_color); +#endif + rt->multisample_color = 0; + } } RID RasterizerStorageGLES2::render_target_create() { @@ -4880,7 +5015,8 @@ void RasterizerStorageGLES2::render_target_set_flag(RID p_render_target, RenderT _render_target_allocate(rt); } break; - default: {} + default: { + } } } @@ -4905,6 +5041,11 @@ void RasterizerStorageGLES2::render_target_set_msaa(RID p_render_target, VS::Vie if (rt->msaa == p_msaa) return; + if (!config.multisample_supported) { + ERR_PRINT("MSAA not supported on this hardware."); + return; + } + _render_target_clear(rt); rt->msaa = p_msaa; _render_target_allocate(rt); @@ -5428,6 +5569,26 @@ void RasterizerStorageGLES2::initialize() { config.support_npot_repeat_mipmap = config.extensions.has("GL_OES_texture_npot"); #endif + +#ifndef GLES_OVER_GL + //Manually load extensions for android and ios + +#ifdef IPHONE_ENABLED + + //void *gles2_lib = dlopen(NULL, RTLD_LAZY); + //glRenderbufferStorageMultisampleAPPLE = dlsym(gles2_lib, "glRenderbufferStorageMultisampleAPPLE"); + //glResolveMultisampleFramebufferAPPLE = dlsym(gles2_lib, "glResolveMultisampleFramebufferAPPLE"); +#else + + void *gles2_lib = dlopen("libGLESv2.so", RTLD_LAZY); + glRenderbufferStorageMultisampleEXT = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)dlsym(gles2_lib, "glRenderbufferStorageMultisampleEXT"); + glFramebufferTexture2DMultisampleEXT = (PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC)dlsym(gles2_lib, "glFramebufferTexture2DMultisampleEXT"); +#endif +#endif + + // Check for multisample support + config.multisample_supported = config.extensions.has("GL_EXT_framebuffer_multisample") || config.extensions.has("GL_EXT_multisampled_render_to_texture") || config.extensions.has("GL_APPLE_framebuffer_multisample"); + #ifdef GLES_OVER_GL config.use_rgba_2d_shadows = false; config.support_depth_texture = true; diff --git a/drivers/gles2/rasterizer_storage_gles2.h b/drivers/gles2/rasterizer_storage_gles2.h index 2ac68fa47a..3134082e2a 100644 --- a/drivers/gles2/rasterizer_storage_gles2.h +++ b/drivers/gles2/rasterizer_storage_gles2.h @@ -92,6 +92,8 @@ public: bool support_shadow_cubemaps; + bool multisample_supported; + GLuint depth_internalformat; GLuint depth_type; @@ -910,6 +912,7 @@ public: bool shadow; bool negative; bool reverse_cull; + bool use_gi; uint32_t cull_mask; @@ -936,6 +939,7 @@ public: virtual void light_set_negative(RID p_light, bool p_enable); virtual void light_set_cull_mask(RID p_light, uint32_t p_mask); virtual void light_set_reverse_cull_face_mode(RID p_light, bool p_enabled); + virtual void light_set_use_gi(RID p_light, bool p_enabled); virtual void light_omni_set_shadow_mode(RID p_light, VS::LightOmniShadowMode p_mode); virtual void light_omni_set_shadow_detail(RID p_light, VS::LightOmniShadowDetail p_detail); @@ -955,6 +959,7 @@ public: virtual VS::LightType light_get_type(RID p_light) const; virtual float light_get_param(RID p_light, VS::LightParam p_param); virtual Color light_get_color(RID p_light); + virtual bool light_get_use_gi(RID p_light); virtual AABB light_get_aabb(RID p_light) const; virtual uint64_t light_get_version(RID p_light) const; @@ -1129,10 +1134,14 @@ public: struct RenderTarget : public RID_Data { GLuint fbo; - GLuint color; GLuint depth; + GLuint multisample_fbo; + GLuint multisample_color; + GLuint multisample_depth; + bool multisample_active; + // TODO post processing effects? // TODO HDR? @@ -1179,6 +1188,10 @@ public: fbo(0), color(0), depth(0), + multisample_fbo(0), + multisample_color(0), + multisample_depth(0), + multisample_active(false), width(0), height(0), used_in_frame(false), diff --git a/drivers/gles2/shaders/effect_blur.glsl b/drivers/gles2/shaders/effect_blur.glsl index a531802c75..df79e89931 100644 --- a/drivers/gles2/shaders/effect_blur.glsl +++ b/drivers/gles2/shaders/effect_blur.glsl @@ -116,12 +116,13 @@ void main() { #ifdef GAUSSIAN_HORIZONTAL vec2 pix_size = pixel_size; pix_size *= 0.5; //reading from larger buffer, so use more samples + // sigma 2 vec4 color = textureLod(source_color, uv_interp + vec2(0.0, 0.0) * pix_size, lod) * 0.214607; color += textureLod(source_color, uv_interp + vec2(1.0, 0.0) * pix_size, lod) * 0.189879; - color += textureLod(source_color, uv_interp + vec2(2.0, 0.0) * pix_size, lod) * 0.157305; + color += textureLod(source_color, uv_interp + vec2(2.0, 0.0) * pix_size, lod) * 0.131514; color += textureLod(source_color, uv_interp + vec2(3.0, 0.0) * pix_size, lod) * 0.071303; color += textureLod(source_color, uv_interp + vec2(-1.0, 0.0) * pix_size, lod) * 0.189879; - color += textureLod(source_color, uv_interp + vec2(-2.0, 0.0) * pix_size, lod) * 0.157305; + color += textureLod(source_color, uv_interp + vec2(-2.0, 0.0) * pix_size, lod) * 0.131514; color += textureLod(source_color, uv_interp + vec2(-3.0, 0.0) * pix_size, lod) * 0.071303; frag_color = color; #endif diff --git a/drivers/gles2/shaders/scene.glsl b/drivers/gles2/shaders/scene.glsl index 222dcd25cb..34f34f9961 100644 --- a/drivers/gles2/shaders/scene.glsl +++ b/drivers/gles2/shaders/scene.glsl @@ -1548,6 +1548,11 @@ FRAGMENT_SHADER_CODE #ifdef BASE_PASS //none + +#ifdef AMBIENT_LIGHT_DISABLED + ambient_light = vec3(0.0, 0.0, 0.0); +#else + #ifdef USE_RADIANCE_MAP vec3 ref_vec = reflect(-eye_position, N); @@ -1570,6 +1575,7 @@ FRAGMENT_SHADER_CODE #endif +#endif // AMBIENT_LIGHT_DISABLED ambient_light *= ambient_energy; #if defined(USE_REFLECTION_PROBE1) || defined(USE_REFLECTION_PROBE2) @@ -1696,6 +1702,8 @@ FRAGMENT_SHADER_CODE #endif +#if !defined(SHADOWS_DISABLED) + #ifdef USE_SHADOW { highp vec4 splane = shadow_coord; @@ -1726,6 +1734,8 @@ FRAGMENT_SHADER_CODE } #endif +#endif //SHADOWS_DISABLED + #endif //type omni #ifdef LIGHT_MODE_DIRECTIONAL @@ -1736,6 +1746,8 @@ FRAGMENT_SHADER_CODE #endif float depth_z = -vertex.z; +#if !defined(SHADOWS_DISABLED) + #ifdef USE_SHADOW #ifdef USE_VERTEX_LIGHTING @@ -1954,6 +1966,8 @@ FRAGMENT_SHADER_CODE #endif //use shadow +#endif // SHADOWS_DISABLED + #endif #ifdef LIGHT_MODE_SPOT @@ -1990,6 +2004,8 @@ FRAGMENT_SHADER_CODE #endif +#if !defined(SHADOWS_DISABLED) + #ifdef USE_SHADOW { highp vec4 splane = shadow_coord; @@ -1999,6 +2015,8 @@ FRAGMENT_SHADER_CODE } #endif +#endif // SHADOWS_DISABLED + #endif // LIGHT_MODE_SPOT #ifdef USE_VERTEX_LIGHTING diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index b0f1be47a1..30aa22732c 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -826,6 +826,8 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size); } + state.canvas_shader.set_uniform(CanvasShaderGLES3::MODELVIEW_MATRIX, state.final_transform * mesh->transform); + RasterizerStorageGLES3::Mesh *mesh_data = storage->mesh_owner.getornull(mesh->mesh); if (mesh_data) { @@ -834,7 +836,7 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur // materials are ignored in 2D meshes, could be added but many things (ie, lighting mode, reading from screen, etc) would break as they are not meant be set up at this point of drawing glBindVertexArray(s->array_id); - glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1); + glVertexAttrib4f(VS::ARRAY_COLOR, mesh->modulate.r, mesh->modulate.g, mesh->modulate.b, mesh->modulate.a); if (s->index_array_len) { glDrawElements(gl_primitive[s->primitive], s->index_array_len, (s->array_len >= (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0); @@ -845,6 +847,8 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur glBindVertexArray(0); } } + state.canvas_shader.set_uniform(CanvasShaderGLES3::MODELVIEW_MATRIX, state.final_transform); + } break; case Item::Command::TYPE_MULTIMESH: { diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 0460e98e28..9aec348291 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -1061,12 +1061,11 @@ void RasterizerSceneGLES3::gi_probe_instance_set_light_data(RID p_probe, RID p_b if (p_data.is_valid()) { RasterizerStorageGLES3::GIProbeData *gipd = storage->gi_probe_data_owner.getornull(p_data); ERR_FAIL_COND(!gipd); - if (gipd) { - gipi->tex_cache = gipd->tex_id; - gipi->cell_size_cache.x = 1.0 / gipd->width; - gipi->cell_size_cache.y = 1.0 / gipd->height; - gipi->cell_size_cache.z = 1.0 / gipd->depth; - } + + gipi->tex_cache = gipd->tex_id; + gipi->cell_size_cache.x = 1.0 / gipd->width; + gipi->cell_size_cache.y = 1.0 / gipd->height; + gipi->cell_size_cache.z = 1.0 / gipd->depth; } } void RasterizerSceneGLES3::gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform) { @@ -1278,7 +1277,8 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material *p_m } break; - default: {} + default: { + } } } @@ -1525,7 +1525,8 @@ void RasterizerSceneGLES3::_setup_geometry(RenderList::Element *e, const Transfo } } break; - default: {} + default: { + } } } @@ -1847,7 +1848,8 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) { } } break; - default: {} + default: { + } } } @@ -3248,7 +3250,8 @@ void RasterizerSceneGLES3::_fill_render_list(InstanceBase **p_cull_result, int p } } break; - default: {} + default: { + } } } } @@ -3667,7 +3670,7 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p } glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.mip_maps[0].color); - storage->shaders.copy.set_conditional(CopyShaderGLES3::LINEAR_TO_SRGB, true); + storage->shaders.copy.set_conditional(CopyShaderGLES3::LINEAR_TO_SRGB, !storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_KEEP_3D_LINEAR]); storage->shaders.copy.set_conditional(CopyShaderGLES3::V_FLIP, storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP]); storage->shaders.copy.set_conditional(CopyShaderGLES3::DISABLE_ALPHA, !storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]); storage->shaders.copy.bind(); @@ -4423,7 +4426,8 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); break; - default: {} + default: { + } } } diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index 6169790163..661be28e6b 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -642,7 +642,8 @@ void RasterizerStorageGLES3::texture_allocate(RID p_texture, int p_width, int p_ p_flags &= ~VS::TEXTURE_FLAG_FILTER; } } break; - default: {} + default: { + } } #endif @@ -1209,10 +1210,7 @@ Ref<Image> RasterizerStorageGLES3::texture_get_data(RID p_texture, int p_layer) for (int i = 0; i < texture->mipmaps; i++) { - int ofs = 0; - if (i > 0) { - ofs = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, real_format, i - 1); - } + int ofs = Image::get_image_mipmap_offset(texture->alloc_width, texture->alloc_height, real_format, i); if (texture->compressed) { @@ -2751,7 +2749,8 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy gui[14] = v.origin.z; gui[15] = 1; } break; - default: {} + default: { + } } } @@ -2919,7 +2918,8 @@ _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type, gui[i] = value[i].real; } } break; - default: {} + default: { + } } } @@ -2962,7 +2962,8 @@ _FORCE_INLINE_ static void _fill_std140_ubo_empty(ShaderLanguage::DataType type, zeromem(data, 64); } break; - default: {} + default: { + } } } @@ -5215,6 +5216,7 @@ RID RasterizerStorageGLES3::light_create(VS::LightType p_type) { light->directional_blend_splits = false; light->directional_range_mode = VS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE; light->reverse_cull = false; + light->use_gi = true; light->version = 0; return light_owner.make_rid(light); @@ -5246,7 +5248,8 @@ void RasterizerStorageGLES3::light_set_param(RID p_light, VS::LightParam p_param light->version++; light->instance_change_notify(true, false); } break; - default: {} + default: { + } } light->param[p_param] = p_value; @@ -5305,6 +5308,15 @@ void RasterizerStorageGLES3::light_set_reverse_cull_face_mode(RID p_light, bool light->instance_change_notify(true, false); } +void RasterizerStorageGLES3::light_set_use_gi(RID p_light, bool p_enabled) { + Light *light = light_owner.getornull(p_light); + ERR_FAIL_COND(!light); + + light->use_gi = p_enabled; + + light->version++; + light->instance_change_notify(true, false); +} void RasterizerStorageGLES3::light_omni_set_shadow_mode(RID p_light, VS::LightOmniShadowMode p_mode) { Light *light = light_owner.getornull(p_light); @@ -5410,6 +5422,13 @@ Color RasterizerStorageGLES3::light_get_color(RID p_light) { return light->color; } +bool RasterizerStorageGLES3::light_get_use_gi(RID p_light) { + Light *light = light_owner.getornull(p_light); + ERR_FAIL_COND_V(!light, false); + + return light->use_gi; +} + bool RasterizerStorageGLES3::light_has_shadow(RID p_light) const { const Light *light = light_owner.getornull(p_light); @@ -5448,7 +5467,8 @@ AABB RasterizerStorageGLES3::light_get_aabb(RID p_light) const { return AABB(); } break; - default: {} + default: { + } } ERR_FAIL_V(AABB()); @@ -7379,7 +7399,8 @@ void RasterizerStorageGLES3::render_target_set_flag(RID p_render_target, RenderT _render_target_allocate(rt); } break; - default: {} + default: { + } } } bool RasterizerStorageGLES3::render_target_was_used(RID p_render_target) { diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h index 92916ed808..a4cc84ef02 100644 --- a/drivers/gles3/rasterizer_storage_gles3.h +++ b/drivers/gles3/rasterizer_storage_gles3.h @@ -930,6 +930,7 @@ public: bool shadow; bool negative; bool reverse_cull; + bool use_gi; uint32_t cull_mask; VS::LightOmniShadowMode omni_shadow_mode; VS::LightOmniShadowDetail omni_shadow_detail; @@ -951,6 +952,7 @@ public: virtual void light_set_negative(RID p_light, bool p_enable); virtual void light_set_cull_mask(RID p_light, uint32_t p_mask); virtual void light_set_reverse_cull_face_mode(RID p_light, bool p_enabled); + virtual void light_set_use_gi(RID p_light, bool p_enabled); virtual void light_omni_set_shadow_mode(RID p_light, VS::LightOmniShadowMode p_mode); virtual void light_omni_set_shadow_detail(RID p_light, VS::LightOmniShadowDetail p_detail); @@ -970,6 +972,7 @@ public: virtual VS::LightType light_get_type(RID p_light) const; virtual float light_get_param(RID p_light, VS::LightParam p_param); virtual Color light_get_color(RID p_light); + virtual bool light_get_use_gi(RID p_light); virtual AABB light_get_aabb(RID p_light) const; virtual uint64_t light_get_version(RID p_light) const; diff --git a/drivers/gles3/shader_gles3.h b/drivers/gles3/shader_gles3.h index 1ed30986bf..be2c34ba07 100644 --- a/drivers/gles3/shader_gles3.h +++ b/drivers/gles3/shader_gles3.h @@ -289,7 +289,9 @@ private: glUniformMatrix4fv(p_uniform, 1, false, matrix); } break; - default: { ERR_FAIL(); } // do nothing + default: { + ERR_FAIL(); + } // do nothing } } diff --git a/drivers/gles3/shaders/effect_blur.glsl b/drivers/gles3/shaders/effect_blur.glsl index fc15ca31b1..ff5a9f326f 100644 --- a/drivers/gles3/shaders/effect_blur.glsl +++ b/drivers/gles3/shaders/effect_blur.glsl @@ -117,12 +117,13 @@ void main() { #ifdef GAUSSIAN_HORIZONTAL vec2 pix_size = pixel_size; pix_size *= 0.5; //reading from larger buffer, so use more samples + // sigma 2 vec4 color = textureLod(source_color, uv_interp + vec2(0.0, 0.0) * pix_size, lod) * 0.214607; color += textureLod(source_color, uv_interp + vec2(1.0, 0.0) * pix_size, lod) * 0.189879; - color += textureLod(source_color, uv_interp + vec2(2.0, 0.0) * pix_size, lod) * 0.157305; + color += textureLod(source_color, uv_interp + vec2(2.0, 0.0) * pix_size, lod) * 0.131514; color += textureLod(source_color, uv_interp + vec2(3.0, 0.0) * pix_size, lod) * 0.071303; color += textureLod(source_color, uv_interp + vec2(-1.0, 0.0) * pix_size, lod) * 0.189879; - color += textureLod(source_color, uv_interp + vec2(-2.0, 0.0) * pix_size, lod) * 0.157305; + color += textureLod(source_color, uv_interp + vec2(-2.0, 0.0) * pix_size, lod) * 0.131514; color += textureLod(source_color, uv_interp + vec2(-3.0, 0.0) * pix_size, lod) * 0.071303; frag_color = color; #endif diff --git a/drivers/png/SCsub b/drivers/png/SCsub index 97ba1de3db..9dc80244ff 100644 --- a/drivers/png/SCsub +++ b/drivers/png/SCsub @@ -26,9 +26,9 @@ if env['builtin_libpng']: ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - env_png.Append(CPPPATH=[thirdparty_dir]) + env_png.Prepend(CPPPATH=[thirdparty_dir]) # Needed for drivers includes and in platform/javascript - env.Append(CPPPATH=[thirdparty_dir]) + env.Prepend(CPPPATH=[thirdparty_dir]) # Currently .ASM filter_neon.S does not compile on NT. import os diff --git a/drivers/unix/file_access_unix.cpp b/drivers/unix/file_access_unix.cpp index 6e045817bc..a285b3b65f 100644 --- a/drivers/unix/file_access_unix.cpp +++ b/drivers/unix/file_access_unix.cpp @@ -293,8 +293,25 @@ uint64_t FileAccessUnix::_get_modified_time(const String &p_file) { }; } -Error FileAccessUnix::_chmod(const String &p_path, int p_mod) { - int err = chmod(p_path.utf8().get_data(), p_mod); +uint32_t FileAccessUnix::_get_unix_permissions(const String &p_file) { + + String file = fix_path(p_file); + struct stat flags; + int err = stat(file.utf8().get_data(), &flags); + + if (!err) { + return flags.st_mode & 0x7FF; //only permissions + } else { + ERR_EXPLAIN("Failed to get unix permissions for: " + p_file); + ERR_FAIL_V(0); + }; +} + +Error FileAccessUnix::_set_unix_permissions(const String &p_file, uint32_t p_permissions) { + + String file = fix_path(p_file); + + int err = chmod(file.utf8().get_data(), p_permissions); if (!err) { return OK; } diff --git a/drivers/unix/file_access_unix.h b/drivers/unix/file_access_unix.h index 6405589b4d..2a369048a4 100644 --- a/drivers/unix/file_access_unix.h +++ b/drivers/unix/file_access_unix.h @@ -85,8 +85,8 @@ public: virtual bool file_exists(const String &p_path); ///< return true if a file exists virtual uint64_t _get_modified_time(const String &p_file); - - virtual Error _chmod(const String &p_path, int p_mod); + virtual uint32_t _get_unix_permissions(const String &p_file); + virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions); FileAccessUnix(); virtual ~FileAccessUnix(); diff --git a/drivers/unix/net_socket_posix.cpp b/drivers/unix/net_socket_posix.cpp index 2dffa083fe..37abccbe27 100644 --- a/drivers/unix/net_socket_posix.cpp +++ b/drivers/unix/net_socket_posix.cpp @@ -177,6 +177,13 @@ NetSocketPosix::~NetSocketPosix() { close(); } +// Silent a warning reported in #27594 + +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wlogical-op" +#endif + NetSocketPosix::NetError NetSocketPosix::_get_socket_error() { #if defined(WINDOWS_ENABLED) int err = WSAGetLastError(); @@ -201,6 +208,10 @@ NetSocketPosix::NetError NetSocketPosix::_get_socket_error() { #endif } +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic pop +#endif + bool NetSocketPosix::_can_use_ip(const IP_Address p_ip, const bool p_for_bind) const { if (p_for_bind && !(p_ip.is_valid() || p_ip.is_wildcard())) { diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp index e7550903a8..25cdc8d8a0 100644 --- a/drivers/unix/os_unix.cpp +++ b/drivers/unix/os_unix.cpp @@ -108,6 +108,7 @@ void OS_Unix::initialize_debugging() { if (ScriptDebugger::get_singleton() != NULL) { struct sigaction action; + memset(&action, 0, sizeof(action)); action.sa_handler = handle_interrupt; sigaction(SIGINT, &action, NULL); } @@ -118,15 +119,6 @@ int OS_Unix::unix_initialize_audio(int p_audio_driver) { return 0; } -// Very simple signal handler to reap processes where ::execute was called with -// !p_blocking -void handle_sigchld(int sig) { - int saved_errno = errno; - while (waitpid((pid_t)(-1), 0, WNOHANG) > 0) { - } - errno = saved_errno; -} - void OS_Unix::initialize_core() { #ifdef NO_THREADS @@ -154,14 +146,6 @@ void OS_Unix::initialize_core() { #endif _setup_clock(); - - struct sigaction sa; - sa.sa_handler = &handle_sigchld; - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_RESTART | SA_NOCLDSTOP; - if (sigaction(SIGCHLD, &sa, 0) == -1) { - perror("ERROR sigaction() failed:"); - } } void OS_Unix::finalize_core() { @@ -292,7 +276,7 @@ uint64_t OS_Unix::get_ticks_usec() const { return longtime; } -Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool read_stderr) { +Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex) { #ifdef __EMSCRIPTEN__ // Don't compile this code at all to avoid undefined references. @@ -319,11 +303,17 @@ Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, bo ERR_FAIL_COND_V(!f, ERR_CANT_OPEN); char buf[65535]; + while (fgets(buf, 65535, f)) { + if (p_pipe_mutex) { + p_pipe_mutex->lock(); + } (*r_pipe) += buf; + if (p_pipe_mutex) { + p_pipe_mutex->unlock(); + } } - int rv = pclose(f); if (r_exitcode) *r_exitcode = rv; @@ -336,6 +326,13 @@ Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, bo if (pid == 0) { // is child + + if (!p_blocking) { + // For non blocking calls, create a new session-ID so parent won't wait for it. + // This ensures the process won't go zombie at end. + setsid(); + } + Vector<CharString> cs; cs.push_back(p_path.utf8()); for (int i = 0; i < p_arguments.size(); i++) @@ -358,6 +355,7 @@ Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, bo waitpid(pid, &status, 0); if (r_exitcode) *r_exitcode = WEXITSTATUS(status); + } else { if (r_child_id) diff --git a/drivers/unix/os_unix.h b/drivers/unix/os_unix.h index 09ab4aa1d8..6a05877a8c 100644 --- a/drivers/unix/os_unix.h +++ b/drivers/unix/os_unix.h @@ -89,7 +89,7 @@ public: virtual void delay_usec(uint32_t p_usec) const; virtual uint64_t get_ticks_usec() const; - virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id = NULL, String *r_pipe = NULL, int *r_exitcode = NULL, bool read_stderr = false); + virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id = NULL, String *r_pipe = NULL, int *r_exitcode = NULL, bool read_stderr = false, Mutex *p_pipe_mutex = NULL); virtual Error kill(const ProcessID &p_pid); virtual int get_process_id() const; diff --git a/drivers/windows/file_access_windows.cpp b/drivers/windows/file_access_windows.cpp index babb393dcb..c13300d09f 100644 --- a/drivers/windows/file_access_windows.cpp +++ b/drivers/windows/file_access_windows.cpp @@ -197,12 +197,14 @@ void FileAccessWindows::seek(size_t p_position) { last_error = OK; if (fseek(f, p_position, SEEK_SET)) check_errors(); + prev_op = 0; } void FileAccessWindows::seek_end(int64_t p_position) { ERR_FAIL_COND(!f); if (fseek(f, p_position, SEEK_END)) check_errors(); + prev_op = 0; } size_t FileAccessWindows::get_position() const { @@ -234,6 +236,12 @@ bool FileAccessWindows::eof_reached() const { uint8_t FileAccessWindows::get_8() const { ERR_FAIL_COND_V(!f, 0); + if (flags == READ_WRITE || flags == WRITE_READ) { + if (prev_op == WRITE) { + fflush(f); + } + prev_op = READ; + } uint8_t b; if (fread(&b, 1, 1, f) == 0) { check_errors(); @@ -246,6 +254,12 @@ uint8_t FileAccessWindows::get_8() const { int FileAccessWindows::get_buffer(uint8_t *p_dst, int p_length) const { ERR_FAIL_COND_V(!f, -1); + if (flags == READ_WRITE || flags == WRITE_READ) { + if (prev_op == WRITE) { + fflush(f); + } + prev_op = READ; + } int read = fread(p_dst, 1, p_length, f); check_errors(); return read; @@ -260,16 +274,34 @@ void FileAccessWindows::flush() { ERR_FAIL_COND(!f); fflush(f); + if (prev_op == WRITE) + prev_op = 0; } void FileAccessWindows::store_8(uint8_t p_dest) { ERR_FAIL_COND(!f); + if (flags == READ_WRITE || flags == WRITE_READ) { + if (prev_op == READ) { + if (last_error != ERR_FILE_EOF) { + fseek(f, 0, SEEK_CUR); + } + } + prev_op = WRITE; + } fwrite(&p_dest, 1, 1, f); } void FileAccessWindows::store_buffer(const uint8_t *p_src, int p_length) { ERR_FAIL_COND(!f); + if (flags == READ_WRITE || flags == WRITE_READ) { + if (prev_op == READ) { + if (last_error != ERR_FILE_EOF) { + fseek(f, 0, SEEK_CUR); + } + } + prev_op = WRITE; + } ERR_FAIL_COND(fwrite(p_src, 1, p_length, f) != p_length); } @@ -307,9 +339,20 @@ uint64_t FileAccessWindows::_get_modified_time(const String &p_file) { } } +uint32_t FileAccessWindows::_get_unix_permissions(const String &p_file) { + ERR_PRINT("Windows does not support unix permissions"); + return 0; +} + +Error FileAccessWindows::_set_unix_permissions(const String &p_file, uint32_t p_permissions) { + ERR_PRINT("Windows does not support unix permissions"); + return FAILED; +} + FileAccessWindows::FileAccessWindows() : f(NULL), flags(0), + prev_op(0), last_error(OK) { } FileAccessWindows::~FileAccessWindows() { diff --git a/drivers/windows/file_access_windows.h b/drivers/windows/file_access_windows.h index c105eb5265..2848ed5279 100644 --- a/drivers/windows/file_access_windows.h +++ b/drivers/windows/file_access_windows.h @@ -47,6 +47,7 @@ class FileAccessWindows : public FileAccess { FILE *f; int flags; void check_errors() const; + mutable int prev_op; mutable Error last_error; String path; String path_src; @@ -79,6 +80,8 @@ public: virtual bool file_exists(const String &p_name); ///< return true if a file exists uint64_t _get_modified_time(const String &p_file); + virtual uint32_t _get_unix_permissions(const String &p_file); + virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions); FileAccessWindows(); virtual ~FileAccessWindows(); diff --git a/drivers/windows/semaphore_windows.cpp b/drivers/windows/semaphore_windows.cpp index 718bb81836..55b47e45eb 100644 --- a/drivers/windows/semaphore_windows.cpp +++ b/drivers/windows/semaphore_windows.cpp @@ -54,7 +54,8 @@ int SemaphoreWindows::get() const { case WAIT_TIMEOUT: { return 0; } break; - default: {} + default: { + } } ERR_FAIL_V(-1); diff --git a/drivers/xaudio2/SCsub b/drivers/xaudio2/SCsub index 3dca95b429..dfc877b6f5 100644 --- a/drivers/xaudio2/SCsub +++ b/drivers/xaudio2/SCsub @@ -3,5 +3,5 @@ Import('env') env.add_source_files(env.drivers_sources, "*.cpp") -env.Append(CXXFLAGS=['-DXAUDIO2_ENABLED']) +env.Append(CPPFLAGS=['-DXAUDIO2_ENABLED']) env.Append(LINKFLAGS=['xaudio2_8.lib']) |
