diff options
Diffstat (limited to 'drivers')
25 files changed, 593 insertions, 357 deletions
diff --git a/drivers/dummy/rasterizer_dummy.h b/drivers/dummy/rasterizer_dummy.h index d109ef7b91..dfdb3a6bba 100644 --- a/drivers/dummy/rasterizer_dummy.h +++ b/drivers/dummy/rasterizer_dummy.h @@ -63,7 +63,8 @@ public: void environment_set_dof_blur_near(RID p_env, bool p_enable, float p_distance, float p_transition, float p_far_amount, VS::EnvironmentDOFBlurQuality p_quality) {} void environment_set_dof_blur_far(RID p_env, bool p_enable, float p_distance, float p_transition, float p_far_amount, VS::EnvironmentDOFBlurQuality p_quality) {} - void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_threshold, VS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, bool p_bicubic_upscale) {} + void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_threshold, VS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, bool p_bicubic_upscale) {} + void environment_set_fog(RID p_env, bool p_enable, float p_begin, float p_end, RID p_gradient_texture) {} void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance, bool p_roughness) {} @@ -74,7 +75,7 @@ public: void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, RID p_ramp) {} void environment_set_fog(RID p_env, bool p_enable, const Color &p_color, const Color &p_sun_color, float p_sun_amount) {} - void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_curve, bool p_transmit, float p_transmit_curve) {} + void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_end, float p_depth_curve, bool p_transmit, float p_transmit_curve) {} void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve) {} bool is_environment(RID p_env) { return false; } @@ -584,22 +585,12 @@ public: SelfList<RasterizerScene::InstanceBase>::List instance_list; - _FORCE_INLINE_ void instance_change_notify() { - - SelfList<RasterizerScene::InstanceBase> *instances = instance_list.first(); - while (instances) { - - instances->self()->base_changed(); - instances = instances->next(); - } - } - - _FORCE_INLINE_ void instance_material_change_notify() { + _FORCE_INLINE_ void instance_change_notify(bool p_aabb = true, bool p_materials = true) { SelfList<RasterizerScene::InstanceBase> *instances = instance_list.first(); while (instances) { - instances->self()->base_material_changed(); + instances->self()->base_changed(p_aabb, p_materials); instances = instances->next(); } } @@ -691,6 +682,8 @@ public: int particles_get_draw_passes(RID p_particles) const { return 0; } RID particles_get_draw_pass_mesh(RID p_particles, int p_pass) const { return RID(); } + virtual bool particles_is_inactive(RID p_particles) const { return false; } + /* RENDER TARGET */ RID render_target_create() { return RID(); } diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index 175587b1bb..f49dbfeabb 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.cpp @@ -58,11 +58,13 @@ #define _EXT_DEBUG_SEVERITY_LOW_ARB 0x9148 #define _EXT_DEBUG_OUTPUT 0x92E0 -#if (defined WINDOWS_ENABLED) && !(defined UWP_ENABLED) +#ifndef GLAPIENTRY +#if defined(WINDOWS_ENABLED) && !defined(UWP_ENABLED) #define GLAPIENTRY APIENTRY #else #define GLAPIENTRY #endif +#endif #if !defined(GLES_OVER_GL) && !defined(IPHONE_ENABLED) // Used for debugging on mobile, but not iOS as EGL is not available diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp index c4b6c607a2..7addbaa9fe 100644 --- a/drivers/gles2/rasterizer_scene_gles2.cpp +++ b/drivers/gles2/rasterizer_scene_gles2.cpp @@ -605,7 +605,6 @@ bool RasterizerSceneGLES2::reflection_probe_instance_postprocess_step(RID p_inst size >>= 1; int mipmaps = 6; - int mm_level = mipmaps - 1; storage->shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES2::USE_SOURCE_PANORAMA, false); storage->shaders.cubemap_filter.bind(); @@ -628,8 +627,6 @@ bool RasterizerSceneGLES2::reflection_probe_instance_postprocess_step(RID p_inst size >>= 1; - mm_level--; - lod++; } @@ -711,7 +708,7 @@ void RasterizerSceneGLES2::environment_set_dof_blur_near(RID p_env, bool p_enabl ERR_FAIL_COND(!env); } -void RasterizerSceneGLES2::environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_threshold, VS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, bool p_bicubic_upscale) { +void RasterizerSceneGLES2::environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_threshold, VS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, bool p_bicubic_upscale) { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); } @@ -752,13 +749,14 @@ void RasterizerSceneGLES2::environment_set_fog(RID p_env, bool p_enable, const C env->fog_sun_amount = p_sun_amount; } -void RasterizerSceneGLES2::environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_curve, bool p_transmit, float p_transmit_curve) { +void RasterizerSceneGLES2::environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_end, float p_depth_curve, bool p_transmit, float p_transmit_curve) { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); env->fog_depth_enabled = p_enable; env->fog_depth_begin = p_depth_begin; + env->fog_depth_end = p_depth_end; env->fog_depth_curve = p_depth_curve; env->fog_transmit_enabled = p_transmit; env->fog_transmit_curve = p_transmit_curve; @@ -1209,6 +1207,8 @@ bool RasterizerSceneGLES2::_setup_material(RasterizerStorageGLES2::Material *p_m state.scene_shader.set_uniform(SceneShaderGLES2::SKELETON_TEXTURE_SIZE, p_skeleton_tex_size); + state.current_main_tex = 0; + for (int i = 0; i < tc; i++) { glActiveTexture(GL_TEXTURE0 + i); @@ -1239,6 +1239,9 @@ bool RasterizerSceneGLES2::_setup_material(RasterizerStorageGLES2::Material *p_m t = t->get_ptr(); glBindTexture(t->target, t->tex_id); + if (i == 0) { + state.current_main_tex = t->tex_id; + } } state.scene_shader.use_material((void *)p_material); @@ -2054,7 +2057,11 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements, if (p_env && !p_shadow && p_env->fog_enabled && (p_env->fog_depth_enabled || p_env->fog_height_enabled)) { state.scene_shader.set_conditional(SceneShaderGLES2::FOG_DEPTH_ENABLED, p_env->fog_depth_enabled); state.scene_shader.set_conditional(SceneShaderGLES2::FOG_HEIGHT_ENABLED, p_env->fog_height_enabled); - fog_max_distance = p_projection.get_z_far(); + if (p_env->fog_depth_end > 0) { + fog_max_distance = p_env->fog_depth_end; + } else { + fog_max_distance = p_projection.get_z_far(); + } using_fog = true; } @@ -2329,7 +2336,6 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements, state.scene_shader.set_uniform(SceneShaderGLES2::TIME, storage->frame.time[0]); state.scene_shader.set_uniform(SceneShaderGLES2::SCREEN_PIXEL_SIZE, screen_pixel_size); - state.scene_shader.set_uniform(SceneShaderGLES2::NORMAL_MULT, 1.0); // TODO mirror? } if (rebind_light && light) { @@ -2488,6 +2494,7 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const Environment *env = NULL; int viewport_width, viewport_height; + bool probe_interior = false; if (p_reflection_probe.is_valid()) { ReflectionProbeInstance *probe = reflection_probe_instance_owner.getornull(p_reflection_probe); @@ -2505,6 +2512,8 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const viewport_width = probe->probe_ptr->resolution; viewport_height = probe->probe_ptr->resolution; + probe_interior = probe->probe_ptr->interior; + } else { state.render_no_shadows = false; current_fb = storage->frame.current_rt->fbo; @@ -2578,9 +2587,30 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const glClearDepth(1.0f); glEnable(GL_DEPTH_TEST); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + // clear color - storage->frame.clear_request = false; + Color clear_color(0, 0, 0, 0); + + if (storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) { + clear_color = Color(0, 0, 0, 0); + storage->frame.clear_request = false; + } else if (!env || env->bg_mode == VS::ENV_BG_CLEAR_COLOR || env->bg_mode == VS::ENV_BG_SKY) { + if (storage->frame.clear_request) { + clear_color = storage->frame.clear_request_color.to_linear(); + storage->frame.clear_request = false; + } + } else if (env->bg_mode == VS::ENV_BG_CANVAS || env->bg_mode == VS::ENV_BG_COLOR || env->bg_mode == VS::ENV_BG_COLOR_SKY) { + clear_color = env->bg_color.to_linear(); + storage->frame.clear_request = false; + } else { + storage->frame.clear_request = false; + } + + if (!env || env->bg_mode != VS::ENV_BG_KEEP) { + glClearColor(clear_color.r, clear_color.g, clear_color.b, clear_color.a); + } + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1); @@ -2615,6 +2645,10 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const } } + if (probe_interior) { + env_radiance_tex = 0; //do not use radiance texture on interiors + } + // render opaque things first render_list.sort_by_key(false); _render_render_list(render_list.elements, render_list.element_count, p_cam_transform, p_cam_projection, p_shadow_atlas, env, env_radiance_tex, 0.0, 0.0, false, false, false); diff --git a/drivers/gles2/rasterizer_scene_gles2.h b/drivers/gles2/rasterizer_scene_gles2.h index 33ac99366d..ba406183c7 100644 --- a/drivers/gles2/rasterizer_scene_gles2.h +++ b/drivers/gles2/rasterizer_scene_gles2.h @@ -360,6 +360,7 @@ public: bool fog_depth_enabled; float fog_depth_begin; + float fog_depth_end; float fog_depth_curve; bool fog_transmit_enabled; float fog_transmit_curve; @@ -385,6 +386,7 @@ public: fog_depth_enabled = true; fog_depth_begin = 10; + fog_depth_end = 0; fog_depth_curve = 1; fog_transmit_enabled = true; @@ -411,7 +413,7 @@ public: virtual void environment_set_dof_blur_near(RID p_env, bool p_enable, float p_distance, float p_transition, float p_amount, VS::EnvironmentDOFBlurQuality p_quality); virtual void environment_set_dof_blur_far(RID p_env, bool p_enable, float p_distance, float p_transition, float p_amount, VS::EnvironmentDOFBlurQuality p_quality); - virtual void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_threshold, VS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, bool p_bicubic_upscale); + virtual void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_threshold, VS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, bool p_bicubic_upscale); virtual void environment_set_fog(RID p_env, bool p_enable, float p_begin, float p_end, RID p_gradient_texture); virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_in, float p_fade_out, float p_depth_tolerance, bool p_roughness); @@ -422,7 +424,7 @@ public: virtual void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, RID p_ramp); virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_color, const Color &p_sun_color, float p_sun_amount); - virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_curve, bool p_transmit, float p_transmit_curve); + virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_end, float p_depth_curve, bool p_transmit, float p_transmit_curve); virtual void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve); virtual bool is_environment(RID p_env); diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp index d5865064cf..3beb8eac33 100644 --- a/drivers/gles2/rasterizer_storage_gles2.cpp +++ b/drivers/gles2/rasterizer_storage_gles2.cpp @@ -613,8 +613,72 @@ Ref<Image> RasterizerStorageGLES2::texture_get_data(RID p_texture, int p_layer) return Ref<Image>(img); #else - ERR_EXPLAIN("Sorry, It's not possible to obtain images back in OpenGL ES"); - ERR_FAIL_V(Ref<Image>()); + Image::Format real_format; + GLenum gl_format; + GLenum gl_internal_format; + GLenum gl_type; + bool compressed; + _get_gl_image_and_format(Ref<Image>(), texture->format, texture->flags, real_format, gl_format, gl_internal_format, gl_type, compressed); + + PoolVector<uint8_t> data; + + int data_size = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, Image::FORMAT_RGBA8, false); + + data.resize(data_size * 2); //add some memory at the end, just in case for buggy drivers + PoolVector<uint8_t>::Write wb = data.write(); + + GLuint temp_framebuffer; + glGenFramebuffers(1, &temp_framebuffer); + + GLuint temp_color_texture; + glGenTextures(1, &temp_color_texture); + + glBindFramebuffer(GL_FRAMEBUFFER, temp_framebuffer); + + glBindTexture(GL_TEXTURE_2D, temp_color_texture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture->alloc_width, texture->alloc_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, temp_color_texture, 0); + + 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, texture->tex_id); + + glViewport(0, 0, texture->alloc_width, texture->alloc_height); + + shaders.copy.bind(); + + glClearColor(0.0, 0.0, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + bind_quad_array(); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + glReadPixels(0, 0, texture->alloc_width, texture->alloc_height, GL_RGBA, GL_UNSIGNED_BYTE, &wb[0]); + + glDeleteTextures(1, &temp_color_texture); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glDeleteFramebuffers(1, &temp_framebuffer); + + wb = PoolVector<uint8_t>::Write(); + + data.resize(data_size); + + Image *img = memnew(Image(texture->alloc_width, texture->alloc_height, false, Image::FORMAT_RGBA8, data)); + if (!texture->compressed) { + img->convert(real_format); + } + + return Ref<Image>(img); + #endif } @@ -1061,6 +1125,10 @@ void RasterizerStorageGLES2::_update_shader(Shader *p_shader) const { p_shader->uniforms.clear(); + if (p_shader->code == String()) { + return; //just invalid, but no error + } + ShaderCompilerGLES2::GeneratedCode gen_code; ShaderCompilerGLES2::IdentifierActions *actions = NULL; @@ -1429,8 +1497,9 @@ Variant RasterizerStorageGLES2::material_get_param_default(RID p_material, const if (material->shader) { if (material->shader->uniforms.has(p_param)) { - Vector<ShaderLanguage::ConstantNode::Value> default_value = material->shader->uniforms[p_param].default_value; - return ShaderLanguage::constant_value_to_variant(default_value, material->shader->uniforms[p_param].type); + ShaderLanguage::ShaderNode::Uniform uniform = material->shader->uniforms[p_param]; + Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value; + return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.hint); } } return Variant(); @@ -1538,7 +1607,7 @@ void RasterizerStorageGLES2::_update_material(Material *p_material) { if (p_material->shader && p_material->shader->mode == VS::SHADER_SPATIAL) { if (p_material->shader->spatial.blend_mode == Shader::Spatial::BLEND_MODE_MIX && - (!p_material->shader->spatial.uses_alpha || (p_material->shader->spatial.uses_alpha && p_material->shader->spatial.depth_draw_mode == Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS))) { + (!p_material->shader->spatial.uses_alpha || p_material->shader->spatial.depth_draw_mode == Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS)) { can_cast_shadow = true; } @@ -1559,7 +1628,7 @@ void RasterizerStorageGLES2::_update_material(Material *p_material) { } for (Map<RasterizerScene::InstanceBase *, int>::Element *E = p_material->instance_owners.front(); E; E = E->next()) { - E->key()->base_material_changed(); + E->key()->base_changed(false, true); } } } @@ -1946,7 +2015,7 @@ void RasterizerStorageGLES2::mesh_add_surface(RID p_mesh, uint32_t p_format, VS: } mesh->surfaces.push_back(surface); - mesh->instance_change_notify(); + mesh->instance_change_notify(true, false); info.vertex_mem += surface->total_data_size; } @@ -2016,7 +2085,7 @@ void RasterizerStorageGLES2::mesh_surface_set_material(RID p_mesh, int p_surface _material_add_geometry(mesh->surfaces[p_surface]->material, mesh->surfaces[p_surface]); } - mesh->instance_material_change_notify(); + mesh->instance_change_notify(false, true); } RID RasterizerStorageGLES2::mesh_surface_get_material(RID p_mesh, int p_surface) const { @@ -2124,13 +2193,11 @@ void RasterizerStorageGLES2::mesh_remove_surface(RID p_mesh, int p_surface) { info.vertex_mem -= surface->total_data_size; - mesh->instance_material_change_notify(); - memdelete(surface); mesh->surfaces.remove(p_surface); - mesh->instance_change_notify(); + mesh->instance_change_notify(true, true); } int RasterizerStorageGLES2::mesh_get_surface_count(RID p_mesh) const { @@ -2704,7 +2771,7 @@ void RasterizerStorageGLES2::update_dirty_multimeshes() { multimesh->dirty_aabb = false; multimesh->dirty_data = false; - multimesh->instance_change_notify(); + multimesh->instance_change_notify(true, false); multimesh_update_list.remove(multimesh_update_list.first()); } @@ -2809,7 +2876,7 @@ void RasterizerStorageGLES2::immediate_end(RID p_immediate) { ERR_FAIL_COND(!im->building); im->building = false; - im->instance_change_notify(); + im->instance_change_notify(true, false); } void RasterizerStorageGLES2::immediate_clear(RID p_immediate) { @@ -2818,7 +2885,7 @@ void RasterizerStorageGLES2::immediate_clear(RID p_immediate) { ERR_FAIL_COND(im->building); im->chunks.clear(); - im->instance_change_notify(); + im->instance_change_notify(true, false); } AABB RasterizerStorageGLES2::immediate_get_aabb(RID p_immediate) const { @@ -2832,7 +2899,7 @@ void RasterizerStorageGLES2::immediate_set_material(RID p_immediate, RID p_mater ERR_FAIL_COND(!im); im->material = p_material; - im->instance_material_change_notify(); + im->instance_change_notify(false, true); } RID RasterizerStorageGLES2::immediate_get_material(RID p_immediate) const { @@ -3043,7 +3110,7 @@ void RasterizerStorageGLES2::update_dirty_skeletons() { } for (Set<RasterizerScene::InstanceBase *>::Element *E = skeleton->instances.front(); E; E = E->next()) { - E->get()->base_changed(); + E->get()->base_changed(true, false); } skeleton_update_list.remove(skeleton_update_list.first()); @@ -3108,7 +3175,7 @@ void RasterizerStorageGLES2::light_set_param(RID p_light, VS::LightParam p_param case VS::LIGHT_PARAM_SHADOW_NORMAL_BIAS: case VS::LIGHT_PARAM_SHADOW_BIAS: { light->version++; - light->instance_change_notify(); + light->instance_change_notify(true, false); } break; default: {} } @@ -3123,7 +3190,7 @@ void RasterizerStorageGLES2::light_set_shadow(RID p_light, bool p_enabled) { light->shadow = p_enabled; light->version++; - light->instance_change_notify(); + light->instance_change_notify(true, false); } void RasterizerStorageGLES2::light_set_shadow_color(RID p_light, const Color &p_color) { @@ -3154,7 +3221,7 @@ void RasterizerStorageGLES2::light_set_cull_mask(RID p_light, uint32_t p_mask) { light->cull_mask = p_mask; light->version++; - light->instance_change_notify(); + light->instance_change_notify(true, false); } void RasterizerStorageGLES2::light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) { @@ -3164,7 +3231,7 @@ void RasterizerStorageGLES2::light_set_reverse_cull_face_mode(RID p_light, bool light->reverse_cull = p_enabled; light->version++; - light->instance_change_notify(); + light->instance_change_notify(true, false); } void RasterizerStorageGLES2::light_omni_set_shadow_mode(RID p_light, VS::LightOmniShadowMode p_mode) { @@ -3174,7 +3241,7 @@ void RasterizerStorageGLES2::light_omni_set_shadow_mode(RID p_light, VS::LightOm light->omni_shadow_mode = p_mode; light->version++; - light->instance_change_notify(); + light->instance_change_notify(true, false); } VS::LightOmniShadowMode RasterizerStorageGLES2::light_omni_get_shadow_mode(RID p_light) { @@ -3191,7 +3258,7 @@ void RasterizerStorageGLES2::light_omni_set_shadow_detail(RID p_light, VS::Light light->omni_shadow_detail = p_detail; light->version++; - light->instance_change_notify(); + light->instance_change_notify(true, false); } void RasterizerStorageGLES2::light_directional_set_shadow_mode(RID p_light, VS::LightDirectionalShadowMode p_mode) { @@ -3201,7 +3268,7 @@ void RasterizerStorageGLES2::light_directional_set_shadow_mode(RID p_light, VS:: light->directional_shadow_mode = p_mode; light->version++; - light->instance_change_notify(); + light->instance_change_notify(true, false); } void RasterizerStorageGLES2::light_directional_set_blend_splits(RID p_light, bool p_enable) { @@ -3211,7 +3278,7 @@ void RasterizerStorageGLES2::light_directional_set_blend_splits(RID p_light, boo light->directional_blend_splits = p_enable; light->version++; - light->instance_change_notify(); + light->instance_change_notify(true, false); } bool RasterizerStorageGLES2::light_directional_get_blend_splits(RID p_light) const { @@ -3330,7 +3397,7 @@ void RasterizerStorageGLES2::reflection_probe_set_update_mode(RID p_probe, VS::R ERR_FAIL_COND(!reflection_probe); reflection_probe->update_mode = p_mode; - reflection_probe->instance_change_notify(); + reflection_probe->instance_change_notify(true, false); } void RasterizerStorageGLES2::reflection_probe_set_intensity(RID p_probe, float p_intensity) { @@ -3371,7 +3438,7 @@ void RasterizerStorageGLES2::reflection_probe_set_max_distance(RID p_probe, floa ERR_FAIL_COND(!reflection_probe); reflection_probe->max_distance = p_distance; - reflection_probe->instance_change_notify(); + reflection_probe->instance_change_notify(true, false); } void RasterizerStorageGLES2::reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) { @@ -3379,7 +3446,7 @@ void RasterizerStorageGLES2::reflection_probe_set_extents(RID p_probe, const Vec ERR_FAIL_COND(!reflection_probe); reflection_probe->extents = p_extents; - reflection_probe->instance_change_notify(); + reflection_probe->instance_change_notify(true, false); } void RasterizerStorageGLES2::reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) { @@ -3387,7 +3454,7 @@ void RasterizerStorageGLES2::reflection_probe_set_origin_offset(RID p_probe, con ERR_FAIL_COND(!reflection_probe); reflection_probe->origin_offset = p_offset; - reflection_probe->instance_change_notify(); + reflection_probe->instance_change_notify(true, false); } void RasterizerStorageGLES2::reflection_probe_set_as_interior(RID p_probe, bool p_enable) { @@ -3411,7 +3478,7 @@ void RasterizerStorageGLES2::reflection_probe_set_enable_shadows(RID p_probe, bo ERR_FAIL_COND(!reflection_probe); reflection_probe->enable_shadows = p_enable; - reflection_probe->instance_change_notify(); + reflection_probe->instance_change_notify(true, false); } void RasterizerStorageGLES2::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) { @@ -3419,7 +3486,7 @@ void RasterizerStorageGLES2::reflection_probe_set_cull_mask(RID p_probe, uint32_ ERR_FAIL_COND(!reflection_probe); reflection_probe->cull_mask = p_layers; - reflection_probe->instance_change_notify(); + reflection_probe->instance_change_notify(true, false); } void RasterizerStorageGLES2::reflection_probe_set_resolution(RID p_probe, int p_resolution) { @@ -3603,7 +3670,7 @@ void RasterizerStorageGLES2::lightmap_capture_set_bounds(RID p_capture, const AA LightmapCapture *capture = lightmap_capture_data_owner.getornull(p_capture); ERR_FAIL_COND(!capture); capture->bounds = p_bounds; - capture->instance_change_notify(); + capture->instance_change_notify(true, false); } AABB RasterizerStorageGLES2::lightmap_capture_get_bounds(RID p_capture) const { @@ -3624,7 +3691,7 @@ void RasterizerStorageGLES2::lightmap_capture_set_octree(RID p_capture, const Po PoolVector<uint8_t>::Read r = p_octree.read(); copymem(w.ptr(), r.ptr(), p_octree.size()); } - capture->instance_change_notify(); + capture->instance_change_notify(true, false); } PoolVector<uint8_t> RasterizerStorageGLES2::lightmap_capture_get_octree(RID p_capture) const { @@ -3775,6 +3842,10 @@ RID RasterizerStorageGLES2::particles_get_draw_pass_mesh(RID p_particles, int p_ void RasterizerStorageGLES2::update_particles() { } +bool RasterizerStorageGLES2::particles_is_inactive(RID p_particles) const { + return true; +} + //////// void RasterizerStorageGLES2::instance_add_skeleton(RID p_skeleton, RasterizerScene::InstanceBase *p_instance) { @@ -4394,6 +4465,7 @@ void RasterizerStorageGLES2::initialize() { } } + config.keep_original_textures = false; config.shrink_textures_x2 = false; config.float_texture_supported = config.extensions.has("GL_ARB_texture_float") || config.extensions.has("GL_OES_texture_float"); @@ -4541,6 +4613,7 @@ void RasterizerStorageGLES2::initialize() { #endif config.force_vertex_shading = GLOBAL_GET("rendering/quality/shading/force_vertex_shading"); + config.use_fast_texture_filter = GLOBAL_GET("rendering/quality/filters/use_nearest_mipmap_filter"); } void RasterizerStorageGLES2::finalize() { diff --git a/drivers/gles2/rasterizer_storage_gles2.h b/drivers/gles2/rasterizer_storage_gles2.h index c928f753b1..5bdc65a0b5 100644 --- a/drivers/gles2/rasterizer_storage_gles2.h +++ b/drivers/gles2/rasterizer_storage_gles2.h @@ -60,20 +60,12 @@ public: bool shrink_textures_x2; bool use_fast_texture_filter; - // bool use_anisotropic_filter; - - bool hdr_supported; - - bool use_rgba_2d_shadows; - - // float anisotropic_level; int max_texture_image_units; int max_texture_size; - bool generate_wireframes; - - bool use_texture_array_environment; + // TODO implement wireframe in GLES2 + // bool generate_wireframes; Set<String> extensions; @@ -83,7 +75,6 @@ public: bool keep_original_textures; - bool no_depth_prepass; bool force_vertex_shading; } config; @@ -159,20 +150,12 @@ public: struct Instantiable : public RID_Data { SelfList<RasterizerScene::InstanceBase>::List instance_list; - _FORCE_INLINE_ void instance_change_notify() { - SelfList<RasterizerScene::InstanceBase> *instances = instance_list.first(); - - while (instances) { - instances->self()->base_changed(); - instances = instances->next(); - } - } + _FORCE_INLINE_ void instance_change_notify(bool p_aabb, bool p_materials) { - _FORCE_INLINE_ void instance_material_change_notify() { SelfList<RasterizerScene::InstanceBase> *instances = instance_list.first(); - while (instances) { - instances->self()->base_material_changed(); + + instances->self()->base_changed(p_aabb, p_materials); instances = instances->next(); } } @@ -272,31 +255,28 @@ public: void *detect_normal_ud; Texture() { - flags = 0; - width = 0; - height = 0; alloc_width = 0; alloc_height = 0; - format = Image::FORMAT_L8; - target = 0; - data_size = 0; - total_data_size = 0; + stored_cube_sides = 0; ignore_mipmaps = false; - - compressed = false; - - active = false; - + render_target = NULL; + flags = width = height = 0; tex_id = 0; - - stored_cube_sides = 0; - + data_size = 0; + format = Image::FORMAT_L8; + active = false; + compressed = false; + total_data_size = 0; + mipmaps = 0; + detect_3d = NULL; + detect_3d_ud = NULL; + detect_srgb = NULL; + detect_srgb_ud = NULL; + detect_normal = NULL; + detect_normal_ud = NULL; proxy = NULL; - - render_target = NULL; - redraw_if_visible = false; } @@ -429,6 +409,7 @@ public: int light_mode; */ + bool uses_screen_texture; bool uses_screen_uv; bool uses_time; @@ -672,7 +653,7 @@ public: SelfList<MultiMesh> *mm = multimeshes.first(); while (mm) { - mm->self()->instance_material_change_notify(); + mm->self()->instance_change_notify(false, true); mm = mm->next(); } } @@ -1109,6 +1090,8 @@ public: virtual int particles_get_draw_passes(RID p_particles) const; virtual RID particles_get_draw_pass_mesh(RID p_particles, int p_pass) const; + virtual bool particles_is_inactive(RID p_particles) const; + /* INSTANCE */ virtual void instance_add_skeleton(RID p_skeleton, RasterizerScene::InstanceBase *p_instance); diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp index 082c520480..d52be09cac 100644 --- a/drivers/gles2/shader_compiler_gles2.cpp +++ b/drivers/gles2/shader_compiler_gles2.cpp @@ -80,19 +80,17 @@ static String _opstr(SL::Operator p_op) { static String _mkid(const String &p_id) { - StringBuffer<> id; - id += "m_"; - id += p_id; - - return id.as_string(); + String id = "m_" + p_id; + return id.replace("__", "_dus_"); //doubleunderscore is reserverd in glsl } static String f2sp0(float p_float) { - if (int(p_float) == p_float) - return itos(p_float) + ".0"; - else - return rtoss(p_float); + String num = rtoss(p_float); + if (num.find(".") == -1 && num.find("e") == -1) { + num += ".0"; + } + return num; } static String get_constant_text(SL::DataType p_type, const Vector<SL::ConstantNode::Value> &p_values) { @@ -364,6 +362,7 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener for (int i = 0; i < snode->functions.size(); i++) { SL::FunctionNode *fnode = snode->functions[i].function; + current_func_name = fnode->name; function_code[fnode->name] = _dump_node_code(fnode->body, 1, r_gen_code, p_actions, p_default_actions, p_assigning); } diff --git a/drivers/gles2/shader_gles2.cpp b/drivers/gles2/shader_gles2.cpp index 628a57c06d..84bd413abb 100644 --- a/drivers/gles2/shader_gles2.cpp +++ b/drivers/gles2/shader_gles2.cpp @@ -99,7 +99,7 @@ void ShaderGLES2::bind_uniforms() { const Map<uint32_t, CameraMatrix>::Element *C = uniform_cameras.front(); while (C) { - int idx = E->key(); + int idx = C->key(); int location = version->uniform_location[idx]; if (location < 0) { @@ -196,6 +196,12 @@ static void _display_error_with_code(const String &p_error, const Vector<const c ERR_PRINTS(p_error); } +static String _mkid(const String &p_id) { + + String id = "m_" + p_id; + return id.replace("__", "_dus_"); //doubleunderscore is reserverd in glsl +} + ShaderGLES2::Version *ShaderGLES2::get_current_version() { Version *_v = version_map.getptr(conditional_version); @@ -492,15 +498,15 @@ ShaderGLES2::Version *ShaderGLES2::get_current_version() { if (cc) { // uniforms for (int i = 0; i < cc->custom_uniforms.size(); i++) { - StringName native_uniform_name = "m_" + cc->custom_uniforms[i]; - GLint location = glGetUniformLocation(v.id, ((String)native_uniform_name).ascii().get_data()); + String native_uniform_name = _mkid(cc->custom_uniforms[i]); + GLint location = glGetUniformLocation(v.id, (native_uniform_name).ascii().get_data()); v.custom_uniform_locations[cc->custom_uniforms[i]] = location; } // textures for (int i = 0; i < cc->texture_uniforms.size(); i++) { - StringName native_uniform_name = "m_" + cc->texture_uniforms[i]; - GLint location = glGetUniformLocation(v.id, ((String)native_uniform_name).ascii().get_data()); + String native_uniform_name = _mkid(cc->texture_uniforms[i]); + GLint location = glGetUniformLocation(v.id, (native_uniform_name).ascii().get_data()); v.custom_uniform_locations[cc->texture_uniforms[i]] = location; } } diff --git a/drivers/gles2/shaders/canvas.glsl b/drivers/gles2/shaders/canvas.glsl index b990384949..79d4eb2243 100644 --- a/drivers/gles2/shaders/canvas.glsl +++ b/drivers/gles2/shaders/canvas.glsl @@ -148,7 +148,10 @@ void main() { vec4 color = color_interp; +#if !defined(COLOR_USED) + //default behavior, texture by color color *= texture2D(color_texture, uv_interp); +#endif #ifdef SCREEN_UV_USED vec2 screen_uv = gl_FragCoord.xy * screen_pixel_size; diff --git a/drivers/gles2/shaders/scene.glsl b/drivers/gles2/shaders/scene.glsl index 2a781605d1..15b90a7771 100644 --- a/drivers/gles2/shaders/scene.glsl +++ b/drivers/gles2/shaders/scene.glsl @@ -84,8 +84,6 @@ uniform highp mat4 world_transform; uniform highp float time; -uniform float normal_mult; - #ifdef RENDER_DEPTH uniform float light_bias; uniform float light_normal_bias; @@ -247,7 +245,7 @@ void light_compute( float cLdotH = max(dot(L, H), 0.0); float shininess = exp2(15.0 * (1.0 - roughness) + 1.0) * 0.25; float blinn = pow(cNdotH, shininess); - blinn *= (shininess + 8.0) / (8.0 * 3.141592654); + blinn *= (shininess + 8.0) * (1.0 / (8.0 * M_PI)); specular_brdf_NL = (blinn) / max(4.0 * cNdotV * cNdotL, 0.75); #endif @@ -330,11 +328,10 @@ void main() { #endif - vec3 normal = normal_attrib * normal_mult; + vec3 normal = normal_attrib; #if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) vec3 tangent = tangent_attrib.xyz; - tangent *= normal_mult; float binormalf = tangent_attrib.a; vec3 binormal = normalize(cross(normal, tangent) * binormalf); #endif @@ -626,7 +623,7 @@ VERTEX_SHADER_CODE float fog_z = smoothstep(fog_depth_begin, fog_max_distance, length(vertex)); - fog_amount = pow(fog_z, fog_depth_curve); + fog_amount = pow(fog_z, fog_depth_curve) * fog_color_base.a; } #endif @@ -1012,9 +1009,7 @@ float G_GGX_2cos(float cos_theta_m, float alpha) { // This approximates G_GGX_2cos(cos_theta_l, alpha) * G_GGX_2cos(cos_theta_v, alpha) // See Filament docs, Specular G section. float V_GGX(float cos_theta_l, float cos_theta_v, float alpha) { - float v = cos_theta_l * (cos_theta_v * (1.0 - alpha) + alpha); - float l = cos_theta_v * (cos_theta_l * (1.0 - alpha) + alpha); - return 0.5 / (v + l); + return 0.5 / mix(2.0 * cos_theta_l * cos_theta_v, cos_theta_l + cos_theta_v, alpha); } float D_GGX(float cos_theta_m, float alpha) { @@ -1124,7 +1119,19 @@ LIGHT_SHADER_CODE float NdotL = dot(N, L); float cNdotL = max(NdotL, 0.0); // clamped NdotL float NdotV = dot(N, V); - float cNdotV = max(NdotV, 0.0); + float cNdotV = max(abs(NdotV), 1e-6); + +#if defined(DIFFUSE_BURLEY) || defined(SPECULAR_BLINN) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_USE_CLEARCOAT) + vec3 H = normalize(V + L); +#endif + +#if defined(SPECULAR_BLINN) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_USE_CLEARCOAT) + float cNdotH = max(dot(N, H), 0.0); +#endif + +#if defined(DIFFUSE_BURLEY) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_USE_CLEARCOAT) + float cLdotH = max(dot(L, H), 0.0); +#endif if (metallic < 1.0) { #if defined(DIFFUSE_OREN_NAYAR) @@ -1160,13 +1167,9 @@ LIGHT_SHADER_CODE #elif defined(DIFFUSE_BURLEY) { - - vec3 H = normalize(V + L); - float cLdotH = max(0.0, dot(L, H)); - - float FD90 = 0.5 + 2.0 * cLdotH * cLdotH * roughness; - float FdV = 1.0 + (FD90 - 1.0) * SchlickFresnel(cNdotV); - float FdL = 1.0 + (FD90 - 1.0) * SchlickFresnel(cNdotL); + float FD90_minus_1 = 2.0 * cLdotH * cLdotH * roughness - 0.5; + float FdV = 1.0 + FD90_minus_1 * SchlickFresnel(cNdotV); + float FdL = 1.0 + FD90_minus_1 * SchlickFresnel(cNdotL); diffuse_brdf_NL = (1.0 / M_PI) * FdV * FdL * cNdotL; /* float energyBias = mix(roughness, 0.0, 0.5); @@ -1209,13 +1212,9 @@ LIGHT_SHADER_CODE #if defined(SPECULAR_BLINN) //normalized blinn - vec3 H = normalize(V + L); - float cNdotH = max(dot(N, H), 0.0); - float cVdotH = max(dot(V, H), 0.0); - float cLdotH = max(dot(L, H), 0.0); float shininess = exp2(15.0 * (1.0 - roughness) + 1.0) * 0.25; float blinn = pow(cNdotH, shininess); - blinn *= (shininess + 8.0) / (8.0 * 3.141592654); + blinn *= (shininess + 8.0) * (1.0 / (8.0 * M_PI)); specular_brdf_NL = (blinn) / max(4.0 * cNdotV * cNdotL, 0.75); #elif defined(SPECULAR_PHONG) @@ -1224,7 +1223,7 @@ LIGHT_SHADER_CODE float cRdotV = max(0.0, dot(R, V)); float shininess = exp2(15.0 * (1.0 - roughness) + 1.0) * 0.25; float phong = pow(cRdotV, shininess); - phong *= (shininess + 8.0) / (8.0 * 3.141592654); + phong *= (shininess + 8.0) * (1.0 / (8.0 * M_PI)); specular_brdf_NL = (phong) / max(4.0 * cNdotV * cNdotL, 0.75); #elif defined(SPECULAR_TOON) @@ -1240,11 +1239,6 @@ LIGHT_SHADER_CODE #elif defined(SPECULAR_SCHLICK_GGX) // shlick+ggx as default - vec3 H = normalize(V + L); - - float cNdotH = max(dot(N, H), 0.0); - float cLdotH = max(dot(L, H), 0.0); - #if defined(LIGHT_USE_ANISOTROPY) float alpha = roughness * roughness; float aspect = sqrt(1.0 - anisotropy * 0.9); @@ -1275,24 +1269,18 @@ LIGHT_SHADER_CODE specular_light += specular_brdf_NL * light_color * specular_blob_intensity * attenuation; #if defined(LIGHT_USE_CLEARCOAT) - if (clearcoat_gloss > 0.0) { -#if !defined(SPECULAR_SCHLICK_GGX) && !defined(SPECULAR_BLINN) - vec3 H = normalize(V + L); -#endif + #if !defined(SPECULAR_SCHLICK_GGX) - float cNdotH = max(dot(N, H), 0.0); - float cLdotH = max(dot(L, H), 0.0); - float cLdotH5 = SchlickFresnel(cLdotH); + float cLdotH5 = SchlickFresnel(cLdotH); #endif - float Dr = GTR1(cNdotH, mix(.1, .001, clearcoat_gloss)); - float Fr = mix(.04, 1.0, cLdotH5); - //float Gr = G_GGX_2cos(cNdotL, .25) * G_GGX_2cos(cNdotV, .25); - float Gr = V_GGX(cNdotL, cNdotV, 0.25); + float Dr = GTR1(cNdotH, mix(.1, .001, clearcoat_gloss)); + float Fr = mix(.04, 1.0, cLdotH5); + //float Gr = G_GGX_2cos(cNdotL, .25) * G_GGX_2cos(cNdotV, .25); + float Gr = V_GGX(cNdotL, cNdotV, 0.25); - float clearcoat_specular_brdf_NL = 0.25 * clearcoat * Gr * Fr * Dr * cNdotL; + float clearcoat_specular_brdf_NL = 0.25 * clearcoat * Gr * Fr * Dr * cNdotL; - specular_light += clearcoat_specular_brdf_NL * light_color * specular_blob_intensity * attenuation; - } + specular_light += clearcoat_specular_brdf_NL * light_color * specular_blob_intensity * attenuation; #endif } @@ -2036,7 +2024,7 @@ FRAGMENT_SHADER_CODE float fog_z = smoothstep(fog_depth_begin, fog_max_distance, length(vertex)); - fog_amount = pow(fog_z, fog_depth_curve); + fog_amount = pow(fog_z, fog_depth_curve) * fog_color_base.a; if (fog_transmit_enabled) { vec3 total_light = gl_FragColor.rgb; diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index f0932c2f80..4166cb8361 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -213,12 +213,12 @@ RasterizerStorageGLES3::Texture *RasterizerCanvasGLES3::_bind_canvas_texture(con } else { + texture = texture->get_ptr(); + if (texture->redraw_if_visible) { //check before proxy, because this is usually used with proxies VisualServerRaster::redraw_request(); } - texture = texture->get_ptr(); - if (texture->render_target) texture->render_target->used_in_frame = true; @@ -254,11 +254,12 @@ RasterizerStorageGLES3::Texture *RasterizerCanvasGLES3::_bind_canvas_texture(con } else { + normal_map = normal_map->get_ptr(); + if (normal_map->redraw_if_visible) { //check before proxy, because this is usually used with proxies VisualServerRaster::redraw_request(); } - normal_map = normal_map->get_ptr(); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, normal_map->tex_id); state.current_normal = p_normal_map; @@ -976,7 +977,7 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur RasterizerStorageGLES3::Texture *texture = _bind_canvas_texture(particles_cmd->texture, particles_cmd->normal_map); if (texture) { - Size2 texpixel_size(1.0 / (texture->width / particles_cmd->h_frames), 1.0 / (texture->height / particles_cmd->v_frames)); + Size2 texpixel_size(1.0 / texture->width, 1.0 / texture->height); state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size); } else { state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, Vector2(1.0, 1.0)); @@ -993,9 +994,6 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur state.canvas_shader.set_uniform(CanvasShaderGLES3::MODELVIEW_MATRIX, state.final_transform * inv_xf); } - state.canvas_shader.set_uniform(CanvasShaderGLES3::H_FRAMES, particles_cmd->h_frames); - state.canvas_shader.set_uniform(CanvasShaderGLES3::V_FRAMES, particles_cmd->v_frames); - glBindVertexArray(data.particle_quad_array); //use particle quad array glBindBuffer(GL_ARRAY_BUFFER, particles->particle_buffers[0]); //bind particle buffer @@ -1072,8 +1070,8 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur glBindVertexArray(0); state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_INSTANCE_CUSTOM, false); - state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_INSTANCING, false); state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_PARTICLES, false); + state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_INSTANCING, false); state.using_texture_rect = true; _set_texture_rect_mode(false); @@ -1223,8 +1221,6 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons bool rebind_shader = true; - state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_DISTANCE_FIELD, false); - glBindBuffer(GL_UNIFORM_BUFFER, state.canvas_item_ubo); glBufferData(GL_UNIFORM_BUFFER, sizeof(CanvasItemUBO), &state.canvas_item_ubo_data, GL_DYNAMIC_DRAW); glBindBuffer(GL_UNIFORM_BUFFER, 0); @@ -1342,7 +1338,7 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons last_blend_mode = last_blend_mode != RasterizerStorageGLES3::Shader::CanvasItem::BLEND_MODE_DISABLED ? last_blend_mode : -1; } - if (shader_ptr != shader_cache) { + if (shader_ptr != shader_cache || rebind_shader) { if (shader_ptr->canvas_item.uses_time) { VisualServerRaster::redraw_request(); @@ -1388,12 +1384,12 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons continue; } + t = t->get_ptr(); + if (t->redraw_if_visible) { //check before proxy, because this is usually used with proxies VisualServerRaster::redraw_request(); } - t = t->get_ptr(); - if (storage->config.srgb_decode_supported && t->using_srgb) { //no srgb in 2D glTexParameteri(t->target, _TEXTURE_SRGB_DECODE_EXT, _SKIP_DECODE_EXT); @@ -1659,6 +1655,14 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons if (current_clip) { glDisable(GL_SCISSOR_TEST); } + //disable states that may have been used + state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_DISTANCE_FIELD, false); + state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_SKELETON, false); + state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_INSTANCE_CUSTOM, false); + state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_PARTICLES, false); + state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_INSTANCING, false); + state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_LIGHTING, false); + state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_SHADOWS, false); } void RasterizerCanvasGLES3::canvas_debug_viewport_shadows(Light *p_lights_with_shadow) { diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp index 2f6a556773..8242d214d3 100644 --- a/drivers/gles3/rasterizer_gles3.cpp +++ b/drivers/gles3/rasterizer_gles3.cpp @@ -79,12 +79,6 @@ RasterizerScene *RasterizerGLES3::get_scene() { #ifdef GLAD_ENABLED // Restricting to GLAD as only used in initialize() with GLAD_GL_ARB_debug_output -#if (defined WINDOWS_ENABLED) && !(defined UWP_ENABLED) -#define GLAPIENTRY APIENTRY -#else -#define GLAPIENTRY -#endif - static void GLAPIENTRY _gl_debug_print(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const GLvoid *userParam) { if (type == _EXT_DEBUG_TYPE_OTHER_ARB) @@ -432,7 +426,6 @@ void RasterizerGLES3::make_current() { void RasterizerGLES3::register_config() { - GLOBAL_DEF("rendering/quality/filters/use_nearest_mipmap_filter", false); GLOBAL_DEF("rendering/quality/filters/anisotropic_filter_level", 4); ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/filters/anisotropic_filter_level", PropertyInfo(Variant::INT, "rendering/quality/filters/anisotropic_filter_level", PROPERTY_HINT_RANGE, "1,16,1")); GLOBAL_DEF("rendering/limits/time/time_rollover_secs", 3600); diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 0d4c83e0db..ffe9e1c831 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -846,7 +846,7 @@ void RasterizerSceneGLES3::environment_set_dof_blur_near(RID p_env, bool p_enabl env->dof_blur_near_amount = p_amount; env->dof_blur_near_quality = p_quality; } -void RasterizerSceneGLES3::environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_threshold, VS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, bool p_bicubic_upscale) { +void RasterizerSceneGLES3::environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_threshold, VS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, bool p_bicubic_upscale) { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); @@ -859,6 +859,7 @@ void RasterizerSceneGLES3::environment_set_glow(RID p_env, bool p_enable, int p_ env->glow_blend_mode = p_blend_mode; env->glow_hdr_bleed_threshold = p_hdr_bleed_threshold; env->glow_hdr_bleed_scale = p_hdr_bleed_scale; + env->glow_hdr_luminance_cap = p_hdr_luminance_cap; env->glow_bicubic_upscale = p_bicubic_upscale; } void RasterizerSceneGLES3::environment_set_fog(RID p_env, bool p_enable, float p_begin, float p_end, RID p_gradient_texture) { @@ -934,13 +935,14 @@ void RasterizerSceneGLES3::environment_set_fog(RID p_env, bool p_enable, const C env->fog_sun_amount = p_sun_amount; } -void RasterizerSceneGLES3::environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_curve, bool p_transmit, float p_transmit_curve) { +void RasterizerSceneGLES3::environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_end, float p_depth_curve, bool p_transmit, float p_transmit_curve) { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); env->fog_depth_enabled = p_enable; env->fog_depth_begin = p_depth_begin; + env->fog_depth_end = p_depth_end; env->fog_depth_curve = p_depth_curve; env->fog_transmit_enabled = p_transmit; env->fog_transmit_curve = p_transmit_curve; @@ -1189,11 +1191,12 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material *p_m if (t) { + t = t->get_ptr(); //resolve for proxies + if (t->redraw_if_visible) { //must check before proxy because this is often used with proxies VisualServerRaster::redraw_request(); } - t = t->get_ptr(); //resolve for proxies #ifdef TOOLS_ENABLED if (t->detect_3d) { t->detect_3d(t->detect_3d_ud); @@ -1428,7 +1431,16 @@ void RasterizerSceneGLES3::_setup_geometry(RenderList::Element *e, const Transfo if (particles->draw_order == VS::PARTICLES_DRAW_ORDER_VIEW_DEPTH && particles->particle_valid_histories[1]) { glBindBuffer(GL_ARRAY_BUFFER, particles->particle_buffer_histories[1]); //modify the buffer, this was used 2 frames ago so it should be good enough for flushing - RasterizerGLES3Particle *particle_array = (RasterizerGLES3Particle *)glMapBufferRange(GL_ARRAY_BUFFER, 0, particles->amount * 24 * sizeof(float), GL_MAP_READ_BIT | GL_MAP_WRITE_BIT); + RasterizerGLES3Particle *particle_array; +#ifndef __EMSCRIPTEN__ + particle_array = static_cast<RasterizerGLES3Particle *>(glMapBufferRange(GL_ARRAY_BUFFER, 0, particles->amount * 24 * sizeof(float), GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)); +#else + PoolVector<RasterizerGLES3Particle> particle_vector; + particle_vector.resize(particles->amount); + PoolVector<RasterizerGLES3Particle>::Write w = particle_vector.write(); + particle_array = w.ptr(); + glGetBufferSubData(GL_ARRAY_BUFFER, 0, particles->amount * sizeof(RasterizerGLES3Particle), particle_array); +#endif SortArray<RasterizerGLES3Particle, RasterizerGLES3ParticleSort> sorter; @@ -1440,7 +1452,17 @@ void RasterizerSceneGLES3::_setup_geometry(RenderList::Element *e, const Transfo sorter.sort(particle_array, particles->amount); +#ifndef __EMSCRIPTEN__ glUnmapBuffer(GL_ARRAY_BUFFER); +#else + w = PoolVector<RasterizerGLES3Particle>::Write(); + particle_array = NULL; + { + PoolVector<RasterizerGLES3Particle>::Read r = particle_vector.read(); + glBufferSubData(GL_ARRAY_BUFFER, 0, particles->amount * sizeof(RasterizerGLES3Particle), r.ptr()); + } + particle_vector = PoolVector<RasterizerGLES3Particle>(); +#endif #ifdef DEBUG_ENABLED if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_WIREFRAME && s->instancing_array_wireframe_id) { glBindVertexArray(s->instancing_array_wireframe_id); // use the wireframe instancing array ID @@ -2202,7 +2224,6 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_ _set_cull(e->sort_key & RenderList::SORT_KEY_MIRROR_FLAG, e->sort_key & RenderList::SORT_KEY_CULL_DISABLED_FLAG, p_reverse_cull); - state.scene_shader.set_uniform(SceneShaderGLES3::NORMAL_MULT, e->instance->mirror ? -1.0 : 1.0); state.scene_shader.set_uniform(SceneShaderGLES3::WORLD_TRANSFORM, e->instance->transform); _render_geometry(e); @@ -2568,6 +2589,7 @@ void RasterizerSceneGLES3::_setup_environment(Environment *env, const CameraMatr state.ubo_data.fog_color_enabled[1] = linear_fog.g; state.ubo_data.fog_color_enabled[2] = linear_fog.b; state.ubo_data.fog_color_enabled[3] = (!p_no_fog && env->fog_enabled) ? 1.0 : 0.0; + state.ubo_data.fog_density = linear_fog.a; Color linear_sun = env->fog_sun_color.to_linear(); state.ubo_data.fog_sun_color_amount[0] = linear_sun.r; @@ -2576,6 +2598,7 @@ void RasterizerSceneGLES3::_setup_environment(Environment *env, const CameraMatr state.ubo_data.fog_sun_color_amount[3] = env->fog_sun_amount; state.ubo_data.fog_depth_enabled = env->fog_depth_enabled; state.ubo_data.fog_depth_begin = env->fog_depth_begin; + state.ubo_data.fog_depth_end = env->fog_depth_end; state.ubo_data.fog_depth_curve = env->fog_depth_curve; state.ubo_data.fog_transmit_enabled = env->fog_transmit_enabled; state.ubo_data.fog_transmit_curve = env->fog_transmit_curve; @@ -3017,20 +3040,17 @@ void RasterizerSceneGLES3::_setup_reflections(RID *p_reflection_probe_cull_resul reflection_ubo.ambient[3] = rpi->probe_ptr->interior_ambient_probe_contrib; } else { Color ambient_linear; - // FIXME: contrib was retrieved but never used, is it meant to be set as ambient[3]? (GH-20361) - //float contrib = 0; if (p_env) { ambient_linear = p_env->ambient_color.to_linear(); ambient_linear.r *= p_env->ambient_energy; ambient_linear.g *= p_env->ambient_energy; ambient_linear.b *= p_env->ambient_energy; - //contrib = p_env->ambient_sky_contribution; } reflection_ubo.ambient[0] = ambient_linear.r; reflection_ubo.ambient[1] = ambient_linear.g; reflection_ubo.ambient[2] = ambient_linear.b; - reflection_ubo.ambient[3] = 0; + reflection_ubo.ambient[3] = 0; //not used in exterior mode, since it just blends with regular ambient light } int cell_size = reflection_atlas->size / reflection_atlas->subdiv; @@ -3577,7 +3597,7 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); } - if (!env || storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) { + if (!env || storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT] || storage->frame.current_rt->width < 4 || storage->frame.current_rt->height < 4) { //no post process on small render targets //no environment or transparent render, simply return and convert to SRGB glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->fbo); glActiveTexture(GL_TEXTURE0); @@ -3879,6 +3899,7 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::PIXEL_SIZE, Vector2(1.0 / vp_w, 1.0 / vp_h)); state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::LOD, float(i)); state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::GLOW_STRENGTH, env->glow_strength); + state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::LUMINANCE_CAP, env->glow_hdr_luminance_cap); glActiveTexture(GL_TEXTURE0); if (i == 0) { @@ -4275,8 +4296,10 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const glClearBufferfv(GL_COLOR, 0, clear_color.components); // specular } + VS::EnvironmentBG bg_mode = (!env || (probe && env->bg_mode == VS::ENV_BG_CANVAS)) ? VS::ENV_BG_CLEAR_COLOR : env->bg_mode; //if no environment, or canvas while rendering a probe (invalid use case), use color. + if (env) { - switch (env->bg_mode) { + switch (bg_mode) { case VS::ENV_BG_COLOR_SKY: case VS::ENV_BG_SKY: @@ -4319,6 +4342,10 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const } } + if (probe && probe->probe_ptr->interior) { + env_radiance_tex = 0; //for rendering probe interiors, radiance must not be used. + } + state.texscreen_copied = false; glBlendEquation(GL_FUNC_ADD); diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h index 4b4a0b9303..0e6027c4ad 100644 --- a/drivers/gles3/rasterizer_scene_gles3.h +++ b/drivers/gles3/rasterizer_scene_gles3.h @@ -145,6 +145,8 @@ public: uint32_t fog_depth_enabled; float fog_depth_begin; + float fog_depth_end; + float fog_density; float fog_depth_curve; uint32_t fog_transmit_enabled; float fog_transmit_curve; @@ -402,6 +404,7 @@ public: VS::EnvironmentGlowBlendMode glow_blend_mode; float glow_hdr_bleed_threshold; float glow_hdr_bleed_scale; + float glow_hdr_luminance_cap; bool glow_bicubic_upscale; VS::EnvironmentToneMapper tone_mapper; @@ -438,6 +441,7 @@ public: bool fog_depth_enabled; float fog_depth_begin; + float fog_depth_end; float fog_depth_curve; bool fog_transmit_enabled; float fog_transmit_curve; @@ -491,6 +495,7 @@ public: glow_blend_mode = VS::GLOW_BLEND_MODE_SOFTLIGHT; glow_hdr_bleed_threshold = 1.0; glow_hdr_bleed_scale = 2.0; + glow_hdr_luminance_cap = 12.0; glow_bicubic_upscale = false; dof_blur_far_enabled = false; @@ -518,6 +523,7 @@ public: fog_depth_enabled = true; fog_depth_begin = 10; + fog_depth_end = 0; fog_depth_curve = 1; fog_transmit_enabled = true; @@ -544,7 +550,7 @@ public: virtual void environment_set_dof_blur_near(RID p_env, bool p_enable, float p_distance, float p_transition, float p_amount, VS::EnvironmentDOFBlurQuality p_quality); virtual void environment_set_dof_blur_far(RID p_env, bool p_enable, float p_distance, float p_transition, float p_amount, VS::EnvironmentDOFBlurQuality p_quality); - virtual void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_threshold, VS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, bool p_bicubic_upscale); + virtual void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_threshold, VS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, bool p_bicubic_upscale); virtual void environment_set_fog(RID p_env, bool p_enable, float p_begin, float p_end, RID p_gradient_texture); virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_in, float p_fade_out, float p_depth_tolerance, bool p_roughness); @@ -555,7 +561,7 @@ public: virtual void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, RID p_ramp); virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_color, const Color &p_sun_color, float p_sun_amount); - virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_curve, bool p_transmit, float p_transmit_curve); + virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_end, float p_depth_curve, bool p_transmit, float p_transmit_curve); virtual void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve); virtual bool is_environment(RID p_env); diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index 406ef6af78..2b038fcc0e 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -101,6 +101,28 @@ #define _EXT_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E #define _EXT_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F +#ifdef __EMSCRIPTEN__ +#include <emscripten/emscripten.h> + +void glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data) { + + /* clang-format off */ + EM_ASM({ + GLctx.getBufferSubData($0, $1, HEAPU8, $2, $3); + }, target, offset, data, size); + /* clang-format on */ +} + +void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data) { + + /* clang-format off */ + EM_ASM({ + GLctx.bufferSubData($0, $1, HEAPU8, $2, $3); + }, target, offset, data, size); + /* clang-format on */ +} +#endif + void glTexStorage2DCustom(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type) { #ifdef GLES_OVER_GL @@ -852,8 +874,6 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Ref<Image> &p int size, ofs; img->get_mipmap_offset_and_size(i, ofs, size); - //print_line("mipmap: "+itos(i)+" size: "+itos(size)+" w: "+itos(mm_w)+", h: "+itos(mm_h)); - if (texture->type == VS::TEXTURE_TYPE_2D || texture->type == VS::TEXTURE_TYPE_CUBEMAP) { if (texture->compressed) { @@ -1040,8 +1060,6 @@ Ref<Image> RasterizerStorageGLES3::texture_get_data(RID p_texture, int p_layer) glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); - //print_line("GET FORMAT: " + Image::get_format_name(texture->format) + " mipmaps: " + itos(texture->mipmaps)); - for (int i = 0; i < texture->mipmaps; i++) { int ofs = 0; @@ -1094,8 +1112,76 @@ Ref<Image> RasterizerStorageGLES3::texture_get_data(RID p_texture, int p_layer) return Ref<Image>(img); #else - ERR_EXPLAIN("Sorry, It's not possible to obtain images back in OpenGL ES"); - ERR_FAIL_V(Ref<Image>()); + Image::Format real_format; + GLenum gl_format; + GLenum gl_internal_format; + GLenum gl_type; + bool compressed; + bool srgb; + _get_gl_image_and_format(Ref<Image>(), texture->format, texture->flags, real_format, gl_format, gl_internal_format, gl_type, compressed, srgb); + + PoolVector<uint8_t> data; + + int data_size = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, Image::FORMAT_RGBA8, false); + + data.resize(data_size * 2); //add some memory at the end, just in case for buggy drivers + PoolVector<uint8_t>::Write wb = data.write(); + + GLuint temp_framebuffer; + glGenFramebuffers(1, &temp_framebuffer); + + GLuint temp_color_texture; + glGenTextures(1, &temp_color_texture); + + glBindFramebuffer(GL_FRAMEBUFFER, temp_framebuffer); + + glBindTexture(GL_TEXTURE_2D, temp_color_texture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture->alloc_width, texture->alloc_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, temp_color_texture, 0); + + 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, texture->tex_id); + + glViewport(0, 0, texture->alloc_width, texture->alloc_height); + + shaders.copy.bind(); + + shaders.copy.set_conditional(CopyShaderGLES3::LINEAR_TO_SRGB, !srgb); + + glClearColor(0.0, 0.0, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + glBindVertexArray(resources.quadie_array); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + glBindVertexArray(0); + + glReadPixels(0, 0, texture->alloc_width, texture->alloc_height, GL_RGBA, GL_UNSIGNED_BYTE, &wb[0]); + + shaders.copy.set_conditional(CopyShaderGLES3::LINEAR_TO_SRGB, false); + + glDeleteTextures(1, &temp_color_texture); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glDeleteFramebuffers(1, &temp_framebuffer); + + wb = PoolVector<uint8_t>::Write(); + + data.resize(data_size); + + Image *img = memnew(Image(texture->alloc_width, texture->alloc_height, false, Image::FORMAT_RGBA8, data)); + if (!texture->compressed) { + img->convert(real_format); + } + + return Ref<Image>(img); #endif } @@ -1811,6 +1897,10 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const { p_shader->uniforms.clear(); + if (p_shader->code == String()) { + return; //just invalid, but no error + } + ShaderCompilerGLES3::GeneratedCode gen_code; ShaderCompilerGLES3::IdentifierActions *actions = NULL; @@ -2157,8 +2247,9 @@ Variant RasterizerStorageGLES3::material_get_param_default(RID p_material, const if (material->shader) { if (material->shader->uniforms.has(p_param)) { - Vector<ShaderLanguage::ConstantNode::Value> default_value = material->shader->uniforms[p_param].default_value; - return ShaderLanguage::constant_value_to_variant(default_value, material->shader->uniforms[p_param].type); + ShaderLanguage::ShaderNode::Uniform uniform = material->shader->uniforms[p_param]; + Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value; + return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.hint); } } return Variant(); @@ -2738,7 +2829,7 @@ void RasterizerStorageGLES3::_update_material(Material *material) { if (material->shader && material->shader->mode == VS::SHADER_SPATIAL) { if (material->shader->spatial.blend_mode == Shader::Spatial::BLEND_MODE_MIX && - (!material->shader->spatial.uses_alpha || (material->shader->spatial.uses_alpha && material->shader->spatial.depth_draw_mode == Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS))) { + (!material->shader->spatial.uses_alpha || material->shader->spatial.depth_draw_mode == Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS)) { can_cast_shadow = true; } @@ -2759,7 +2850,7 @@ void RasterizerStorageGLES3::_update_material(Material *material) { } for (Map<RasterizerScene::InstanceBase *, int>::Element *E = material->instance_owners.front(); E; E = E->next()) { - E->key()->base_material_changed(); + E->key()->base_changed(false, true); } } } @@ -2795,9 +2886,6 @@ void RasterizerStorageGLES3::_update_material(Material *material) { if (E->get().order < 0) continue; // texture, does not go here - //if (material->shader->mode == VS::SHADER_PARTICLES) { - // print_line("uniform " + String(E->key()) + " order " + itos(E->get().order) + " offset " + itos(material->shader->ubo_offsets[E->get().order])); - //} //regular uniform uint8_t *data = &local_ubo[material->shader->ubo_offsets[E->get().order]]; @@ -3385,7 +3473,7 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh, uint32_t p_format, VS: } mesh->surfaces.push_back(surface); - mesh->instance_change_notify(); + mesh->instance_change_notify(true, false); info.vertex_mem += surface->total_data_size; } @@ -3458,7 +3546,7 @@ void RasterizerStorageGLES3::mesh_surface_set_material(RID p_mesh, int p_surface _material_add_geometry(mesh->surfaces[p_surface]->material, mesh->surfaces[p_surface]); } - mesh->instance_material_change_notify(); + mesh->instance_change_notify(false, true); } RID RasterizerStorageGLES3::mesh_surface_get_material(RID p_mesh, int p_surface) const { @@ -3494,21 +3582,26 @@ PoolVector<uint8_t> RasterizerStorageGLES3::mesh_surface_get_array(RID p_mesh, i Surface *surface = mesh->surfaces[p_surface]; - glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id); - void *data = glMapBufferRange(GL_ARRAY_BUFFER, 0, surface->array_byte_size, GL_MAP_READ_BIT); - - ERR_FAIL_COND_V(!data, PoolVector<uint8_t>()); - PoolVector<uint8_t> ret; ret.resize(surface->array_byte_size); + glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id); +#if defined(GLES_OVER_GL) || defined(__EMSCRIPTEN__) + { + PoolVector<uint8_t>::Write w = ret.write(); + glGetBufferSubData(GL_ARRAY_BUFFER, 0, surface->array_byte_size, w.ptr()); + } +#else + void *data = glMapBufferRange(GL_ARRAY_BUFFER, 0, surface->array_byte_size, GL_MAP_READ_BIT); + ERR_FAIL_NULL_V(data, PoolVector<uint8_t>()); { - PoolVector<uint8_t>::Write w = ret.write(); copymem(w.ptr(), data, surface->array_byte_size); } glUnmapBuffer(GL_ARRAY_BUFFER); +#endif + glBindBuffer(GL_ARRAY_BUFFER, 0); return ret; } @@ -3521,22 +3614,26 @@ PoolVector<uint8_t> RasterizerStorageGLES3::mesh_surface_get_index_array(RID p_m ERR_FAIL_COND_V(surface->index_array_len == 0, PoolVector<uint8_t>()); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, surface->index_id); - void *data = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, surface->index_array_byte_size, GL_MAP_READ_BIT); - - ERR_FAIL_COND_V(!data, PoolVector<uint8_t>()); - PoolVector<uint8_t> ret; ret.resize(surface->index_array_byte_size); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, surface->index_id); +#if defined(GLES_OVER_GL) || defined(__EMSCRIPTEN__) + { + PoolVector<uint8_t>::Write w = ret.write(); + glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, surface->index_array_byte_size, w.ptr()); + } +#else + void *data = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, surface->index_array_byte_size, GL_MAP_READ_BIT); + ERR_FAIL_NULL_V(data, PoolVector<uint8_t>()); { - PoolVector<uint8_t>::Write w = ret.write(); copymem(w.ptr(), data, surface->index_array_byte_size); } - glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); +#endif + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); return ret; } @@ -3577,23 +3674,26 @@ Vector<PoolVector<uint8_t> > RasterizerStorageGLES3::mesh_surface_get_blend_shap for (int i = 0; i < mesh->surfaces[p_surface]->blend_shapes.size(); i++) { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->surfaces[p_surface]->blend_shapes[i].vertex_id); - void *data = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, mesh->surfaces[p_surface]->array_byte_size, GL_MAP_READ_BIT); - - ERR_FAIL_COND_V(!data, Vector<PoolVector<uint8_t> >()); - PoolVector<uint8_t> ret; ret.resize(mesh->surfaces[p_surface]->array_byte_size); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->surfaces[p_surface]->blend_shapes[i].vertex_id); +#if defined(GLES_OVER_GL) || defined(__EMSCRIPTEN__) + { + PoolVector<uint8_t>::Write w = ret.write(); + glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, mesh->surfaces[p_surface]->array_byte_size, w.ptr()); + } +#else + void *data = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, mesh->surfaces[p_surface]->array_byte_size, GL_MAP_READ_BIT); + ERR_FAIL_COND_V(!data, Vector<PoolVector<uint8_t> >()); { - PoolVector<uint8_t>::Write w = ret.write(); copymem(w.ptr(), data, mesh->surfaces[p_surface]->array_byte_size); } + glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); +#endif bsarr.push_back(ret); - - glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); } return bsarr; @@ -3642,13 +3742,11 @@ void RasterizerStorageGLES3::mesh_remove_surface(RID p_mesh, int p_surface) { info.vertex_mem -= surface->total_data_size; - mesh->instance_material_change_notify(); - memdelete(surface); mesh->surfaces.remove(p_surface); - mesh->instance_change_notify(); + mesh->instance_change_notify(true, true); } int RasterizerStorageGLES3::mesh_get_surface_count(RID p_mesh) const { @@ -3664,7 +3762,7 @@ void RasterizerStorageGLES3::mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb ERR_FAIL_COND(!mesh); mesh->custom_aabb = p_aabb; - mesh->instance_change_notify(); + mesh->instance_change_notify(true, false); } AABB RasterizerStorageGLES3::mesh_get_custom_aabb(RID p_mesh) const { @@ -3680,12 +3778,14 @@ AABB RasterizerStorageGLES3::mesh_get_aabb(RID p_mesh, RID p_skeleton) const { Mesh *mesh = mesh_owner.get(p_mesh); ERR_FAIL_COND_V(!mesh, AABB()); - if (mesh->custom_aabb != AABB()) + if (mesh->custom_aabb != AABB()) { return mesh->custom_aabb; + } Skeleton *sk = NULL; - if (p_skeleton.is_valid()) + if (p_skeleton.is_valid()) { sk = skeleton_owner.get(p_skeleton); + } AABB aabb; @@ -3724,6 +3824,7 @@ AABB RasterizerStorageGLES3::mesh_get_aabb(RID p_mesh, RID p_skeleton) const { mtx.origin.y = texture[base_ofs + 3]; AABB baabb = mtx.xform(skbones[j]); + if (first) { laabb = baabb; first = false; @@ -4563,7 +4664,7 @@ void RasterizerStorageGLES3::update_dirty_multimeshes() { multimesh->dirty_aabb = false; multimesh->dirty_data = false; - multimesh->instance_change_notify(); + multimesh->instance_change_notify(true, false); multimesh_update_list.remove(multimesh_update_list.first()); } @@ -4674,7 +4775,7 @@ void RasterizerStorageGLES3::immediate_end(RID p_immediate) { im->building = false; - im->instance_change_notify(); + im->instance_change_notify(true, false); } void RasterizerStorageGLES3::immediate_clear(RID p_immediate) { @@ -4683,7 +4784,7 @@ void RasterizerStorageGLES3::immediate_clear(RID p_immediate) { ERR_FAIL_COND(im->building); im->chunks.clear(); - im->instance_change_notify(); + im->instance_change_notify(true, false); } AABB RasterizerStorageGLES3::immediate_get_aabb(RID p_immediate) const { @@ -4698,7 +4799,7 @@ void RasterizerStorageGLES3::immediate_set_material(RID p_immediate, RID p_mater Immediate *im = immediate_owner.get(p_immediate); ERR_FAIL_COND(!im); im->material = p_material; - im->instance_material_change_notify(); + im->instance_change_notify(false, true); } RID RasterizerStorageGLES3::immediate_get_material(RID p_immediate) const { @@ -4904,7 +5005,7 @@ void RasterizerStorageGLES3::update_dirty_skeletons() { } for (Set<RasterizerScene::InstanceBase *>::Element *E = skeleton->instances.front(); E; E = E->next()) { - E->get()->base_changed(); + E->get()->base_changed(true, false); } skeleton_update_list.remove(skeleton_update_list.first()); @@ -4970,7 +5071,7 @@ void RasterizerStorageGLES3::light_set_param(RID p_light, VS::LightParam p_param case VS::LIGHT_PARAM_SHADOW_BIAS: { light->version++; - light->instance_change_notify(); + light->instance_change_notify(true, false); } break; default: {} } @@ -4984,7 +5085,7 @@ void RasterizerStorageGLES3::light_set_shadow(RID p_light, bool p_enabled) { light->shadow = p_enabled; light->version++; - light->instance_change_notify(); + light->instance_change_notify(true, false); } void RasterizerStorageGLES3::light_set_shadow_color(RID p_light, const Color &p_color) { @@ -5017,7 +5118,7 @@ void RasterizerStorageGLES3::light_set_cull_mask(RID p_light, uint32_t p_mask) { light->cull_mask = p_mask; light->version++; - light->instance_change_notify(); + light->instance_change_notify(true, false); } void RasterizerStorageGLES3::light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) { @@ -5028,7 +5129,7 @@ void RasterizerStorageGLES3::light_set_reverse_cull_face_mode(RID p_light, bool light->reverse_cull = p_enabled; light->version++; - light->instance_change_notify(); + light->instance_change_notify(true, false); } void RasterizerStorageGLES3::light_omni_set_shadow_mode(RID p_light, VS::LightOmniShadowMode p_mode) { @@ -5039,7 +5140,7 @@ void RasterizerStorageGLES3::light_omni_set_shadow_mode(RID p_light, VS::LightOm light->omni_shadow_mode = p_mode; light->version++; - light->instance_change_notify(); + light->instance_change_notify(true, false); } VS::LightOmniShadowMode RasterizerStorageGLES3::light_omni_get_shadow_mode(RID p_light) { @@ -5057,7 +5158,7 @@ void RasterizerStorageGLES3::light_omni_set_shadow_detail(RID p_light, VS::Light light->omni_shadow_detail = p_detail; light->version++; - light->instance_change_notify(); + light->instance_change_notify(true, false); } void RasterizerStorageGLES3::light_directional_set_shadow_mode(RID p_light, VS::LightDirectionalShadowMode p_mode) { @@ -5067,7 +5168,7 @@ void RasterizerStorageGLES3::light_directional_set_shadow_mode(RID p_light, VS:: light->directional_shadow_mode = p_mode; light->version++; - light->instance_change_notify(); + light->instance_change_notify(true, false); } void RasterizerStorageGLES3::light_directional_set_blend_splits(RID p_light, bool p_enable) { @@ -5077,7 +5178,7 @@ void RasterizerStorageGLES3::light_directional_set_blend_splits(RID p_light, boo light->directional_blend_splits = p_enable; light->version++; - light->instance_change_notify(); + light->instance_change_notify(true, false); } bool RasterizerStorageGLES3::light_directional_get_blend_splits(RID p_light) const { @@ -5208,7 +5309,7 @@ void RasterizerStorageGLES3::reflection_probe_set_update_mode(RID p_probe, VS::R ERR_FAIL_COND(!reflection_probe); reflection_probe->update_mode = p_mode; - reflection_probe->instance_change_notify(); + reflection_probe->instance_change_notify(true, false); } void RasterizerStorageGLES3::reflection_probe_set_intensity(RID p_probe, float p_intensity) { @@ -5249,7 +5350,7 @@ void RasterizerStorageGLES3::reflection_probe_set_max_distance(RID p_probe, floa ERR_FAIL_COND(!reflection_probe); reflection_probe->max_distance = p_distance; - reflection_probe->instance_change_notify(); + reflection_probe->instance_change_notify(true, false); } void RasterizerStorageGLES3::reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) { @@ -5257,7 +5358,7 @@ void RasterizerStorageGLES3::reflection_probe_set_extents(RID p_probe, const Vec ERR_FAIL_COND(!reflection_probe); reflection_probe->extents = p_extents; - reflection_probe->instance_change_notify(); + reflection_probe->instance_change_notify(true, false); } void RasterizerStorageGLES3::reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) { @@ -5265,7 +5366,7 @@ void RasterizerStorageGLES3::reflection_probe_set_origin_offset(RID p_probe, con ERR_FAIL_COND(!reflection_probe); reflection_probe->origin_offset = p_offset; - reflection_probe->instance_change_notify(); + reflection_probe->instance_change_notify(true, false); } void RasterizerStorageGLES3::reflection_probe_set_as_interior(RID p_probe, bool p_enable) { @@ -5289,7 +5390,7 @@ void RasterizerStorageGLES3::reflection_probe_set_enable_shadows(RID p_probe, bo ERR_FAIL_COND(!reflection_probe); reflection_probe->enable_shadows = p_enable; - reflection_probe->instance_change_notify(); + reflection_probe->instance_change_notify(true, false); } void RasterizerStorageGLES3::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) { @@ -5297,7 +5398,7 @@ void RasterizerStorageGLES3::reflection_probe_set_cull_mask(RID p_probe, uint32_ ERR_FAIL_COND(!reflection_probe); reflection_probe->cull_mask = p_layers; - reflection_probe->instance_change_notify(); + reflection_probe->instance_change_notify(true, false); } void RasterizerStorageGLES3::reflection_probe_set_resolution(RID p_probe, int p_resolution) { @@ -5385,7 +5486,7 @@ void RasterizerStorageGLES3::gi_probe_set_bounds(RID p_probe, const AABB &p_boun gip->bounds = p_bounds; gip->version++; - gip->instance_change_notify(); + gip->instance_change_notify(true, false); } AABB RasterizerStorageGLES3::gi_probe_get_bounds(RID p_probe) const { @@ -5402,7 +5503,7 @@ void RasterizerStorageGLES3::gi_probe_set_cell_size(RID p_probe, float p_size) { gip->cell_size = p_size; gip->version++; - gip->instance_change_notify(); + gip->instance_change_notify(true, false); } float RasterizerStorageGLES3::gi_probe_get_cell_size(RID p_probe) const { @@ -5435,7 +5536,7 @@ void RasterizerStorageGLES3::gi_probe_set_dynamic_data(RID p_probe, const PoolVe gip->dynamic_data = p_data; gip->version++; - gip->instance_change_notify(); + gip->instance_change_notify(true, false); } PoolVector<int> RasterizerStorageGLES3::gi_probe_get_dynamic_data(RID p_probe) const { @@ -5667,7 +5768,7 @@ void RasterizerStorageGLES3::lightmap_capture_set_bounds(RID p_capture, const AA LightmapCapture *capture = lightmap_capture_data_owner.getornull(p_capture); ERR_FAIL_COND(!capture); capture->bounds = p_bounds; - capture->instance_change_notify(); + capture->instance_change_notify(true, false); } AABB RasterizerStorageGLES3::lightmap_capture_get_bounds(RID p_capture) const { @@ -5688,7 +5789,7 @@ void RasterizerStorageGLES3::lightmap_capture_set_octree(RID p_capture, const Po PoolVector<uint8_t>::Read r = p_octree.read(); copymem(w.ptr(), r.ptr(), p_octree.size()); } - capture->instance_change_notify(); + capture->instance_change_notify(true, false); } PoolVector<uint8_t> RasterizerStorageGLES3::lightmap_capture_get_octree(RID p_capture) const { @@ -5911,7 +6012,7 @@ void RasterizerStorageGLES3::particles_set_custom_aabb(RID p_particles, const AA ERR_FAIL_COND(!particles); particles->custom_aabb = p_aabb; _particles_update_histories(particles); - particles->instance_change_notify(); + particles->instance_change_notify(true, false); } void RasterizerStorageGLES3::particles_set_speed_scale(RID p_particles, float p_scale) { @@ -6001,9 +6102,21 @@ AABB RasterizerStorageGLES3::particles_get_current_aabb(RID p_particles) { const Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND_V(!particles, AABB()); + const float *data; glBindBuffer(GL_ARRAY_BUFFER, particles->particle_buffers[0]); - float *data = (float *)glMapBufferRange(GL_ARRAY_BUFFER, 0, particles->amount * 16 * 6, GL_MAP_READ_BIT); +#if defined(GLES_OVER_GL) || defined(__EMSCRIPTEN__) + PoolVector<uint8_t> vector; + vector.resize(particles->amount * 16 * 6); + { + PoolVector<uint8_t>::Write w = vector.write(); + glGetBufferSubData(GL_ARRAY_BUFFER, 0, particles->amount * 16 * 6, w.ptr()); + } + PoolVector<uint8_t>::Read r = vector.read(); + data = reinterpret_cast<const float *>(r.ptr()); +#else + data = (float *)glMapBufferRange(GL_ARRAY_BUFFER, 0, particles->amount * 16 * 6, GL_MAP_READ_BIT); +#endif AABB aabb; Transform inv = particles->emission_transform.affine_inverse(); @@ -6020,7 +6133,13 @@ AABB RasterizerStorageGLES3::particles_get_current_aabb(RID p_particles) { aabb.expand_to(pos); } +#if defined(GLES_OVER_GL) || defined(__EMSCRIPTEN__) + r = PoolVector<uint8_t>::Read(); + vector = PoolVector<uint8_t>(); +#else glUnmapBuffer(GL_ARRAY_BUFFER); +#endif + glBindBuffer(GL_ARRAY_BUFFER, 0); float longest_axis = 0; @@ -6319,12 +6438,19 @@ void RasterizerStorageGLES3::update_particles() { particles->particle_valid_histories[0] = true; } - particles->instance_change_notify(); //make sure shadows are updated + particles->instance_change_notify(true, false); //make sure shadows are updated } glDisable(GL_RASTERIZER_DISCARD); } +bool RasterizerStorageGLES3::particles_is_inactive(RID p_particles) const { + + const Particles *particles = particles_owner.getornull(p_particles); + ERR_FAIL_COND_V(!particles, false); + return !particles->emitting && particles->inactive; +} + //////// void RasterizerStorageGLES3::instance_add_skeleton(RID p_skeleton, RasterizerScene::InstanceBase *p_instance) { @@ -7547,7 +7673,7 @@ void RasterizerStorageGLES3::initialize() { config.etc2_supported = true; config.hdr_supported = false; config.s3tc_supported = config.extensions.has("GL_EXT_texture_compression_dxt1") || config.extensions.has("GL_EXT_texture_compression_s3tc") || config.extensions.has("WEBGL_compressed_texture_s3tc"); - config.rgtc_supported = config.extensions.has("GL_EXT_texture_compression_rgtc") || config.extensions.has("GL_ARB_texture_compression_rgtc"); + config.rgtc_supported = config.extensions.has("GL_EXT_texture_compression_rgtc") || config.extensions.has("GL_ARB_texture_compression_rgtc") || config.extensions.has("EXT_texture_compression_rgtc"); #endif config.pvrtc_supported = config.extensions.has("GL_IMG_texture_compression_pvrtc"); diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h index 9a4798ac2a..398ffdeb82 100644 --- a/drivers/gles3/rasterizer_storage_gles3.h +++ b/drivers/gles3/rasterizer_storage_gles3.h @@ -43,6 +43,12 @@ #include "shaders/cubemap_filter.glsl.gen.h" #include "shaders/particles.glsl.gen.h" +// WebGL 2.0 has no MapBufferRange/UnmapBuffer, but offers a non-ES style BufferSubData API instead. +#ifdef __EMSCRIPTEN__ +void glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data); +void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data); +#endif + class RasterizerCanvasGLES3; class RasterizerSceneGLES3; @@ -175,22 +181,12 @@ public: SelfList<RasterizerScene::InstanceBase>::List instance_list; - _FORCE_INLINE_ void instance_change_notify() { + _FORCE_INLINE_ void instance_change_notify(bool p_aabb, bool p_materials) { SelfList<RasterizerScene::InstanceBase> *instances = instance_list.first(); while (instances) { - instances->self()->base_changed(); - instances = instances->next(); - } - } - - _FORCE_INLINE_ void instance_material_change_notify() { - - SelfList<RasterizerScene::InstanceBase> *instances = instance_list.first(); - while (instances) { - - instances->self()->base_material_changed(); + instances->self()->base_changed(p_aabb, p_materials); instances = instances->next(); } } @@ -443,6 +439,7 @@ public: }; int light_mode; + bool uses_screen_texture; bool uses_screen_uv; bool uses_time; @@ -658,7 +655,7 @@ public: bool active; virtual void material_changed_notify() { - mesh->instance_material_change_notify(); + mesh->instance_change_notify(false, true); mesh->update_multimeshes(); } @@ -706,7 +703,7 @@ public: SelfList<MultiMesh> *mm = multimeshes.first(); while (mm) { - mm->self()->instance_material_change_notify(); + mm->self()->instance_change_notify(false, true); mm = mm->next(); } } @@ -1264,6 +1261,8 @@ public: virtual int particles_get_draw_passes(RID p_particles) const; virtual RID particles_get_draw_pass_mesh(RID p_particles, int p_pass) const; + virtual bool particles_is_inactive(RID p_particles) const; + /* INSTANCE */ virtual void instance_add_skeleton(RID p_skeleton, RasterizerScene::InstanceBase *p_instance); diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp index be36b41417..2372dfb17e 100644 --- a/drivers/gles3/shader_compiler_gles3.cpp +++ b/drivers/gles3/shader_compiler_gles3.cpp @@ -133,8 +133,7 @@ static String _interpstr(SL::DataInterpolation p_interp) { switch (p_interp) { case SL::INTERPOLATION_FLAT: return "flat "; - case SL::INTERPOLATION_NO_PERSPECTIVE: return "noperspective "; - case SL::INTERPOLATION_SMOOTH: return "smooth "; + case SL::INTERPOLATION_SMOOTH: return ""; } return ""; } @@ -167,15 +166,17 @@ static String _opstr(SL::Operator p_op) { static String _mkid(const String &p_id) { - return "m_" + p_id; + String id = "m_" + p_id; + return id.replace("__", "_dus_"); //doubleunderscore is reserverd in glsl } static String f2sp0(float p_float) { - if (int(p_float) == p_float) - return itos(p_float) + ".0"; - else - return rtoss(p_float); + String num = rtoss(p_float); + if (num.find(".") == -1 && num.find("e") == -1) { + num += ".0"; + } + return num; } static String get_constant_text(SL::DataType p_type, const Vector<SL::ConstantNode::Value> &p_values) { @@ -228,7 +229,7 @@ static String get_constant_text(SL::DataType p_type, const Vector<SL::ConstantNo text += ")"; return text; } break; - case SL::TYPE_FLOAT: return f2sp0(p_values[0].real) + "f"; + case SL::TYPE_FLOAT: return f2sp0(p_values[0].real); case SL::TYPE_VEC2: case SL::TYPE_VEC3: case SL::TYPE_VEC4: { @@ -476,6 +477,7 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener //code for functions for (int i = 0; i < pnode->functions.size(); i++) { SL::FunctionNode *fnode = pnode->functions[i].function; + current_func_name = fnode->name; function_code[fnode->name] = _dump_node_code(fnode->body, p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning); } diff --git a/drivers/gles3/shader_gles3.cpp b/drivers/gles3/shader_gles3.cpp index 799179e8d4..404a9107ab 100644 --- a/drivers/gles3/shader_gles3.cpp +++ b/drivers/gles3/shader_gles3.cpp @@ -219,20 +219,15 @@ ShaderGLES3::Version *ShaderGLES3::get_current_version() { strings.push_back("#version 300 es\n"); #endif - int define_line_ofs = 1; - for (int i = 0; i < custom_defines.size(); i++) { strings.push_back(custom_defines[i].get_data()); - define_line_ofs++; } for (int j = 0; j < conditional_count; j++) { bool enable = ((1 << j) & conditional_version.version); strings.push_back(enable ? conditional_defines[j] : ""); - if (enable) - define_line_ofs++; if (enable) { DEBUG_PRINT(conditional_defines[j]); @@ -253,7 +248,6 @@ ShaderGLES3::Version *ShaderGLES3::get_current_version() { ERR_FAIL_COND_V(!custom_code_map.has(conditional_version.code_version), NULL); cc = &custom_code_map[conditional_version.code_version]; v.code_version = cc->version; - define_line_ofs += 2; } /* CREATE PROGRAM */ diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl index 8e8b693eb2..51a4edd233 100644 --- a/drivers/gles3/shaders/canvas.glsl +++ b/drivers/gles3/shaders/canvas.glsl @@ -92,11 +92,6 @@ const bool at_light_pass = true; const bool at_light_pass = false; #endif -#ifdef USE_PARTICLES -uniform int h_frames; -uniform int v_frames; -#endif - #if defined(USE_MATERIAL) /* clang-format off */ @@ -146,15 +141,6 @@ void main() { #ifdef USE_PARTICLES //scale by texture size outvec.xy /= color_texpixel_size; - - //compute h and v frames and adjust UV interp for animation - int total_frames = h_frames * v_frames; - int frame = min(int(float(total_frames) * instance_custom.z), total_frames - 1); - float frame_w = 1.0 / float(h_frames); - float frame_h = 1.0 / float(v_frames); - uv_interp.x = uv_interp.x * frame_w + frame_w * float(frame % h_frames); - uv_interp.y = uv_interp.y * frame_h + frame_h * float(frame / h_frames); - #endif #define extra_matrix extra_matrix_instance @@ -491,6 +477,7 @@ void main() { #if defined(NORMALMAP_USED) vec3 normal_map = vec3(0.0, 0.0, 1.0); + normal_used = true; #endif /* clang-format off */ diff --git a/drivers/gles3/shaders/effect_blur.glsl b/drivers/gles3/shaders/effect_blur.glsl index b67d06bc10..fc15ca31b1 100644 --- a/drivers/gles3/shaders/effect_blur.glsl +++ b/drivers/gles3/shaders/effect_blur.glsl @@ -94,6 +94,7 @@ uniform sampler2D source_dof_original; //texunit:2 uniform float exposure; uniform float white; +uniform highp float luminance_cap; #ifdef GLOW_USE_AUTO_EXPOSURE @@ -271,7 +272,7 @@ void main() { float luminance = max(frag_color.r, max(frag_color.g, frag_color.b)); float feedback = max(smoothstep(glow_hdr_threshold, glow_hdr_threshold + glow_hdr_scale, luminance), glow_bloom); - frag_color *= feedback; + frag_color = min(frag_color * feedback, vec4(luminance_cap)); #endif diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index 91ab34f775..407e7ec591 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -42,8 +42,6 @@ layout(location = 4) in vec2 uv_attrib; layout(location = 5) in vec2 uv2_attrib; #endif -uniform float normal_mult; - #ifdef USE_SKELETON layout(location = 6) in uvec4 bone_indices; // attrib:6 layout(location = 7) in vec4 bone_weights; // attrib:7 @@ -98,6 +96,8 @@ layout(std140) uniform SceneData { // ubo:0 bool fog_depth_enabled; highp float fog_depth_begin; + highp float fog_depth_end; + mediump float fog_density; highp float fog_depth_curve; bool fog_transmit_enabled; highp float fog_transmit_curve; @@ -278,11 +278,10 @@ void main() { } #endif - vec3 normal = normal_attrib * normal_mult; + vec3 normal = normal_attrib; #if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY) vec3 tangent = tangent_attrib.xyz; - tangent *= normal_mult; float binormalf = tangent_attrib.a; #endif @@ -675,6 +674,8 @@ layout(std140) uniform SceneData { bool fog_depth_enabled; highp float fog_depth_begin; + highp float fog_depth_end; + mediump float fog_density; highp float fog_depth_curve; bool fog_transmit_enabled; highp float fog_transmit_curve; @@ -949,6 +950,18 @@ LIGHT_SHADER_CODE float NdotV = dot(N, V); float cNdotV = max(NdotV, 0.0); +#if defined(DIFFUSE_BURLEY) || defined(SPECULAR_BLINN) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_USE_CLEARCOAT) + vec3 H = normalize(V + L); +#endif + +#if defined(SPECULAR_BLINN) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_USE_CLEARCOAT) + float cNdotH = max(dot(N, H), 0.0); +#endif + +#if defined(DIFFUSE_BURLEY) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_USE_CLEARCOAT) + float cLdotH = max(dot(L, H), 0.0); +#endif + if (metallic < 1.0) { #if defined(DIFFUSE_OREN_NAYAR) vec3 diffuse_brdf_NL; @@ -983,13 +996,9 @@ LIGHT_SHADER_CODE #elif defined(DIFFUSE_BURLEY) { - - vec3 H = normalize(V + L); - float cLdotH = max(0.0, dot(L, H)); - - float FD90 = 0.5 + 2.0 * cLdotH * cLdotH * roughness; - float FdV = 1.0 + (FD90 - 1.0) * SchlickFresnel(cNdotV); - float FdL = 1.0 + (FD90 - 1.0) * SchlickFresnel(cNdotL); + float FD90_minus_1 = 2.0 * cLdotH * cLdotH * roughness - 0.5; + float FdV = 1.0 + FD90_minus_1 * SchlickFresnel(cNdotV); + float FdL = 1.0 + FD90_minus_1 * SchlickFresnel(cNdotL); diffuse_brdf_NL = (1.0 / M_PI) * FdV * FdL * cNdotL; /* float energyBias = mix(roughness, 0.0, 0.5); @@ -1026,13 +1035,9 @@ LIGHT_SHADER_CODE #if defined(SPECULAR_BLINN) //normalized blinn - vec3 H = normalize(V + L); - float cNdotH = max(dot(N, H), 0.0); - float cVdotH = max(dot(V, H), 0.0); - float cLdotH = max(dot(L, H), 0.0); float shininess = exp2(15.0 * (1.0 - roughness) + 1.0) * 0.25; float blinn = pow(cNdotH, shininess); - blinn *= (shininess + 8.0) / (8.0 * 3.141592654); + blinn *= (shininess + 8.0) * (1.0 / (8.0 * M_PI)); float intensity = (blinn) / max(4.0 * cNdotV * cNdotL, 0.75); specular_light += light_color * intensity * specular_blob_intensity * attenuation; @@ -1043,7 +1048,7 @@ LIGHT_SHADER_CODE float cRdotV = max(0.0, dot(R, V)); float shininess = exp2(15.0 * (1.0 - roughness) + 1.0) * 0.25; float phong = pow(cRdotV, shininess); - phong *= (shininess + 8.0) / (8.0 * 3.141592654); + phong *= (shininess + 8.0) * (1.0 / (8.0 * M_PI)); float intensity = (phong) / max(4.0 * cNdotV * cNdotL, 0.75); specular_light += light_color * intensity * specular_blob_intensity * attenuation; @@ -1063,11 +1068,6 @@ LIGHT_SHADER_CODE #elif defined(SPECULAR_SCHLICK_GGX) // shlick+ggx as default - vec3 H = normalize(V + L); - - float cNdotH = max(dot(N, H), 0.0); - float cLdotH = max(dot(L, H), 0.0); - #if defined(LIGHT_USE_ANISOTROPY) float alpha = roughness * roughness; @@ -1095,23 +1095,17 @@ LIGHT_SHADER_CODE #endif #if defined(LIGHT_USE_CLEARCOAT) - if (clearcoat_gloss > 0.0) { -#if !defined(SPECULAR_SCHLICK_GGX) && !defined(SPECULAR_BLINN) - vec3 H = normalize(V + L); -#endif + #if !defined(SPECULAR_SCHLICK_GGX) - float cNdotH = max(dot(N, H), 0.0); - float cLdotH = max(dot(L, H), 0.0); - float cLdotH5 = SchlickFresnel(cLdotH); + float cLdotH5 = SchlickFresnel(cLdotH); #endif - float Dr = GTR1(cNdotH, mix(.1, .001, clearcoat_gloss)); - float Fr = mix(.04, 1.0, cLdotH5); - float Gr = G_GGX_2cos(cNdotL, .25) * G_GGX_2cos(cNdotV, .25); + float Dr = GTR1(cNdotH, mix(.1, .001, clearcoat_gloss)); + float Fr = mix(.04, 1.0, cLdotH5); + float Gr = G_GGX_2cos(cNdotL, .25) * G_GGX_2cos(cNdotV, .25); - float specular_brdf_NL = 0.25 * clearcoat * Gr * Fr * Dr * cNdotL; + float clearcoat_specular_brdf_NL = 0.25 * clearcoat * Gr * Fr * Dr * cNdotL; - specular_light += specular_brdf_NL * light_color * specular_blob_intensity * attenuation; - } + specular_light += clearcoat_specular_brdf_NL * light_color * specular_blob_intensity * attenuation; #endif } @@ -1510,7 +1504,7 @@ void gi_probe_compute(mediump sampler3D probe, mat4 probe_xform, vec3 bounds, ve //irradiance - vec3 irr_light = voxel_cone_trace(probe, cell_size, probe_pos, environment, blend_ambient, ref_vec, max(min_ref_tan, tan(roughness * 0.5 * M_PI)), max_distance, p_bias); + vec3 irr_light = voxel_cone_trace(probe, cell_size, probe_pos, environment, blend_ambient, ref_vec, max(min_ref_tan, tan(roughness * 0.5 * M_PI * 0.99)), max_distance, p_bias); irr_light *= multiplier; //irr_light=vec3(0.0); @@ -1591,24 +1585,24 @@ void main() { float alpha = 1.0; -#if defined(DO_SIDE_CHECK) - float side = gl_FrontFacing ? 1.0 : -1.0; -#else - float side = 1.0; -#endif - #if defined(ALPHA_SCISSOR_USED) float alpha_scissor = 0.5; #endif #if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY) - vec3 binormal = normalize(binormal_interp) * side; - vec3 tangent = normalize(tangent_interp) * side; + vec3 binormal = normalize(binormal_interp); + vec3 tangent = normalize(tangent_interp); #else vec3 binormal = vec3(0.0); vec3 tangent = vec3(0.0); #endif - vec3 normal = normalize(normal_interp) * side; + vec3 normal = normalize(normal_interp); + +#if defined(DO_SIDE_CHECK) + if (!gl_FrontFacing) { + normal = -normal; + } +#endif #if defined(ENABLE_UV_INTERP) vec2 uv = uv_interp; @@ -1664,7 +1658,7 @@ FRAGMENT_SHADER_CODE normalmap.xy = normalmap.xy * 2.0 - 1.0; normalmap.z = sqrt(max(0.0, 1.0 - dot(normalmap.xy, normalmap.xy))); //always ignore Z, as it can be RG packed, Z may be pos/neg, etc. - normal = normalize(mix(normal_interp, tangent * normalmap.x + binormal * normalmap.y + normal * normalmap.z, normaldepth)) * side; + normal = normalize(mix(normal, tangent * normalmap.x + binormal * normalmap.y + normal * normalmap.z, normaldepth)); #endif @@ -2033,10 +2027,11 @@ FRAGMENT_SHADER_CODE //apply fog if (fog_depth_enabled) { + float fog_far = fog_depth_end > 0 ? fog_depth_end : z_far; - float fog_z = smoothstep(fog_depth_begin, z_far, length(vertex)); + float fog_z = smoothstep(fog_depth_begin, fog_far, length(vertex)); - fog_amount = pow(fog_z, fog_depth_curve); + fog_amount = pow(fog_z, fog_depth_curve) * fog_density; if (fog_transmit_enabled) { vec3 total_light = emission + ambient_light + specular_light + diffuse_light; float transmit = pow(fog_z, fog_transmit_curve); diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.cpp b/drivers/pulseaudio/audio_driver_pulseaudio.cpp index d78316945f..720824d451 100644 --- a/drivers/pulseaudio/audio_driver_pulseaudio.cpp +++ b/drivers/pulseaudio/audio_driver_pulseaudio.cpp @@ -346,9 +346,9 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) { for (int j = 0; j < ad->pa_map.channels - 1; j++) { ad->samples_out.write[out_idx++] = ad->samples_in[in_idx++] >> 16; } - uint32_t l = ad->samples_in[in_idx++]; - uint32_t r = ad->samples_in[in_idx++]; - ad->samples_out.write[out_idx++] = ((l >> 1) + (r >> 1)) >> 16; + uint32_t l = ad->samples_in[in_idx++] >> 16; + uint32_t r = ad->samples_in[in_idx++] >> 16; + ad->samples_out.write[out_idx++] = (l + r) / 2; } } } @@ -374,7 +374,7 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) { const void *ptr = ad->samples_out.ptr(); ret = pa_stream_write(ad->pa_str, (char *)ptr + write_ofs, bytes_to_write, NULL, 0LL, PA_SEEK_RELATIVE); if (ret != 0) { - ERR_PRINT("pa_stream_write error"); + ERR_PRINTS("PulseAudio: pa_stream_write error: " + String(pa_strerror(ret))); } else { avail_bytes -= bytes_to_write; write_ofs += bytes_to_write; @@ -401,6 +401,9 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) { break; } } + + avail_bytes = 0; + write_ofs = 0; } if (ad->pa_rec_str && pa_stream_get_state(ad->pa_rec_str) == PA_STREAM_READY) { diff --git a/drivers/unix/dir_access_unix.cpp b/drivers/unix/dir_access_unix.cpp index 929e67faa9..bea249d4b6 100644 --- a/drivers/unix/dir_access_unix.cpp +++ b/drivers/unix/dir_access_unix.cpp @@ -328,6 +328,17 @@ Error DirAccessUnix::change_dir(String p_dir) { return ERR_INVALID_PARAMETER; } + String base = _get_root_path(); + if (base != String() && !try_dir.begins_with(base)) { + ERR_FAIL_COND_V(getcwd(real_current_dir_name, 2048) == NULL, ERR_BUG); + String new_dir; + new_dir.parse_utf8(real_current_dir_name); + + if (!new_dir.begins_with(base)) { + try_dir = current_dir; //revert + } + } + // the directory exists, so set current_dir to try_dir current_dir = try_dir; ERR_FAIL_COND_V(chdir(prev_dir.utf8().get_data()) != 0, ERR_BUG); diff --git a/drivers/unix/net_socket_posix.cpp b/drivers/unix/net_socket_posix.cpp index 2cc2032cbb..833b17f122 100644 --- a/drivers/unix/net_socket_posix.cpp +++ b/drivers/unix/net_socket_posix.cpp @@ -55,7 +55,7 @@ #include <netinet/tcp.h> -#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED) +#if defined(__APPLE__) #define MSG_NOSIGNAL SO_NOSIGPIPE #endif @@ -110,7 +110,7 @@ size_t NetSocketPosix::_set_addr_storage(struct sockaddr_storage *p_addr, const } else { // IPv4 socket // IPv4 socket with IPv6 address - ERR_FAIL_COND_V(!p_ip.is_ipv4(), 0); + ERR_FAIL_COND_V(!p_ip.is_wildcard() && !p_ip.is_ipv4(), 0); struct sockaddr_in *addr4 = (struct sockaddr_in *)p_addr; addr4->sin_family = AF_INET; @@ -122,7 +122,6 @@ size_t NetSocketPosix::_set_addr_storage(struct sockaddr_storage *p_addr, const addr4->sin_addr.s_addr = INADDR_ANY; } - copymem(&addr4->sin_addr.s_addr, p_ip.get_ipv4(), 4); return sizeof(sockaddr_in); } } diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp index 7ff27be501..279274734f 100644 --- a/drivers/unix/os_unix.cpp +++ b/drivers/unix/os_unix.cpp @@ -288,6 +288,11 @@ uint64_t OS_Unix::get_ticks_usec() const { 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) { +#ifdef __EMSCRIPTEN__ + // Don't compile this code at all to avoid undefined references. + // Actual virtual call goes to OS_JavaScript. + ERR_FAIL_V(ERR_BUG); +#else if (p_blocking && r_pipe) { String argss; @@ -354,6 +359,7 @@ Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, bo } return OK; +#endif } Error OS_Unix::kill(const ProcessID &p_pid) { |