summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/SCsub5
-rw-r--r--drivers/gl_context/context_gl.cpp2
-rw-r--r--drivers/gl_context/context_gl.h2
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp63
-rw-r--r--drivers/gles3/rasterizer_gles3.cpp50
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp108
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.h13
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp140
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.h48
-rw-r--r--drivers/gles3/shader_compiler_gles3.cpp9
-rw-r--r--drivers/gles3/shaders/canvas.glsl3
-rw-r--r--drivers/gles3/shaders/copy.glsl24
-rw-r--r--drivers/gles3/shaders/scene.glsl205
-rw-r--r--drivers/gles3/shaders/ssao.glsl24
-rw-r--r--drivers/gles3/shaders/ssao_blur.glsl20
-rw-r--r--drivers/gles3/shaders/subsurf_scattering.glsl25
-rw-r--r--drivers/gles3/shaders/tonemap.glsl7
-rw-r--r--drivers/unix/SCsub10
-rw-r--r--drivers/unix/os_unix.cpp50
-rw-r--r--drivers/unix/os_unix.h13
-rw-r--r--drivers/wasapi/audio_driver_wasapi.cpp53
-rw-r--r--drivers/wasapi/audio_driver_wasapi.h2
-rw-r--r--drivers/windows/dir_access_windows.cpp2
23 files changed, 488 insertions, 390 deletions
diff --git a/drivers/SCsub b/drivers/SCsub
index 34d6254578..938927f3a9 100644
--- a/drivers/SCsub
+++ b/drivers/SCsub
@@ -34,7 +34,12 @@ if env['tools']:
SConscript("convex_decomp/SCsub")
if env['vsproj']:
+ import os
+ path = os.getcwd()
+ # Change directory so the path resolves correctly in the function call.
+ os.chdir("..")
env.AddToVSProject(env.drivers_sources)
+ os.chdir(path)
if env.split_drivers:
env.split_lib("drivers")
diff --git a/drivers/gl_context/context_gl.cpp b/drivers/gl_context/context_gl.cpp
index a453eef227..1581512369 100644
--- a/drivers/gl_context/context_gl.cpp
+++ b/drivers/gl_context/context_gl.cpp
@@ -29,7 +29,7 @@
/*************************************************************************/
#include "context_gl.h"
-#if defined(OPENGL_ENABLED) || defined(GLES2_ENABLED)
+#if defined(OPENGL_ENABLED) || defined(GLES_ENABLED)
ContextGL *ContextGL::singleton = NULL;
diff --git a/drivers/gl_context/context_gl.h b/drivers/gl_context/context_gl.h
index 399657eb52..3496f2948c 100644
--- a/drivers/gl_context/context_gl.h
+++ b/drivers/gl_context/context_gl.h
@@ -30,7 +30,7 @@
#ifndef CONTEXT_GL_H
#define CONTEXT_GL_H
-#if defined(OPENGL_ENABLED) || defined(GLES2_ENABLED)
+#if defined(OPENGL_ENABLED) || defined(GLES_ENABLED)
#include "typedefs.h"
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index 5d62d2f5a0..308a18aa9d 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -149,13 +149,6 @@ void RasterizerCanvasGLES3::canvas_begin() {
storage->frame.clear_request = false;
}
- /*canvas_shader.unbind();
- canvas_shader.set_custom_shader(0);
- canvas_shader.set_conditional(CanvasShaderGLES2::USE_MODULATE,false);
- canvas_shader.bind();
- canvas_shader.set_uniform(CanvasShaderGLES2::TEXTURE, 0);
- canvas_use_modulate=false;*/
-
reset_canvas();
state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_TEXTURE_RECT, true);
@@ -911,61 +904,6 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur
}
}
-#if 0
-void RasterizerGLES2::_canvas_item_setup_shader_params(ShaderMaterial *material,Shader* shader) {
-
- if (canvas_shader.bind())
- rebind_texpixel_size=true;
-
- if (material->shader_version!=shader->version) {
- //todo optimize uniforms
- material->shader_version=shader->version;
- }
-
- if (shader->has_texscreen && framebuffer.active) {
-
- int x = viewport.x;
- int y = window_size.height-(viewport.height+viewport.y);
-
- canvas_shader.set_uniform(CanvasShaderGLES2::TEXSCREEN_SCREEN_MULT,Vector2(float(viewport.width)/framebuffer.width,float(viewport.height)/framebuffer.height));
- canvas_shader.set_uniform(CanvasShaderGLES2::TEXSCREEN_SCREEN_CLAMP,Color(float(x)/framebuffer.width,float(y)/framebuffer.height,float(x+viewport.width)/framebuffer.width,float(y+viewport.height)/framebuffer.height));
- canvas_shader.set_uniform(CanvasShaderGLES2::TEXSCREEN_TEX,max_texture_units-1);
- glActiveTexture(GL_TEXTURE0+max_texture_units-1);
- glBindTexture(GL_TEXTURE_2D,framebuffer.sample_color);
- if (framebuffer.scale==1 && !canvas_texscreen_used) {
-#ifdef GLEW_ENABLED
- if (current_rt) {
- glReadBuffer(GL_COLOR_ATTACHMENT0);
- } else {
- glReadBuffer(GL_BACK);
- }
-#endif
- if (current_rt) {
- glCopyTexSubImage2D(GL_TEXTURE_2D,0,viewport.x,viewport.y,viewport.x,viewport.y,viewport.width,viewport.height);
- canvas_shader.set_uniform(CanvasShaderGLES2::TEXSCREEN_SCREEN_CLAMP,Color(float(x)/framebuffer.width,float(viewport.y)/framebuffer.height,float(x+viewport.width)/framebuffer.width,float(y+viewport.height)/framebuffer.height));
- //window_size.height-(viewport.height+viewport.y)
- } else {
- glCopyTexSubImage2D(GL_TEXTURE_2D,0,x,y,x,y,viewport.width,viewport.height);
- }
-
- canvas_texscreen_used=true;
- }
-
- glActiveTexture(GL_TEXTURE0);
-
- }
-
- if (shader->has_screen_uv) {
- canvas_shader.set_uniform(CanvasShaderGLES2::SCREEN_UV_MULT,Vector2(1.0/viewport.width,1.0/viewport.height));
- }
-
-
- uses_texpixel_size=shader->uses_texpixel_size;
-
-}
-
-#endif
-
void RasterizerCanvasGLES3::_copy_texscreen(const Rect2 &p_rect) {
glDisable(GL_BLEND);
@@ -1570,6 +1508,7 @@ void RasterizerCanvasGLES3::reset_canvas() {
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
glDisable(GL_SCISSOR_TEST);
+ glDisable(GL_DITHER);
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
if (storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) {
diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp
index d1c8ccfe21..ee61481a86 100644
--- a/drivers/gles3/rasterizer_gles3.cpp
+++ b/drivers/gles3/rasterizer_gles3.cpp
@@ -83,6 +83,9 @@ static void GLAPIENTRY _gl_debug_print(GLenum source, GLenum type, GLuint id, GL
if (type == _EXT_DEBUG_TYPE_OTHER_ARB)
return;
+ if (type == _EXT_DEBUG_TYPE_PERFORMANCE_ARB)
+ return; //these are ultimately annoying, so removing for now
+
char debSource[256], debType[256], debSev[256];
if (source == _EXT_DEBUG_SOURCE_API_ARB)
strcpy(debSource, "OpenGL");
@@ -138,53 +141,48 @@ void RasterizerGLES3::initialize() {
print_line("Using GLES3 video driver");
}
-#ifdef GLEW_ENABLED
- GLuint res = glewInit();
- ERR_FAIL_COND(res != GLEW_OK);
- if (OS::get_singleton()->is_stdout_verbose()) {
- print_line(String("GLES2: Using GLEW ") + (const char *)glewGetString(GLEW_VERSION));
+#ifdef GLAD_ENABLED
+ if (!gladLoadGL()) {
+ ERR_PRINT("Error initializing GLAD");
}
- // Check for GL 2.1 compatibility, if not bail out
- if (!glewIsSupported("GL_VERSION_3_0")) {
- ERR_PRINT("Your system's graphic drivers seem not to support OpenGL 3.0+ / GLES 3.0, sorry :(\n"
+// GLVersion seems to be used for both GL and GL ES, so we need different version checks for them
+#ifdef OPENGL_ENABLED // OpenGL 3.3 Core Profile required
+ if (GLVersion.major < 3 && GLVersion.minor < 3) {
+#else // OpenGL ES 3.0
+ if (GLVersion.major < 3) {
+#endif
+ ERR_PRINT("Your system's graphic drivers seem not to support OpenGL 3.3 / OpenGL ES 3.0, sorry :(\n"
"Try a drivers update, buy a new GPU or try software rendering on Linux; Godot will now crash with a segmentation fault.");
- OS::get_singleton()->alert("Your system's graphic drivers seem not to support OpenGL 3.0+ / GLES 3.0, sorry :(\n"
+ OS::get_singleton()->alert("Your system's graphic drivers seem not to support OpenGL 3.3 / OpenGL ES 3.0, sorry :(\n"
"Godot Engine will self-destruct as soon as you acknowledge this error message.",
- "Fatal error: Insufficient OpenGL / GLES drivers");
- // TODO: If it's even possible, we should stop the execution without segfault and memory leaks :)
- }
-#endif
-
-#ifdef GLAD_ENABLED
-
- if (!gladLoadGL()) {
- ERR_PRINT("Error initializing GLAD");
+ "Fatal error: Insufficient OpenGL / GLES driver support");
}
#ifdef __APPLE__
// FIXME glDebugMessageCallbackARB does not seem to work on Mac OS X and opengl 3, this may be an issue with our opengl canvas..
#else
- glEnable(_EXT_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
- glDebugMessageCallbackARB(_gl_debug_print, NULL);
- glEnable(_EXT_DEBUG_OUTPUT);
+ if (OS::get_singleton()->is_stdout_verbose()) {
+ glEnable(_EXT_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
+ glDebugMessageCallbackARB(_gl_debug_print, NULL);
+ glEnable(_EXT_DEBUG_OUTPUT);
+ }
#endif
-#endif
+#endif // GLAD_ENABLED
- /* glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB,GL_DEBUG_TYPE_ERROR_ARB,GL_DEBUG_SEVERITY_HIGH_ARB,0,NULL,GL_TRUE);
+ /* // For debugging
+ glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB,GL_DEBUG_TYPE_ERROR_ARB,GL_DEBUG_SEVERITY_HIGH_ARB,0,NULL,GL_TRUE);
glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB,GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB,GL_DEBUG_SEVERITY_HIGH_ARB,0,NULL,GL_TRUE);
glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB,GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB,GL_DEBUG_SEVERITY_HIGH_ARB,0,NULL,GL_TRUE);
glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB,GL_DEBUG_TYPE_PORTABILITY_ARB,GL_DEBUG_SEVERITY_HIGH_ARB,0,NULL,GL_TRUE);
glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB,GL_DEBUG_TYPE_PERFORMANCE_ARB,GL_DEBUG_SEVERITY_HIGH_ARB,0,NULL,GL_TRUE);
glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB,GL_DEBUG_TYPE_OTHER_ARB,GL_DEBUG_SEVERITY_HIGH_ARB,0,NULL,GL_TRUE);
glDebugMessageInsertARB(
-
GL_DEBUG_SOURCE_API_ARB,
GL_DEBUG_TYPE_OTHER_ARB, 1,
GL_DEBUG_SEVERITY_HIGH_ARB,5, "hello");
-
-*/
+ */
const GLubyte *renderer = glGetString(GL_RENDERER);
print_line("OpenGL ES 3.0 Renderer: " + String((const char *)renderer));
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index eaf0b06664..0c57e4e9cf 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -379,6 +379,7 @@ bool RasterizerSceneGLES3::shadow_atlas_update_light(RID p_atlas, RID p_light_in
sh->owner = p_light_intance;
sh->alloc_tick = tick;
sh->version = p_light_version;
+ li->shadow_atlases.insert(p_atlas);
//make new key
key = new_quadrant << ShadowAtlas::QUADRANT_SHIFT;
@@ -414,6 +415,7 @@ bool RasterizerSceneGLES3::shadow_atlas_update_light(RID p_atlas, RID p_light_in
sh->owner = p_light_intance;
sh->alloc_tick = tick;
sh->version = p_light_version;
+ li->shadow_atlases.insert(p_atlas);
//make new key
uint32_t key = new_quadrant << ShadowAtlas::QUADRANT_SHIFT;
@@ -893,7 +895,7 @@ void RasterizerSceneGLES3::environment_set_ssr(RID p_env, bool p_enable, int p_m
env->ssr_roughness = p_roughness;
}
-void RasterizerSceneGLES3::environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, const Color &p_color, bool p_blur) {
+void RasterizerSceneGLES3::environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, const Color &p_color, VS::EnvironmentSSAOQuality p_quality, VisualServer::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
@@ -907,6 +909,8 @@ void RasterizerSceneGLES3::environment_set_ssao(RID p_env, bool p_enable, float
env->ssao_light_affect = p_light_affect;
env->ssao_color = p_color;
env->ssao_filter = p_blur;
+ env->ssao_quality = p_quality;
+ env->ssao_bilateral_sharpness = p_bilateral_sharpness;
}
void RasterizerSceneGLES3::environment_set_tonemap(RID p_env, VS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) {
@@ -2140,7 +2144,6 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
first = false;
}
- glFrontFace(GL_CW);
glBindVertexArray(0);
state.scene_shader.set_conditional(SceneShaderGLES3::USE_INSTANCING, false);
@@ -2349,22 +2352,7 @@ void RasterizerSceneGLES3::_draw_sky(RasterizerStorageGLES3::Sky *p_sky, const C
glDepthFunc(GL_LEQUAL);
glColorMask(1, 1, 1, 1);
- float flip_sign = p_vflip ? -1 : 1;
-
- Vector3 vertices[8] = {
- Vector3(-1, -1 * flip_sign, 1),
- Vector3(0, 1, 0),
- Vector3(1, -1 * flip_sign, 1),
- Vector3(1, 1, 0),
- Vector3(1, 1 * flip_sign, 1),
- Vector3(1, 0, 0),
- Vector3(-1, 1 * flip_sign, 1),
- Vector3(0, 0, 0)
-
- };
-
- //sky uv vectors
- float vw, vh, zn;
+ // Camera
CameraMatrix camera;
if (p_custom_fov) {
@@ -2379,17 +2367,39 @@ void RasterizerSceneGLES3::_draw_sky(RasterizerStorageGLES3::Sky *p_sky, const C
camera = p_projection;
}
- camera.get_viewport_size(vw, vh);
- zn = p_projection.get_z_near();
+ float flip_sign = p_vflip ? -1 : 1;
- for (int i = 0; i < 4; i++) {
+ /*
+ If matrix[2][0] or matrix[2][1] we're dealing with an asymmetrical projection matrix. This is the case for stereoscopic rendering (i.e. VR).
+ To ensure the image rendered is perspective correct we need to move some logic into the shader. For this the USE_ASYM_PANO option is introduced.
+ It also means the uv coordinates are ignored in this mode and we don't need our loop.
+ */
+ bool asymmetrical = ((camera.matrix[2][0] != 0.0) || (camera.matrix[2][1] != 0.0));
+
+ Vector3 vertices[8] = {
+ Vector3(-1, -1 * flip_sign, 1),
+ Vector3(0, 1, 0),
+ Vector3(1, -1 * flip_sign, 1),
+ Vector3(1, 1, 0),
+ Vector3(1, 1 * flip_sign, 1),
+ Vector3(1, 0, 0),
+ Vector3(-1, 1 * flip_sign, 1),
+ Vector3(0, 0, 0)
+ };
- Vector3 uv = vertices[i * 2 + 1];
- uv.x = (uv.x * 2.0 - 1.0) * vw;
- uv.y = -(uv.y * 2.0 - 1.0) * vh;
- uv.z = -zn;
- vertices[i * 2 + 1] = p_transform.basis.xform(uv).normalized();
- vertices[i * 2 + 1].z = -vertices[i * 2 + 1].z;
+ if (!asymmetrical) {
+ float vw, vh, zn;
+ camera.get_viewport_size(vw, vh);
+ zn = p_projection.get_z_near();
+
+ for (int i = 0; i < 4; i++) {
+ Vector3 uv = vertices[i * 2 + 1];
+ uv.x = (uv.x * 2.0 - 1.0) * vw;
+ uv.y = -(uv.y * 2.0 - 1.0) * vh;
+ uv.z = -zn;
+ vertices[i * 2 + 1] = p_transform.basis.xform(uv).normalized();
+ vertices[i * 2 + 1].z = -vertices[i * 2 + 1].z;
+ }
}
glBindBuffer(GL_ARRAY_BUFFER, state.sky_verts);
@@ -2398,16 +2408,24 @@ void RasterizerSceneGLES3::_draw_sky(RasterizerStorageGLES3::Sky *p_sky, const C
glBindVertexArray(state.sky_array);
- storage->shaders.copy.set_conditional(CopyShaderGLES3::USE_PANORAMA, true);
+ storage->shaders.copy.set_conditional(CopyShaderGLES3::USE_ASYM_PANO, asymmetrical);
+ storage->shaders.copy.set_conditional(CopyShaderGLES3::USE_PANORAMA, !asymmetrical);
storage->shaders.copy.set_conditional(CopyShaderGLES3::USE_MULTIPLIER, true);
storage->shaders.copy.bind();
storage->shaders.copy.set_uniform(CopyShaderGLES3::MULTIPLIER, p_energy);
+ if (asymmetrical) {
+ // pack the bits we need from our projection matrix
+ storage->shaders.copy.set_uniform(CopyShaderGLES3::ASYM_PROJ, camera.matrix[2][0], camera.matrix[0][0], camera.matrix[2][1], camera.matrix[1][1]);
+ ///@TODO I couldn't get mat3 + p_transform.basis to work, that would be better here.
+ storage->shaders.copy.set_uniform(CopyShaderGLES3::PANO_TRANSFORM, p_transform);
+ }
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glBindVertexArray(0);
glColorMask(1, 1, 1, 1);
+ storage->shaders.copy.set_conditional(CopyShaderGLES3::USE_ASYM_PANO, false);
storage->shaders.copy.set_conditional(CopyShaderGLES3::USE_MULTIPLIER, false);
storage->shaders.copy.set_conditional(CopyShaderGLES3::USE_PANORAMA, false);
}
@@ -2553,8 +2571,8 @@ void RasterizerSceneGLES3::_setup_directional_light(int p_index, const Transform
ubo_data.light_direction_attenuation[3] = 1.0;
ubo_data.light_params[0] = 0;
- ubo_data.light_params[1] = li->light_ptr->param[VS::LIGHT_PARAM_SPECULAR];
- ubo_data.light_params[2] = 0;
+ ubo_data.light_params[1] = 0;
+ ubo_data.light_params[2] = li->light_ptr->param[VS::LIGHT_PARAM_SPECULAR];
ubo_data.light_params[3] = 0;
Color shadow_color = li->light_ptr->shadow_color.to_linear();
@@ -3170,6 +3188,15 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_
glDisable(GL_CULL_FACE);
glDisable(GL_BLEND);
+ if (env->ssao_enabled || env->ssr_enabled) {
+
+ //copy normal and roughness to effect buffer
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->buffers.fbo);
+ glReadBuffer(GL_COLOR_ATTACHMENT2);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, storage->frame.current_rt->buffers.effect_fbo);
+ glBlitFramebuffer(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, 0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
+ }
+
if (env->ssao_enabled) {
//copy diffuse to front buffer
glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->buffers.fbo);
@@ -3219,6 +3246,8 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_
// do SSAO!
state.ssao_shader.set_conditional(SsaoShaderGLES3::ENABLE_RADIUS2, env->ssao_radius2 > 0.001);
state.ssao_shader.set_conditional(SsaoShaderGLES3::USE_ORTHOGONAL_PROJECTION, p_cam_projection.is_orthogonal());
+ state.ssao_shader.set_conditional(SsaoShaderGLES3::SSAO_QUALITY_LOW, env->ssao_quality == VS::ENV_SSAO_QUALITY_LOW);
+ state.ssao_shader.set_conditional(SsaoShaderGLES3::SSAO_QUALITY_HIGH, env->ssao_quality == VS::ENV_SSAO_QUALITY_HIGH);
state.ssao_shader.bind();
state.ssao_shader.set_uniform(SsaoShaderGLES3::CAMERA_Z_FAR, p_cam_projection.get_z_far());
state.ssao_shader.set_uniform(SsaoShaderGLES3::CAMERA_Z_NEAR, p_cam_projection.get_z_near());
@@ -3271,6 +3300,9 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_
state.ssao_blur_shader.set_uniform(SsaoBlurShaderGLES3::CAMERA_Z_FAR, p_cam_projection.get_z_far());
state.ssao_blur_shader.set_uniform(SsaoBlurShaderGLES3::CAMERA_Z_NEAR, p_cam_projection.get_z_near());
+ state.ssao_blur_shader.set_uniform(SsaoBlurShaderGLES3::EDGE_SHARPNESS, env->ssao_bilateral_sharpness);
+ state.ssao_blur_shader.set_uniform(SsaoBlurShaderGLES3::FILTER_SCALE, int(env->ssao_filter));
+
GLint axis[2] = { i, 1 - i };
glUniform2iv(state.ssao_blur_shader.get_uniform(SsaoBlurShaderGLES3::AXIS), 1, axis);
glUniform2iv(state.ssao_blur_shader.get_uniform(SsaoBlurShaderGLES3::SCREEN_SIZE), 1, ss);
@@ -3279,6 +3311,8 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_
glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.ssao.blur_red[i]);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->depth);
+ glActiveTexture(GL_TEXTURE2);
+ glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->buffers.effect);
glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->effects.ssao.blur_fbo[1 - i]);
if (i == 0) {
glClearBufferfv(GL_COLOR, 0, white.components); // specular
@@ -3370,12 +3404,6 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_
if (env->ssr_enabled) {
- //copy normal and roughness to effect buffer
- glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->buffers.fbo);
- glReadBuffer(GL_COLOR_ATTACHMENT2);
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER, storage->frame.current_rt->buffers.effect_fbo);
- glBlitFramebuffer(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, 0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
-
//blur diffuse into effect mipmaps using separatable convolution
//storage->shaders.copy.set_conditional(CopyShaderGLES3::GAUSSIAN_HORIZONTAL,true);
_blur_effect_buffer();
@@ -3995,6 +4023,8 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
state.ubo_data.shadow_dual_paraboloid_render_side = 0;
state.ubo_data.shadow_dual_paraboloid_render_zfar = 0;
+ p_cam_projection.get_viewport_size(state.ubo_data.viewport_size[0], state.ubo_data.viewport_size[1]);
+
if (storage->frame.current_rt) {
state.ubo_data.screen_pixel_size[0] = 1.0 / storage->frame.current_rt->width;
state.ubo_data.screen_pixel_size[1] = 1.0 / storage->frame.current_rt->height;
@@ -4252,7 +4282,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
if (i > 0) {
glEnable(GL_BLEND);
}
- _setup_directional_light(i, p_cam_transform.affine_inverse(), shadow_atlas != NULL);
+ _setup_directional_light(i, p_cam_transform.affine_inverse(), shadow_atlas != NULL && shadow_atlas->size > 0);
_render_list(render_list.elements, render_list.element_count, p_cam_transform, p_cam_projection, env_radiance_tex, false, false, false, i > 0, shadow_atlas != NULL);
}
}
@@ -4315,7 +4345,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
} else {
for (int i = 0; i < state.directional_light_count; i++) {
directional_light = directional_lights[i];
- _setup_directional_light(i, p_cam_transform.affine_inverse(), shadow_atlas != NULL);
+ _setup_directional_light(i, p_cam_transform.affine_inverse(), shadow_atlas != NULL && shadow_atlas->size > 0);
_render_list(&render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, p_cam_transform, p_cam_projection, env_radiance_tex, false, true, false, i > 0, shadow_atlas != NULL);
}
}
@@ -5024,6 +5054,8 @@ void RasterizerSceneGLES3::initialize() {
}
state.debug_draw = VS::VIEWPORT_DEBUG_DRAW_DISABLED;
+
+ glFrontFace(GL_CW);
}
void RasterizerSceneGLES3::iteration() {
diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h
index 28a5cef0ee..69b43c7813 100644
--- a/drivers/gles3/rasterizer_scene_gles3.h
+++ b/drivers/gles3/rasterizer_scene_gles3.h
@@ -124,6 +124,7 @@ public:
float z_slope_scale;
float shadow_dual_paraboloid_render_zfar;
float shadow_dual_paraboloid_render_side;
+ float viewport_size[2];
float screen_pixel_size[2];
float shadow_atlas_pixel_size[2];
float shadow_directional_pixel_size[2];
@@ -143,7 +144,7 @@ public:
float fog_height_min;
float fog_height_max;
float fog_height_curve;
- uint8_t padding[8];
+ // make sure this struct is padded to be a multiple of 16 bytes for webgl
} ubo_data;
@@ -379,7 +380,9 @@ public:
float ssao_bias;
float ssao_light_affect;
Color ssao_color;
- bool ssao_filter;
+ VS::EnvironmentSSAOQuality ssao_quality;
+ float ssao_bilateral_sharpness;
+ VS::EnvironmentSSAOBlur ssao_filter;
bool glow_enabled;
int glow_levels;
@@ -456,7 +459,9 @@ public:
ssao_radius2 = 0.0;
ssao_bias = 0.01;
ssao_light_affect = 0;
- ssao_filter = true;
+ ssao_filter = VS::ENV_SSAO_BLUR_3x3;
+ ssao_quality = VS::ENV_SSAO_QUALITY_LOW;
+ ssao_bilateral_sharpness = 4;
tone_mapper = VS::ENV_TONE_MAPPER_LINEAR;
tone_mapper_exposure = 1.0;
@@ -532,7 +537,7 @@ public:
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);
- virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, const Color &p_color, bool p_blur);
+ virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, const Color &p_color, VS::EnvironmentSSAOQuality p_quality, VS::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness);
virtual void environment_set_tonemap(RID p_env, VS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale);
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index 44a9909bd7..a41d84a2aa 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -2430,7 +2430,8 @@ void RasterizerStorageGLES3::_update_material(Material *material) {
if (material->shader && material->shader->mode == VS::SHADER_SPATIAL) {
- if (!material->shader->spatial.uses_alpha && material->shader->spatial.blend_mode == Shader::Spatial::BLEND_MODE_MIX) {
+ 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))) {
can_cast_shadow = true;
}
@@ -2599,7 +2600,7 @@ RID RasterizerStorageGLES3::mesh_create() {
return mesh_owner.make_rid(mesh);
}
-void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh, uint32_t p_format, VS::PrimitiveType p_primitive, const PoolVector<uint8_t> &p_array, int p_vertex_count, const PoolVector<uint8_t> &p_index_array, int p_index_count, const Rect3 &p_aabb, const Vector<PoolVector<uint8_t> > &p_blend_shapes, const Vector<Rect3> &p_bone_aabbs) {
+void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh, uint32_t p_format, VS::PrimitiveType p_primitive, const PoolVector<uint8_t> &p_array, int p_vertex_count, const PoolVector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<PoolVector<uint8_t> > &p_blend_shapes, const Vector<AABB> &p_bone_aabbs) {
PoolVector<uint8_t> array = p_array;
@@ -2865,7 +2866,7 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh, uint32_t p_format, VS:
glGenBuffers(1, &surface->vertex_id);
glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id);
- glBufferData(GL_ARRAY_BUFFER, array_size, vr.ptr(), GL_STATIC_DRAW);
+ glBufferData(GL_ARRAY_BUFFER, array_size, vr.ptr(), p_format & VS::ARRAY_FLAG_USE_DYNAMIC_UPDATE ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
if (p_format & VS::ARRAY_FORMAT_INDEX) {
@@ -3103,6 +3104,22 @@ VS::BlendShapeMode RasterizerStorageGLES3::mesh_get_blend_shape_mode(RID p_mesh)
return mesh->blend_shape_mode;
}
+void RasterizerStorageGLES3::mesh_surface_update_region(RID p_mesh, int p_surface, int p_offset, const PoolVector<uint8_t> &p_data) {
+
+ Mesh *mesh = mesh_owner.getornull(p_mesh);
+ ERR_FAIL_COND(!mesh);
+ ERR_FAIL_INDEX(p_surface, mesh->surfaces.size());
+
+ int total_size = p_data.size();
+ ERR_FAIL_COND(p_offset + total_size > mesh->surfaces[p_surface]->array_byte_size);
+
+ PoolVector<uint8_t>::Read r = p_data.read();
+
+ glBindBuffer(GL_ARRAY_BUFFER, mesh->surfaces[p_surface]->array_id);
+ glBufferSubData(GL_ARRAY_BUFFER, p_offset, total_size, r.ptr());
+ glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
+}
+
void RasterizerStorageGLES3::mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) {
Mesh *mesh = mesh_owner.getornull(p_mesh);
@@ -3223,11 +3240,11 @@ VS::PrimitiveType RasterizerStorageGLES3::mesh_surface_get_primitive_type(RID p_
return mesh->surfaces[p_surface]->primitive;
}
-Rect3 RasterizerStorageGLES3::mesh_surface_get_aabb(RID p_mesh, int p_surface) const {
+AABB RasterizerStorageGLES3::mesh_surface_get_aabb(RID p_mesh, int p_surface) const {
const Mesh *mesh = mesh_owner.getornull(p_mesh);
- ERR_FAIL_COND_V(!mesh, Rect3());
- ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), Rect3());
+ ERR_FAIL_COND_V(!mesh, AABB());
+ ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), AABB());
return mesh->surfaces[p_surface]->aabb;
}
@@ -3262,11 +3279,11 @@ Vector<PoolVector<uint8_t> > RasterizerStorageGLES3::mesh_surface_get_blend_shap
return bsarr;
}
-Vector<Rect3> RasterizerStorageGLES3::mesh_surface_get_skeleton_aabb(RID p_mesh, int p_surface) const {
+Vector<AABB> RasterizerStorageGLES3::mesh_surface_get_skeleton_aabb(RID p_mesh, int p_surface) const {
const Mesh *mesh = mesh_owner.getornull(p_mesh);
- ERR_FAIL_COND_V(!mesh, Vector<Rect3>());
- ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), Vector<Rect3>());
+ ERR_FAIL_COND_V(!mesh, Vector<AABB>());
+ ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), Vector<AABB>());
return mesh->surfaces[p_surface]->skeleton_bone_aabb;
}
@@ -3320,7 +3337,7 @@ int RasterizerStorageGLES3::mesh_get_surface_count(RID p_mesh) const {
return mesh->surfaces.size();
}
-void RasterizerStorageGLES3::mesh_set_custom_aabb(RID p_mesh, const Rect3 &p_aabb) {
+void RasterizerStorageGLES3::mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) {
Mesh *mesh = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND(!mesh);
@@ -3328,37 +3345,37 @@ void RasterizerStorageGLES3::mesh_set_custom_aabb(RID p_mesh, const Rect3 &p_aab
mesh->custom_aabb = p_aabb;
}
-Rect3 RasterizerStorageGLES3::mesh_get_custom_aabb(RID p_mesh) const {
+AABB RasterizerStorageGLES3::mesh_get_custom_aabb(RID p_mesh) const {
const Mesh *mesh = mesh_owner.getornull(p_mesh);
- ERR_FAIL_COND_V(!mesh, Rect3());
+ ERR_FAIL_COND_V(!mesh, AABB());
return mesh->custom_aabb;
}
-Rect3 RasterizerStorageGLES3::mesh_get_aabb(RID p_mesh, RID p_skeleton) const {
+AABB RasterizerStorageGLES3::mesh_get_aabb(RID p_mesh, RID p_skeleton) const {
Mesh *mesh = mesh_owner.get(p_mesh);
- ERR_FAIL_COND_V(!mesh, Rect3());
+ ERR_FAIL_COND_V(!mesh, AABB());
- if (mesh->custom_aabb != Rect3())
+ if (mesh->custom_aabb != AABB())
return mesh->custom_aabb;
Skeleton *sk = NULL;
if (p_skeleton.is_valid())
sk = skeleton_owner.get(p_skeleton);
- Rect3 aabb;
+ AABB aabb;
if (sk && sk->size != 0) {
for (int i = 0; i < mesh->surfaces.size(); i++) {
- Rect3 laabb;
+ AABB laabb;
if ((mesh->surfaces[i]->format & VS::ARRAY_FORMAT_BONES) && mesh->surfaces[i]->skeleton_bone_aabb.size()) {
int bs = mesh->surfaces[i]->skeleton_bone_aabb.size();
- const Rect3 *skbones = mesh->surfaces[i]->skeleton_bone_aabb.ptr();
+ const AABB *skbones = mesh->surfaces[i]->skeleton_bone_aabb.ptr();
const bool *skused = mesh->surfaces[i]->skeleton_bone_used.ptr();
int sbs = sk->size;
@@ -3384,7 +3401,7 @@ Rect3 RasterizerStorageGLES3::mesh_get_aabb(RID p_mesh, RID p_skeleton) const {
mtx.basis[1].y = texture[base_ofs + 1];
mtx.origin.y = texture[base_ofs + 3];
- Rect3 baabb = mtx.xform(skbones[j]);
+ AABB baabb = mtx.xform(skbones[j]);
if (first) {
laabb = baabb;
first = false;
@@ -3417,7 +3434,7 @@ Rect3 RasterizerStorageGLES3::mesh_get_aabb(RID p_mesh, RID p_skeleton) const {
mtx.basis[2].z = texture[base_ofs + 2];
mtx.origin.z = texture[base_ofs + 3];
- Rect3 baabb = mtx.xform(skbones[j]);
+ AABB baabb = mtx.xform(skbones[j]);
if (first) {
laabb = baabb;
first = false;
@@ -4011,10 +4028,10 @@ int RasterizerStorageGLES3::multimesh_get_visible_instances(RID p_multimesh) con
return multimesh->visible_instances;
}
-Rect3 RasterizerStorageGLES3::multimesh_get_aabb(RID p_multimesh) const {
+AABB RasterizerStorageGLES3::multimesh_get_aabb(RID p_multimesh) const {
MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
- ERR_FAIL_COND_V(!multimesh, Rect3());
+ ERR_FAIL_COND_V(!multimesh, AABB());
const_cast<RasterizerStorageGLES3 *>(this)->update_dirty_multimeshes(); //update pending AABBs
@@ -4036,7 +4053,7 @@ void RasterizerStorageGLES3::update_dirty_multimeshes() {
if (multimesh->size && multimesh->dirty_aabb) {
- Rect3 mesh_aabb;
+ AABB mesh_aabb;
if (multimesh->mesh.is_valid()) {
mesh_aabb = mesh_get_aabb(multimesh->mesh, RID());
@@ -4048,7 +4065,7 @@ void RasterizerStorageGLES3::update_dirty_multimeshes() {
int count = multimesh->data.size();
float *data = multimesh->data.ptr();
- Rect3 aabb;
+ AABB aabb;
if (multimesh->transform_format == VS::MULTIMESH_TRANSFORM_2D) {
@@ -4063,7 +4080,7 @@ void RasterizerStorageGLES3::update_dirty_multimeshes() {
xform.basis[1][1] = dataptr[5];
xform.origin[1] = dataptr[7];
- Rect3 laabb = xform.xform(mesh_aabb);
+ AABB laabb = xform.xform(mesh_aabb);
if (i == 0)
aabb = laabb;
else
@@ -4089,7 +4106,7 @@ void RasterizerStorageGLES3::update_dirty_multimeshes() {
xform.basis.elements[2][2] = dataptr[10];
xform.origin.z = dataptr[11];
- Rect3 laabb = xform.xform(mesh_aabb);
+ AABB laabb = xform.xform(mesh_aabb);
if (i == 0)
aabb = laabb;
else
@@ -4225,10 +4242,10 @@ void RasterizerStorageGLES3::immediate_clear(RID p_immediate) {
im->instance_change_notify();
}
-Rect3 RasterizerStorageGLES3::immediate_get_aabb(RID p_immediate) const {
+AABB RasterizerStorageGLES3::immediate_get_aabb(RID p_immediate) const {
Immediate *im = immediate_owner.get(p_immediate);
- ERR_FAIL_COND_V(!im, Rect3());
+ ERR_FAIL_COND_V(!im, AABB());
return im->aabb;
}
@@ -4449,6 +4466,7 @@ RID RasterizerStorageGLES3::light_create(VS::LightType p_type) {
light->type = p_type;
light->param[VS::LIGHT_PARAM_ENERGY] = 1.0;
+ light->param[VS::LIGHT_PARAM_INDIRECT_ENERGY] = 1.0;
light->param[VS::LIGHT_PARAM_SPECULAR] = 0.5;
light->param[VS::LIGHT_PARAM_RANGE] = 1.0;
light->param[VS::LIGHT_PARAM_SPOT_ANGLE] = 45;
@@ -4677,10 +4695,10 @@ uint64_t RasterizerStorageGLES3::light_get_version(RID p_light) const {
return light->version;
}
-Rect3 RasterizerStorageGLES3::light_get_aabb(RID p_light) const {
+AABB RasterizerStorageGLES3::light_get_aabb(RID p_light) const {
const Light *light = light_owner.getornull(p_light);
- ERR_FAIL_COND_V(!light, Rect3());
+ ERR_FAIL_COND_V(!light, AABB());
switch (light->type) {
@@ -4688,22 +4706,22 @@ Rect3 RasterizerStorageGLES3::light_get_aabb(RID p_light) const {
float len = light->param[VS::LIGHT_PARAM_RANGE];
float size = Math::tan(Math::deg2rad(light->param[VS::LIGHT_PARAM_SPOT_ANGLE])) * len;
- return Rect3(Vector3(-size, -size, -len), Vector3(size * 2, size * 2, len));
+ return AABB(Vector3(-size, -size, -len), Vector3(size * 2, size * 2, len));
} break;
case VS::LIGHT_OMNI: {
float r = light->param[VS::LIGHT_PARAM_RANGE];
- return Rect3(-Vector3(r, r, r), Vector3(r, r, r) * 2);
+ return AABB(-Vector3(r, r, r), Vector3(r, r, r) * 2);
} break;
case VS::LIGHT_DIRECTIONAL: {
- return Rect3();
+ return AABB();
} break;
default: {}
}
- ERR_FAIL_V(Rect3());
- return Rect3();
+ ERR_FAIL_V(AABB());
+ return AABB();
}
/* PROBE API */
@@ -4825,11 +4843,11 @@ void RasterizerStorageGLES3::reflection_probe_set_cull_mask(RID p_probe, uint32_
reflection_probe->instance_change_notify();
}
-Rect3 RasterizerStorageGLES3::reflection_probe_get_aabb(RID p_probe) const {
+AABB RasterizerStorageGLES3::reflection_probe_get_aabb(RID p_probe) const {
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
- ERR_FAIL_COND_V(!reflection_probe, Rect3());
+ ERR_FAIL_COND_V(!reflection_probe, AABB());
- Rect3 aabb;
+ AABB aabb;
aabb.position = -reflection_probe->extents;
aabb.size = reflection_probe->extents * 2.0;
@@ -4886,7 +4904,7 @@ RID RasterizerStorageGLES3::gi_probe_create() {
GIProbe *gip = memnew(GIProbe);
- gip->bounds = Rect3(Vector3(), Vector3(1, 1, 1));
+ gip->bounds = AABB(Vector3(), Vector3(1, 1, 1));
gip->dynamic_range = 1.0;
gip->energy = 1.0;
gip->propagation = 1.0;
@@ -4900,7 +4918,7 @@ RID RasterizerStorageGLES3::gi_probe_create() {
return gi_probe_owner.make_rid(gip);
}
-void RasterizerStorageGLES3::gi_probe_set_bounds(RID p_probe, const Rect3 &p_bounds) {
+void RasterizerStorageGLES3::gi_probe_set_bounds(RID p_probe, const AABB &p_bounds) {
GIProbe *gip = gi_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!gip);
@@ -4909,10 +4927,10 @@ void RasterizerStorageGLES3::gi_probe_set_bounds(RID p_probe, const Rect3 &p_bou
gip->version++;
gip->instance_change_notify();
}
-Rect3 RasterizerStorageGLES3::gi_probe_get_bounds(RID p_probe) const {
+AABB RasterizerStorageGLES3::gi_probe_get_bounds(RID p_probe) const {
const GIProbe *gip = gi_probe_owner.getornull(p_probe);
- ERR_FAIL_COND_V(!gip, Rect3());
+ ERR_FAIL_COND_V(!gip, AABB());
return gip->bounds;
}
@@ -5321,7 +5339,7 @@ void RasterizerStorageGLES3::_particles_update_histories(Particles *particles) {
particles->clear = true;
}
-void RasterizerStorageGLES3::particles_set_custom_aabb(RID p_particles, const Rect3 &p_aabb) {
+void RasterizerStorageGLES3::particles_set_custom_aabb(RID p_particles, const AABB &p_aabb) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
@@ -5412,15 +5430,15 @@ void RasterizerStorageGLES3::particles_request_process(RID p_particles) {
}
}
-Rect3 RasterizerStorageGLES3::particles_get_current_aabb(RID p_particles) {
+AABB RasterizerStorageGLES3::particles_get_current_aabb(RID p_particles) {
const Particles *particles = particles_owner.getornull(p_particles);
- ERR_FAIL_COND_V(!particles, Rect3());
+ ERR_FAIL_COND_V(!particles, AABB());
glBindBuffer(GL_ARRAY_BUFFER, particles->particle_buffers[0]);
float *data = (float *)glMapBufferRange(GL_ARRAY_BUFFER, 0, particles->amount * 16 * 6, GL_MAP_READ_BIT);
- Rect3 aabb;
+ AABB aabb;
Transform inv = particles->emission_transform.affine_inverse();
@@ -5442,7 +5460,7 @@ Rect3 RasterizerStorageGLES3::particles_get_current_aabb(RID p_particles) {
float longest_axis = 0;
for (int i = 0; i < particles->draw_passes.size(); i++) {
if (particles->draw_passes[i].is_valid()) {
- Rect3 maabb = mesh_get_aabb(particles->draw_passes[i], RID());
+ AABB maabb = mesh_get_aabb(particles->draw_passes[i], RID());
longest_axis = MAX(maabb.get_longest_axis_size(), longest_axis);
}
}
@@ -5452,10 +5470,10 @@ Rect3 RasterizerStorageGLES3::particles_get_current_aabb(RID p_particles) {
return aabb;
}
-Rect3 RasterizerStorageGLES3::particles_get_aabb(RID p_particles) const {
+AABB RasterizerStorageGLES3::particles_get_aabb(RID p_particles) const {
const Particles *particles = particles_owner.getornull(p_particles);
- ERR_FAIL_COND_V(!particles, Rect3());
+ ERR_FAIL_COND_V(!particles, AABB());
return particles->custom_aabb;
}
@@ -7010,14 +7028,22 @@ void RasterizerStorageGLES3::initialize() {
glBindBuffer(GL_ARRAY_BUFFER, resources.quadie);
{
const float qv[16] = {
- -1, -1,
- 0, 0,
- -1, 1,
- 0, 1,
- 1, 1,
- 1, 1,
- 1, -1,
- 1, 0,
+ -1,
+ -1,
+ 0,
+ 0,
+ -1,
+ 1,
+ 0,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ -1,
+ 1,
+ 0,
};
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 16, qv, GL_STATIC_DRAW);
diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h
index 6abc22b643..8aa8235b42 100644
--- a/drivers/gles3/rasterizer_storage_gles3.h
+++ b/drivers/gles3/rasterizer_storage_gles3.h
@@ -592,7 +592,7 @@ public:
GLuint instancing_array_wireframe_id;
int index_wireframe_len;
- Vector<Rect3> skeleton_bone_aabb;
+ Vector<AABB> skeleton_bone_aabb;
Vector<bool> skeleton_bone_used;
//bool packed;
@@ -604,7 +604,7 @@ public:
Vector<BlendShape> blend_shapes;
- Rect3 aabb;
+ AABB aabb;
int array_len;
int index_array_len;
@@ -659,7 +659,7 @@ public:
Vector<Surface *> surfaces;
int blend_shape_count;
VS::BlendShapeMode blend_shape_mode;
- Rect3 custom_aabb;
+ AABB custom_aabb;
mutable uint64_t last_pass;
SelfList<MultiMesh>::List multimeshes;
@@ -684,7 +684,7 @@ public:
virtual RID mesh_create();
- virtual void mesh_add_surface(RID p_mesh, uint32_t p_format, VS::PrimitiveType p_primitive, const PoolVector<uint8_t> &p_array, int p_vertex_count, const PoolVector<uint8_t> &p_index_array, int p_index_count, const Rect3 &p_aabb, const Vector<PoolVector<uint8_t> > &p_blend_shapes = Vector<PoolVector<uint8_t> >(), const Vector<Rect3> &p_bone_aabbs = Vector<Rect3>());
+ virtual void mesh_add_surface(RID p_mesh, uint32_t p_format, VS::PrimitiveType p_primitive, const PoolVector<uint8_t> &p_array, int p_vertex_count, const PoolVector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<PoolVector<uint8_t> > &p_blend_shapes = Vector<PoolVector<uint8_t> >(), const Vector<AABB> &p_bone_aabbs = Vector<AABB>());
virtual void mesh_set_blend_shape_count(RID p_mesh, int p_amount);
virtual int mesh_get_blend_shape_count(RID p_mesh) const;
@@ -692,6 +692,8 @@ public:
virtual void mesh_set_blend_shape_mode(RID p_mesh, VS::BlendShapeMode p_mode);
virtual VS::BlendShapeMode mesh_get_blend_shape_mode(RID p_mesh) const;
+ virtual void mesh_surface_update_region(RID p_mesh, int p_surface, int p_offset, const PoolVector<uint8_t> &p_data);
+
virtual void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material);
virtual RID mesh_surface_get_material(RID p_mesh, int p_surface) const;
@@ -704,17 +706,17 @@ public:
virtual uint32_t mesh_surface_get_format(RID p_mesh, int p_surface) const;
virtual VS::PrimitiveType mesh_surface_get_primitive_type(RID p_mesh, int p_surface) const;
- virtual Rect3 mesh_surface_get_aabb(RID p_mesh, int p_surface) const;
+ virtual AABB mesh_surface_get_aabb(RID p_mesh, int p_surface) const;
virtual Vector<PoolVector<uint8_t> > mesh_surface_get_blend_shapes(RID p_mesh, int p_surface) const;
- virtual Vector<Rect3> mesh_surface_get_skeleton_aabb(RID p_mesh, int p_surface) const;
+ virtual Vector<AABB> mesh_surface_get_skeleton_aabb(RID p_mesh, int p_surface) const;
virtual void mesh_remove_surface(RID p_mesh, int p_surface);
virtual int mesh_get_surface_count(RID p_mesh) const;
- virtual void mesh_set_custom_aabb(RID p_mesh, const Rect3 &p_aabb);
- virtual Rect3 mesh_get_custom_aabb(RID p_mesh) const;
+ virtual void mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb);
+ virtual AABB mesh_get_custom_aabb(RID p_mesh) const;
- virtual Rect3 mesh_get_aabb(RID p_mesh, RID p_skeleton) const;
+ virtual AABB mesh_get_aabb(RID p_mesh, RID p_skeleton) const;
virtual void mesh_clear(RID p_mesh);
void mesh_render_blend_shapes(Surface *s, float *p_weights);
@@ -727,7 +729,7 @@ public:
VS::MultimeshTransformFormat transform_format;
VS::MultimeshColorFormat color_format;
Vector<float> data;
- Rect3 aabb;
+ AABB aabb;
SelfList<MultiMesh> update_list;
SelfList<MultiMesh> mesh_list;
GLuint buffer;
@@ -778,7 +780,7 @@ public:
virtual void multimesh_set_visible_instances(RID p_multimesh, int p_visible);
virtual int multimesh_get_visible_instances(RID p_multimesh) const;
- virtual Rect3 multimesh_get_aabb(RID p_multimesh) const;
+ virtual AABB multimesh_get_aabb(RID p_multimesh) const;
/* IMMEDIATE API */
@@ -799,7 +801,7 @@ public:
List<Chunk> chunks;
bool building;
int mask;
- Rect3 aabb;
+ AABB aabb;
Immediate() {
type = GEOMETRY_IMMEDIATE;
@@ -828,7 +830,7 @@ public:
virtual void immediate_clear(RID p_immediate);
virtual void immediate_set_material(RID p_immediate, RID p_material);
virtual RID immediate_get_material(RID p_immediate) const;
- virtual Rect3 immediate_get_aabb(RID p_immediate) const;
+ virtual AABB immediate_get_aabb(RID p_immediate) const;
/* SKELETON API */
@@ -916,7 +918,7 @@ public:
virtual float light_get_param(RID p_light, VS::LightParam p_param);
virtual Color light_get_color(RID p_light);
- virtual Rect3 light_get_aabb(RID p_light) const;
+ virtual AABB light_get_aabb(RID p_light) const;
virtual uint64_t light_get_version(RID p_light) const;
/* PROBE API */
@@ -954,7 +956,7 @@ public:
virtual void reflection_probe_set_enable_shadows(RID p_probe, bool p_enable);
virtual void reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers);
- virtual Rect3 reflection_probe_get_aabb(RID p_probe) const;
+ virtual AABB reflection_probe_get_aabb(RID p_probe) const;
virtual VS::ReflectionProbeUpdateMode reflection_probe_get_update_mode(RID p_probe) const;
virtual uint32_t reflection_probe_get_cull_mask(RID p_probe) const;
@@ -967,7 +969,7 @@ public:
struct GIProbe : public Instantiable {
- Rect3 bounds;
+ AABB bounds;
Transform to_cell;
float cell_size;
@@ -988,8 +990,8 @@ public:
virtual RID gi_probe_create();
- virtual void gi_probe_set_bounds(RID p_probe, const Rect3 &p_bounds);
- virtual Rect3 gi_probe_get_bounds(RID p_probe) const;
+ virtual void gi_probe_set_bounds(RID p_probe, const AABB &p_bounds);
+ virtual AABB gi_probe_get_bounds(RID p_probe) const;
virtual void gi_probe_set_cell_size(RID p_probe, float p_size);
virtual float gi_probe_get_cell_size(RID p_probe) const;
@@ -1056,7 +1058,7 @@ public:
float explosiveness;
float randomness;
bool restart_request;
- Rect3 custom_aabb;
+ AABB custom_aabb;
bool use_local_coords;
RID process_material;
@@ -1111,7 +1113,7 @@ public:
restart_request = false;
- custom_aabb = Rect3(Vector3(-4, -4, -4), Vector3(8, 8, 8));
+ custom_aabb = AABB(Vector3(-4, -4, -4), Vector3(8, 8, 8));
draw_order = VS::PARTICLES_DRAW_ORDER_INDEX;
particle_buffers[0] = 0;
@@ -1153,7 +1155,7 @@ public:
virtual void particles_set_pre_process_time(RID p_particles, float p_time);
virtual void particles_set_explosiveness_ratio(RID p_particles, float p_ratio);
virtual void particles_set_randomness_ratio(RID p_particles, float p_ratio);
- virtual void particles_set_custom_aabb(RID p_particles, const Rect3 &p_aabb);
+ virtual void particles_set_custom_aabb(RID p_particles, const AABB &p_aabb);
virtual void particles_set_speed_scale(RID p_particles, float p_scale);
virtual void particles_set_use_local_coordinates(RID p_particles, bool p_enable);
virtual void particles_set_process_material(RID p_particles, RID p_material);
@@ -1167,8 +1169,8 @@ public:
virtual void particles_set_draw_pass_mesh(RID p_particles, int p_pass, RID p_mesh);
virtual void particles_request_process(RID p_particles);
- virtual Rect3 particles_get_current_aabb(RID p_particles);
- virtual Rect3 particles_get_aabb(RID p_particles) const;
+ virtual AABB particles_get_current_aabb(RID p_particles);
+ virtual AABB particles_get_aabb(RID p_particles) const;
virtual void _particles_update_histories(Particles *particles);
diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp
index 91159e3381..325df8e4f1 100644
--- a/drivers/gles3/shader_compiler_gles3.cpp
+++ b/drivers/gles3/shader_compiler_gles3.cpp
@@ -741,6 +741,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_CANVAS_ITEM].usage_defines["NORMAL"] = "#define NORMAL_USED\n";
actions[VS::SHADER_CANVAS_ITEM].usage_defines["NORMALMAP"] = "#define NORMALMAP_USED\n";
actions[VS::SHADER_CANVAS_ITEM].usage_defines["SHADOW_COLOR"] = "#define SHADOW_COLOR_USED\n";
+ actions[VS::SHADER_CANVAS_ITEM].usage_defines["LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n";
actions[VS::SHADER_CANVAS_ITEM].render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n";
@@ -766,10 +767,10 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
//builtins
actions[VS::SHADER_SPATIAL].renames["TIME"] = "time";
- //actions[VS::SHADER_SPATIAL].renames["VIEWPORT_SIZE"]=ShaderLanguage::TYPE_VEC2;
+ actions[VS::SHADER_SPATIAL].renames["VIEWPORT_SIZE"] = "viewport_size";
actions[VS::SHADER_SPATIAL].renames["FRAGCOORD"] = "gl_FragCoord";
- actions[VS::SHADER_SPATIAL].renames["FRONT_FACING"] = "gl_FrotFacing";
+ actions[VS::SHADER_SPATIAL].renames["FRONT_FACING"] = "gl_FrontFacing";
actions[VS::SHADER_SPATIAL].renames["NORMALMAP"] = "normalmap";
actions[VS::SHADER_SPATIAL].renames["NORMALMAP_DEPTH"] = "normaldepth";
actions[VS::SHADER_SPATIAL].renames["ALBEDO"] = "albedo";
@@ -828,6 +829,9 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_SPATIAL].usage_defines["SCREEN_TEXTURE"] = "#define SCREEN_TEXTURE_USED\n";
actions[VS::SHADER_SPATIAL].usage_defines["SCREEN_UV"] = "#define SCREEN_UV_USED\n";
+ actions[VS::SHADER_SPATIAL].usage_defines["DIFFUSE_LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n";
+ actions[VS::SHADER_SPATIAL].usage_defines["SPECULAR_LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n";
+
actions[VS::SHADER_SPATIAL].renames["SSS_STRENGTH"] = "sss_strength";
actions[VS::SHADER_SPATIAL].render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n";
@@ -838,6 +842,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_lambert_wrap"] = "#define DIFFUSE_LAMBERT_WRAP\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_toon"] = "#define DIFFUSE_TOON\n";
+ actions[VS::SHADER_SPATIAL].render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_SCHLICK_GGX\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["specular_blinn"] = "#define SPECULAR_BLINN\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["specular_phong"] = "#define SPECULAR_PHONG\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["specular_toon"] = "#define SPECULAR_TOON\n";
diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl
index 731d6968ce..4bbb18ce42 100644
--- a/drivers/gles3/shaders/canvas.glsl
+++ b/drivers/gles3/shaders/canvas.glsl
@@ -381,8 +381,7 @@ void main() {
if (clip_rect_uv) {
- vec2 half_texpixel = color_texpixel_size * 0.5;
- uv = clamp(uv,src_rect.xy+half_texpixel,src_rect.xy+abs(src_rect.zw)-color_texpixel_size);
+ uv = clamp(uv,src_rect.xy,src_rect.xy+abs(src_rect.zw));
}
#endif
diff --git a/drivers/gles3/shaders/copy.glsl b/drivers/gles3/shaders/copy.glsl
index d33193ee50..743fe122d1 100644
--- a/drivers/gles3/shaders/copy.glsl
+++ b/drivers/gles3/shaders/copy.glsl
@@ -27,6 +27,8 @@ void main() {
#if defined(USE_CUBEMAP) || defined(USE_PANORAMA)
cube_interp = cube_in;
+#elif defined(USE_ASYM_PANO)
+ uv_interp = vertex_attrib.xy;
#else
uv_interp = uv_in;
#ifdef V_FLIP
@@ -59,6 +61,11 @@ in vec3 cube_interp;
in vec2 uv_interp;
#endif
+#ifdef USE_ASYM_PANO
+uniform highp mat4 pano_transform;
+uniform highp vec4 asym_proj;
+#endif
+
#ifdef USE_CUBEMAP
uniform samplerCube source_cube; //texunit:0
#else
@@ -70,7 +77,7 @@ uniform sampler2D source; //texunit:0
uniform float multiplier;
#endif
-#ifdef USE_PANORAMA
+#if defined(USE_PANORAMA) || defined(USE_ASYM_PANO)
vec4 texturePanorama(vec3 normal,sampler2D pano ) {
@@ -122,6 +129,21 @@ void main() {
vec4 color = texturePanorama( normalize(cube_interp), source );
+#elif defined(USE_ASYM_PANO)
+
+ // When an assymetrical projection matrix is used (applicable for stereoscopic rendering i.e. VR) we need to do this calculation per fragment to get a perspective correct result.
+ // Note that we're ignoring the x-offset for IPD, with Z sufficiently in the distance it becomes neglectible, as a result we could probably just set cube_normal.z to -1.
+ // The Matrix[2][0] (= asym_proj.x) and Matrix[2][1] (= asym_proj.z) values are what provide the right shift in the image.
+
+ vec3 cube_normal;
+ cube_normal.z = -1000000.0;
+ cube_normal.x = (cube_normal.z * (-uv_interp.x - asym_proj.x)) / asym_proj.y;
+ cube_normal.y = (cube_normal.z * (-uv_interp.y - asym_proj.z)) / asym_proj.a;
+ cube_normal = mat3(pano_transform) * cube_normal;
+ cube_normal.z = -cube_normal.z;
+
+ vec4 color = texturePanorama( normalize(cube_normal.xyz), source );
+
#elif defined(USE_CUBEMAP)
vec4 color = texture( source_cube, normalize(cube_interp) );
diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index 341a5bf2c7..9880663143 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -80,6 +80,7 @@ layout(std140) uniform SceneData { //ubo:0
highp float shadow_dual_paraboloid_render_zfar;
highp float shadow_dual_paraboloid_render_side;
+ highp vec2 viewport_size;
highp vec2 screen_pixel_size;
highp vec2 shadow_atlas_pixel_size;
highp vec2 directional_shadow_pixel_size;
@@ -566,6 +567,7 @@ in vec3 normal_interp;
uniform bool no_ambient_light;
+
#ifdef USE_RADIANCE_MAP
@@ -663,6 +665,7 @@ layout(std140) uniform SceneData {
highp float shadow_dual_paraboloid_render_zfar;
highp float shadow_dual_paraboloid_render_side;
+ highp vec2 viewport_size;
highp vec2 screen_pixel_size;
highp vec2 shadow_atlas_pixel_size;
highp vec2 directional_shadow_pixel_size;
@@ -865,11 +868,57 @@ float contact_shadow_compute(vec3 pos, vec3 dir, float max_distance) {
#endif
-// GGX Specular
-// Source: http://www.filmicworlds.com/images/ggx-opt/optimized-ggx.hlsl
-float G1V(float dotNV, float k)
-{
- return 1.0 / (dotNV * (1.0 - k) + k);
+
+// This returns the G_GGX function divided by 2 cos_theta_m, where in practice cos_theta_m is either N.L or N.V.
+// We're dividing this factor off because the overall term we'll end up looks like
+// (see, for example, the first unnumbered equation in B. Burley, "Physically Based Shading at Disney", SIGGRAPH 2012):
+//
+// F(L.V) D(N.H) G(N.L) G(N.V) / (4 N.L N.V)
+//
+// We're basically regouping this as
+//
+// F(L.V) D(N.H) [G(N.L)/(2 N.L)] [G(N.V) / (2 N.V)]
+//
+// and thus, this function implements the [G(N.m)/(2 N.m)] part with m = L or V.
+//
+// The contents of the D and G (G1) functions (GGX) are taken from
+// E. Heitz, "Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs", J. Comp. Graph. Tech. 3 (2) (2014).
+// Eqns 71-72 and 85-86 (see also Eqns 43 and 80).
+
+float G_GGX_2cos(float cos_theta_m, float alpha) {
+ // Schlick's approximation
+ // C. Schlick, "An Inexpensive BRDF Model for Physically-based Rendering", Computer Graphics Forum. 13 (3): 233 (1994)
+ // Eq. (19), although see Heitz (2014) the about the problems with his derivation.
+ // It nevertheless approximates GGX well with k = alpha/2.
+ float k = 0.5*alpha;
+ return 0.5 / (cos_theta_m * (1.0 - k) + k);
+
+ // float cos2 = cos_theta_m*cos_theta_m;
+ // float sin2 = (1.0-cos2);
+ // return 1.0 /( cos_theta_m + sqrt(cos2 + alpha*alpha*sin2) );
+}
+
+float D_GGX(float cos_theta_m, float alpha) {
+ float alpha2 = alpha*alpha;
+ float d = 1.0 + (alpha2-1.0)*cos_theta_m*cos_theta_m;
+ return alpha2/(M_PI * d * d);
+}
+
+float G_GGX_anisotropic_2cos(float cos_theta_m, float alpha_x, float alpha_y, float cos_phi, float sin_phi) {
+ float cos2 = cos_theta_m * cos_theta_m;
+ float sin2 = (1.0-cos2);
+ float s_x = alpha_x * cos_phi;
+ float s_y = alpha_y * sin_phi;
+ return 1.0 / (cos_theta_m + sqrt(cos2 + (s_x*s_x + s_y*s_y)*sin2 ));
+}
+
+float D_GGX_anisotropic(float cos_theta_m, float alpha_x, float alpha_y, float cos_phi, float sin_phi) {
+ float cos2 = cos_theta_m * cos_theta_m;
+ float sin2 = (1.0-cos2);
+ float r_x = cos_phi/alpha_x;
+ float r_y = sin_phi/alpha_y;
+ float d = cos2 + sin2*(r_x * r_x + r_y * r_y);
+ return 1.0 / (M_PI * alpha_x * alpha_y * d * d );
}
@@ -894,7 +943,7 @@ vec3 metallic_to_specular_color(float metallic, float specular, vec3 albedo) {
return mix(vec3(dielectric), albedo, metallic); // TODO: reference?
}
-void light_compute(vec3 N, vec3 L, vec3 V, vec3 B, vec3 T, vec3 light_color, vec3 attenuation, vec3 diffuse_color, vec3 transmission, float specular_blob_intensity, float roughness, float rim, float rim_tint, float clearcoat, float clearcoat_gloss, float anisotropy, inout vec3 diffuse_light, inout vec3 specular_light) {
+void light_compute(vec3 N, vec3 L, vec3 V, vec3 B, vec3 T, vec3 light_color, vec3 attenuation, vec3 diffuse_color, vec3 transmission, float specular_blob_intensity, float roughness, float metallic, float rim, float rim_tint, float clearcoat, float clearcoat_gloss, float anisotropy, inout vec3 diffuse_light, inout vec3 specular_light) {
#if defined(USE_LIGHT_SHADER_CODE)
//light is written by the light shader
@@ -913,80 +962,82 @@ LIGHT_SHADER_CODE
float NdotV = dot(N, V);
float cNdotV = max(NdotV, 0.0);
+ if (metallic < 1.0) {
#if defined(DIFFUSE_OREN_NAYAR)
- vec3 diffuse_brdf_NL;
+ vec3 diffuse_brdf_NL;
#else
- float diffuse_brdf_NL; // BRDF times N.L for calculating diffuse radiance
+ float diffuse_brdf_NL; // BRDF times N.L for calculating diffuse radiance
#endif
#if defined(DIFFUSE_LAMBERT_WRAP)
- //energy conserving lambert wrap shader
- diffuse_brdf_NL = max(0.0,(NdotL + roughness) / ((1.0 + roughness) * (1.0 + roughness)));
+ //energy conserving lambert wrap shader
+ diffuse_brdf_NL = max(0.0,(NdotL + roughness) / ((1.0 + roughness) * (1.0 + roughness)));
#elif defined(DIFFUSE_OREN_NAYAR)
- {
- // see http://mimosa-pudica.net/improved-oren-nayar.html
- float LdotV = dot(L, V);
+ {
+ // see http://mimosa-pudica.net/improved-oren-nayar.html
+ float LdotV = dot(L, V);
- float s = LdotV - NdotL * NdotV;
- float t = mix(1.0, max(NdotL, NdotV), step(0.0, s));
+ float s = LdotV - NdotL * NdotV;
+ float t = mix(1.0, max(NdotL, NdotV), step(0.0, s));
- float sigma2 = roughness * roughness; // TODO: this needs checking
- vec3 A = 1.0 + sigma2 * (- 0.5 / (sigma2 + 0.33) + 0.17*diffuse_color / (sigma2 + 0.13) );
- float B = 0.45 * sigma2 / (sigma2 + 0.09);
+ float sigma2 = roughness * roughness; // TODO: this needs checking
+ vec3 A = 1.0 + sigma2 * (- 0.5 / (sigma2 + 0.33) + 0.17*diffuse_color / (sigma2 + 0.13) );
+ float B = 0.45 * sigma2 / (sigma2 + 0.09);
- diffuse_brdf_NL = cNdotL * (A + vec3(B) * s / t) * (1.0 / M_PI);
- }
+ diffuse_brdf_NL = cNdotL * (A + vec3(B) * s / t) * (1.0 / M_PI);
+ }
#elif defined(DIFFUSE_TOON)
- diffuse_brdf_NL = smoothstep(-roughness,max(roughness,0.01),NdotL);
+ diffuse_brdf_NL = smoothstep(-roughness,max(roughness,0.01),NdotL);
#elif defined(DIFFUSE_BURLEY)
- {
+ {
- vec3 H = normalize(V + L);
- float cLdotH = max(0.0,dot(L, H));
+ 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);
- diffuse_brdf_NL = (1.0 / M_PI) * FdV * FdL * cNdotL;
-/*
- float energyBias = mix(roughness, 0.0, 0.5);
- float energyFactor = mix(roughness, 1.0, 1.0 / 1.51);
- float fd90 = energyBias + 2.0 * VoH * VoH * roughness;
- float f0 = 1.0;
- float lightScatter = f0 + (fd90 - f0) * pow(1.0 - cNdotL, 5.0);
- float viewScatter = f0 + (fd90 - f0) * pow(1.0 - cNdotV, 5.0);
-
- diffuse_brdf_NL = lightScatter * viewScatter * energyFactor;*/
- }
+ 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);
+ diffuse_brdf_NL = (1.0 / M_PI) * FdV * FdL * cNdotL;
+ /*
+ float energyBias = mix(roughness, 0.0, 0.5);
+ float energyFactor = mix(roughness, 1.0, 1.0 / 1.51);
+ float fd90 = energyBias + 2.0 * VoH * VoH * roughness;
+ float f0 = 1.0;
+ float lightScatter = f0 + (fd90 - f0) * pow(1.0 - cNdotL, 5.0);
+ float viewScatter = f0 + (fd90 - f0) * pow(1.0 - cNdotV, 5.0);
+
+ diffuse_brdf_NL = lightScatter * viewScatter * energyFactor;*/
+ }
#else
- //lambert
- diffuse_brdf_NL = cNdotL * (1.0 / M_PI);
+ //lambert
+ diffuse_brdf_NL = cNdotL * (1.0 / M_PI);
#endif
#if defined(TRANSMISSION_USED)
- diffuse_light += light_color * diffuse_color * mix(vec3(diffuse_brdf_NL), vec3(M_PI), transmission) * attenuation;
+ diffuse_light += light_color * diffuse_color * mix(vec3(diffuse_brdf_NL), vec3(M_PI), transmission) * attenuation;
#else
- diffuse_light += light_color * diffuse_color * diffuse_brdf_NL * attenuation;
+ diffuse_light += light_color * diffuse_color * diffuse_brdf_NL * attenuation;
#endif
#if defined(LIGHT_USE_RIM)
- float rim_light = pow(1.0-cNdotV, (1.0-roughness)*16.0);
- diffuse_light += rim_light * rim * mix(vec3(1.0),diffuse_color,rim_tint) * light_color;
+ float rim_light = pow(1.0-cNdotV, (1.0-roughness)*16.0);
+ diffuse_light += rim_light * rim * mix(vec3(1.0),diffuse_color,rim_tint) * light_color;
#endif
+ }
- if (roughness > 0.0) {
+ if (roughness > 0.0) { // FIXME: roughness == 0 should not disable specular light entirely
// D
@@ -1019,14 +1070,13 @@ LIGHT_SHADER_CODE
#elif defined(SPECULAR_SCHLICK_GGX)
// shlick+ggx as default
- float alpha = roughness * roughness;
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)
+# if defined(LIGHT_USE_ANISOTROPY)
float aspect = sqrt(1.0-anisotropy*0.9);
float rx = roughness/aspect;
@@ -1035,44 +1085,43 @@ LIGHT_SHADER_CODE
float ay = ry*ry;
float XdotH = dot( T, H );
float YdotH = dot( B, H );
- float denom = XdotH*XdotH / (ax*ax) + YdotH*YdotH / (ay*ay) + cNdotH*cNdotH;
- float D = 1.0 / ( M_PI * ax*ay * denom*denom );
+ float D = D_GGX_anisotropic(cNdotH, ax, ay, XdotH, YdotH);
+ float G = G_GGX_anisotropic_2cos(cNdotL, ax, ay, XdotH, YdotH) * G_GGX_anisotropic_2cos(cNdotV, ax, ay, XdotH, YdotH);
-#else
- float alphaSqr = alpha * alpha;
- float denom = cNdotH * cNdotH * (alphaSqr - 1.0) + 1.0;
- float D = alphaSqr / (M_PI * denom * denom);
-#endif
+# else
+ float alpha = roughness * roughness;
+ float D = D_GGX(cNdotH, alpha);
+ float G = G_GGX_2cos(cNdotL, alpha) * G_GGX_2cos(cNdotV, alpha);
+# endif
// F
float F0 = 1.0; // FIXME
float cLdotH5 = SchlickFresnel(cLdotH);
float F = mix(cLdotH5, 1.0, F0);
- // V
- float k = alpha / 2.0f;
- float vis = G1V(cNdotL, k) * G1V(cNdotV, k);
+ float specular_brdf_NL = cNdotL * D * F * G;
- float speci = cNdotL * D * F * vis;
-
- specular_light += speci * light_color * specular_blob_intensity * attenuation;
+ specular_light += specular_brdf_NL * light_color * specular_blob_intensity * attenuation;
#endif
#if defined(LIGHT_USE_CLEARCOAT)
-
+ if (clearcoat_gloss > 0.0) {
# if !defined(SPECULAR_SCHLICK_GGX) && !defined(SPECULAR_BLINN)
- vec3 H = normalize(V + L);
+ 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 cNdotH = max(dot(N,H), 0.0);
+ float cLdotH = max(dot(L,H), 0.0);
+ float cLdotH5 = SchlickFresnel(cLdotH);
#endif
- float Dr = GTR1(cNdotH, mix(.1, .001, clearcoat_gloss));
- float Fr = mix(.04, 1.0, cLdotH5);
- float Gr = G1V(cNdotL, .25) * G1V(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);
- specular_light += .25*clearcoat*Gr*Fr*Dr;
+ float specular_brdf_NL = 0.25 * clearcoat * Gr * Fr * Dr * cNdotL;
+
+ specular_light += specular_brdf_NL * light_color * specular_blob_intensity * attenuation;
+ }
#endif
}
@@ -1154,7 +1203,7 @@ vec3 light_transmittance(float translucency,vec3 light_vec, vec3 normal, vec3 po
}
#endif
-void light_process_omni(int idx, vec3 vertex, vec3 eye_vec,vec3 normal,vec3 binormal, vec3 tangent, vec3 albedo, vec3 transmission, float roughness, float rim, float rim_tint, float clearcoat, float clearcoat_gloss, float anisotropy, float p_blob_intensity, inout vec3 diffuse_light, inout vec3 specular_light) {
+void light_process_omni(int idx, vec3 vertex, vec3 eye_vec,vec3 normal,vec3 binormal, vec3 tangent, vec3 albedo, vec3 transmission, float roughness, float metallic, float rim, float rim_tint, float clearcoat, float clearcoat_gloss, float anisotropy, float p_blob_intensity, inout vec3 diffuse_light, inout vec3 specular_light) {
vec3 light_rel_vec = omni_lights[idx].light_pos_inv_radius.xyz-vertex;
float light_length = length( light_rel_vec );
@@ -1208,11 +1257,11 @@ void light_process_omni(int idx, vec3 vertex, vec3 eye_vec,vec3 normal,vec3 bino
light_attenuation*=mix(omni_lights[idx].shadow_color_contact.rgb,vec3(1.0),shadow);
}
- light_compute(normal,normalize(light_rel_vec),eye_vec,binormal,tangent,omni_lights[idx].light_color_energy.rgb,light_attenuation,albedo,transmission,omni_lights[idx].light_params.z*p_blob_intensity,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
+ light_compute(normal,normalize(light_rel_vec),eye_vec,binormal,tangent,omni_lights[idx].light_color_energy.rgb,light_attenuation,albedo,transmission,omni_lights[idx].light_params.z*p_blob_intensity,roughness,metallic,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
}
-void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 binormal, vec3 tangent,vec3 albedo, vec3 transmission,float roughness, float rim,float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,float p_blob_intensity, inout vec3 diffuse_light, inout vec3 specular_light) {
+void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 binormal, vec3 tangent,vec3 albedo, vec3 transmission,float roughness, float metallic, float rim, float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,float p_blob_intensity, inout vec3 diffuse_light, inout vec3 specular_light) {
vec3 light_rel_vec = spot_lights[idx].light_pos_inv_radius.xyz-vertex;
float light_length = length( light_rel_vec );
@@ -1242,7 +1291,7 @@ void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 bi
light_attenuation*=mix(spot_lights[idx].shadow_color_contact.rgb,vec3(1.0),shadow);
}
- light_compute(normal,normalize(light_rel_vec),eye_vec,binormal,tangent,spot_lights[idx].light_color_energy.rgb,light_attenuation,albedo,transmission,spot_lights[idx].light_params.z*p_blob_intensity,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
+ light_compute(normal,normalize(light_rel_vec),eye_vec,binormal,tangent,spot_lights[idx].light_color_energy.rgb,light_attenuation,albedo,transmission,spot_lights[idx].light_params.z*p_blob_intensity,roughness,metallic,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
}
@@ -1875,7 +1924,7 @@ FRAGMENT_SHADER_CODE
specular_light*=mix(vec3(1.0),light_attenuation,specular_light_interp.a);
#else
- light_compute(normal,-light_direction_attenuation.xyz,eye_vec,binormal,tangent,light_color_energy.rgb,light_attenuation,albedo,transmission,light_params.z*specular_blob_intensity,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
+ light_compute(normal,-light_direction_attenuation.xyz,eye_vec,binormal,tangent,light_color_energy.rgb,light_attenuation,albedo,transmission,light_params.z*specular_blob_intensity,roughness,metallic,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
#endif
@@ -1913,11 +1962,11 @@ FRAGMENT_SHADER_CODE
#else
for(int i=0;i<omni_light_count;i++) {
- light_process_omni(omni_light_indices[i],vertex,eye_vec,normal,binormal,tangent,albedo,transmission,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,specular_blob_intensity,diffuse_light,specular_light);
+ light_process_omni(omni_light_indices[i],vertex,eye_vec,normal,binormal,tangent,albedo,transmission,roughness,metallic,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,specular_blob_intensity,diffuse_light,specular_light);
}
for(int i=0;i<spot_light_count;i++) {
- light_process_spot(spot_light_indices[i],vertex,eye_vec,normal,binormal,tangent,albedo,transmission,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,specular_blob_intensity,diffuse_light,specular_light);
+ light_process_spot(spot_light_indices[i],vertex,eye_vec,normal,binormal,tangent,albedo,transmission,roughness,metallic,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,specular_blob_intensity,diffuse_light,specular_light);
}
#endif //USE_VERTEX_LIGHTING
@@ -1944,7 +1993,7 @@ FRAGMENT_SHADER_CODE
//energy conservation
- diffuse_light *= 1.0-metallic; // TODO: avoid diffuse and ambient light calculations when metallic == 1
+ diffuse_light *= 1.0-metallic; // TODO: avoid all diffuse and ambient light calculations when metallic == 1 up to this point
ambient_light *= 1.0-metallic;
@@ -2063,5 +2112,3 @@ FRAGMENT_SHADER_CODE
}
-
-
diff --git a/drivers/gles3/shaders/ssao.glsl b/drivers/gles3/shaders/ssao.glsl
index c668e63745..219f0957e0 100644
--- a/drivers/gles3/shaders/ssao.glsl
+++ b/drivers/gles3/shaders/ssao.glsl
@@ -13,8 +13,24 @@ void main() {
#define TWO_PI 6.283185307179586476925286766559
+#ifdef SSAO_QUALITY_HIGH
+
+#define NUM_SAMPLES (80)
+
+#endif
+
+#ifdef SSAO_QUALITY_LOW
+
#define NUM_SAMPLES (15)
+#endif
+
+#if !defined(SSAO_QUALITY_LOW) && !defined(SSAO_QUALITY_HIGH)
+
+#define NUM_SAMPLES (40)
+
+#endif
+
// If using depth mip levels, the log of the maximum pixel offset before we need to switch to a lower
// miplevel to maintain reasonable spatial locality in the cache
// If this number is too small (< 3), too many taps will land in the same pixel, and we'll get bad variance that manifests as flashing.
@@ -212,12 +228,12 @@ void main() {
//visibility=-C.z/camera_z_far;
//return;
-
- //vec3 n_C = texelFetch(source_normal,ssC,0).rgb * 2.0 - 1.0;
-
+#if 0
+ vec3 n_C = texelFetch(source_normal,ssC,0).rgb * 2.0 - 1.0;
+#else
vec3 n_C = reconstructCSFaceNormal(C);
n_C = -n_C;
-
+#endif
// Hash function used in the HPG12 AlchemyAO paper
float randomPatternRotationAngle = mod(float((3 * ssC.x ^ ssC.y + ssC.x * ssC.y) * 10), TWO_PI);
diff --git a/drivers/gles3/shaders/ssao_blur.glsl b/drivers/gles3/shaders/ssao_blur.glsl
index c7c978dc37..472dc21acf 100644
--- a/drivers/gles3/shaders/ssao_blur.glsl
+++ b/drivers/gles3/shaders/ssao_blur.glsl
@@ -15,6 +15,7 @@ void main() {
uniform sampler2D source_ssao; //texunit:0
uniform sampler2D source_depth; //texunit:1
+uniform sampler2D source_normal; //texunit:3
layout(location = 0) out float visibility;
@@ -24,7 +25,7 @@ layout(location = 0) out float visibility;
// Tunable Parameters:
/** Increase to make depth edges crisper. Decrease to reduce flicker. */
-#define EDGE_SHARPNESS (4.0)
+uniform float edge_sharpness;
/** Step in 2-pixel intervals since we already blurred against neighbors in the
first AO pass. This constant can be increased while R decreases to improve
@@ -34,7 +35,8 @@ layout(location = 0) out float visibility;
unobjectionable after shading was applied but eliminated most temporal incoherence
from using small numbers of sample taps.
*/
-#define SCALE (3)
+
+uniform int filter_scale;
/** Filter radius in pixels. This will be multiplied by SCALE. */
#define R (4)
@@ -63,13 +65,14 @@ void main() {
ivec2 ssC = ivec2(gl_FragCoord.xy);
float depth = texelFetch(source_depth, ssC, 0).r;
+ //vec3 normal = texelFetch(source_normal,ssC,0).rgb * 2.0 - 1.0;
depth = depth * 2.0 - 1.0;
depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth * (camera_z_far - camera_z_near));
float depth_divide = 1.0 / camera_z_far;
- depth*=depth_divide;
+// depth*=depth_divide;
/*
if (depth > camera_z_far*0.999) {
@@ -92,20 +95,23 @@ void main() {
// so the IF statement has no runtime cost
if (r != 0) {
- ivec2 ppos = ssC + axis * (r * SCALE);
+ ivec2 ppos = ssC + axis * (r * filter_scale);
float value = texelFetch(source_ssao, clamp(ppos,ivec2(0),clamp_limit), 0).r;
- float temp_depth = texelFetch(source_depth, clamp(ssC,ivec2(0),clamp_limit), 0).r;
+ ivec2 rpos = clamp(ppos,ivec2(0),clamp_limit);
+ float temp_depth = texelFetch(source_depth, rpos, 0).r;
+ //vec3 temp_normal = texelFetch(source_normal, rpos, 0).rgb * 2.0 - 1.0;
temp_depth = temp_depth * 2.0 - 1.0;
temp_depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - temp_depth * (camera_z_far - camera_z_near));
- temp_depth *= depth_divide;
+// temp_depth *= depth_divide;
// spatial domain: offset gaussian tap
float weight = 0.3 + gaussian[abs(r)];
+ //weight *= max(0.0,dot(temp_normal,normal));
// range domain (the "bilateral" weight). As depth difference increases, decrease weight.
weight *= max(0.0, 1.0
- - (EDGE_SHARPNESS * 2000.0) * abs(temp_depth - depth)
+ - edge_sharpness * abs(temp_depth - depth)
);
sum += value * weight;
diff --git a/drivers/gles3/shaders/subsurf_scattering.glsl b/drivers/gles3/shaders/subsurf_scattering.glsl
index 20c3b7473f..fc66d66198 100644
--- a/drivers/gles3/shaders/subsurf_scattering.glsl
+++ b/drivers/gles3/shaders/subsurf_scattering.glsl
@@ -82,18 +82,18 @@ QUALIFIER vec2 kernel[17] = vec2[](
const int kernel_size=11;
-QUALIFIER vec4 kernel[11] = vec4[](
- vec4(0.560479, 0.0),
- vec4(0.00471691, -2.0),
- vec4(0.0192831, -1.28),
- vec4(0.03639, -0.72),
- vec4(0.0821904, -0.32),
- vec4(0.0771802, -0.08),
- vec4(0.0771802, 0.08),
- vec4(0.0821904, 0.32),
- vec4(0.03639, 0.72),
- vec4(0.0192831, 1.28),
- vec4(0.00471691,2.0)
+QUALIFIER vec2 kernel[11] = vec2[](
+ vec2(0.560479, 0.0),
+ vec2(0.00471691, -2.0),
+ vec2(0.0192831, -1.28),
+ vec2(0.03639, -0.72),
+ vec2(0.0821904, -0.32),
+ vec2(0.0771802, -0.08),
+ vec2(0.0771802, 0.08),
+ vec2(0.0821904, 0.32),
+ vec2(0.03639, 0.72),
+ vec2(0.0192831, 1.28),
+ vec2(0.00471691,2.0)
);
#endif //USE_11_SAMPLES
@@ -190,4 +190,3 @@ void main() {
frag_color = base_color;
}
}
-
diff --git a/drivers/gles3/shaders/tonemap.glsl b/drivers/gles3/shaders/tonemap.glsl
index 73dec4f90c..2f671158b2 100644
--- a/drivers/gles3/shaders/tonemap.glsl
+++ b/drivers/gles3/shaders/tonemap.glsl
@@ -175,12 +175,9 @@ vec3 tonemap_reindhart(vec3 color,float white) {
return ( color * ( 1.0 + ( color / ( white) ) ) ) / ( 1.0 + color );
}
-
void main() {
- ivec2 coord = ivec2(gl_FragCoord.xy);
- vec3 color = texelFetch(source,coord,0).rgb;
-
+ vec4 color = textureLod(source, uv_interp, 0.0);
#ifdef USE_AUTO_EXPOSURE
@@ -324,5 +321,3 @@ void main() {
frag_color=vec4(color.rgb,1.0);
}
-
-
diff --git a/drivers/unix/SCsub b/drivers/unix/SCsub
index c560e1289f..ada8255580 100644
--- a/drivers/unix/SCsub
+++ b/drivers/unix/SCsub
@@ -2,16 +2,6 @@
Import('env')
-g_set_p = '#ifdef UNIX_ENABLED\n'
-g_set_p += '#include "os_unix.h"\n'
-g_set_p += 'String OS_Unix::get_global_settings_path() const {\n'
-g_set_p += '\treturn "' + env["unix_global_settings_path"] + '";\n'
-g_set_p += '}\n'
-g_set_p += '#endif'
-f = open("os_unix_global_settings_path.gen.cpp", "w")
-f.write(g_set_p)
-f.close()
-
env.add_source_files(env.drivers_sources, "*.cpp")
env["check_c_headers"] = [ [ "mntent.h", "HAVE_MNTENT" ] ]
diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp
index 29fe73f170..0d102902e8 100644
--- a/drivers/unix/os_unix.cpp
+++ b/drivers/unix/os_unix.cpp
@@ -133,13 +133,6 @@ void OS_Unix::initialize_core() {
}
}
-void OS_Unix::initialize_logger() {
- Vector<Logger *> loggers;
- loggers.push_back(memnew(UnixTerminalLogger));
- loggers.push_back(memnew(RotatedFileLogger("user://logs/log.txt")));
- _set_logger(memnew(CompositeLogger(loggers)));
-}
-
void OS_Unix::finalize_core() {
}
@@ -285,7 +278,7 @@ uint64_t OS_Unix::get_ticks_usec() const {
return longtime;
}
-Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode) {
+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) {
if (p_blocking && r_pipe) {
@@ -297,7 +290,11 @@ Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, bo
argss += String(" \"") + p_arguments[i] + "\"";
}
- argss += " 2>/dev/null"; //silence stderr
+ if (read_stderr) {
+ argss += " 2>&1"; // Read stderr too
+ } else {
+ argss += " 2>/dev/null"; //silence stderr
+ }
FILE *f = popen(argss.utf8().get_data(), "r");
ERR_FAIL_COND_V(!f, ERR_CANT_OPEN);
@@ -339,7 +336,7 @@ Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, bo
execvp(getprogname(), &args[0]);
}
#else
- execv(p_path.utf8().get_data(), &args[0]);
+ execvp(p_path.utf8().get_data(), &args[0]);
#endif
// still alive? something failed..
fprintf(stderr, "**ERROR** OS_Unix::execute - Could not create child process while executing: %s\n", p_path.utf8().get_data());
@@ -448,32 +445,21 @@ int OS_Unix::get_processor_count() const {
return sysconf(_SC_NPROCESSORS_CONF);
}
-String OS_Unix::get_data_dir() const {
-
- String an = get_safe_application_name();
- if (an != "") {
-
- if (has_environment("HOME")) {
+String OS_Unix::get_user_data_dir() const {
- bool use_godot = ProjectSettings::get_singleton()->get("application/config/use_shared_user_dir");
- if (use_godot)
- return get_environment("HOME") + "/.godot/app_userdata/" + an;
- else
- return get_environment("HOME") + "/." + an;
+ String appname = get_safe_application_name();
+ if (appname != "") {
+ bool use_godot_dir = ProjectSettings::get_singleton()->get("application/config/use_shared_user_dir");
+ if (use_godot_dir) {
+ return get_data_path().plus_file(get_godot_dir_name()).plus_file("app_userdata").plus_file(appname);
+ } else {
+ return get_data_path().plus_file(appname);
}
}
return ProjectSettings::get_singleton()->get_resource_path();
}
-String OS_Unix::get_installed_templates_path() const {
- String p = get_global_settings_path();
- if (p != "")
- return p + "/templates/";
- else
- return "";
-}
-
String OS_Unix::get_executable_path() const {
#ifdef __linux__
@@ -548,4 +534,10 @@ void UnixTerminalLogger::log_error(const char *p_function, const char *p_file, i
UnixTerminalLogger::~UnixTerminalLogger() {}
+OS_Unix::OS_Unix() {
+ Vector<Logger *> loggers;
+ loggers.push_back(memnew(UnixTerminalLogger));
+ _set_logger(memnew(CompositeLogger(loggers)));
+}
+
#endif
diff --git a/drivers/unix/os_unix.h b/drivers/unix/os_unix.h
index 1cc44c0ffd..5b3fb824f0 100644
--- a/drivers/unix/os_unix.h
+++ b/drivers/unix/os_unix.h
@@ -49,12 +49,10 @@ protected:
//virtual int get_video_driver_count() const;
//virtual const char * get_video_driver_name(int p_driver) const;
- //virtual VideoMode get_default_video_mode() const;
virtual int get_audio_driver_count() const;
virtual const char *get_audio_driver_name(int p_driver) const;
- virtual void initialize_logger();
virtual void initialize_core();
virtual int unix_initialize_audio(int p_audio_driver);
//virtual void initialize(int p_video_driver,int p_audio_driver);
@@ -63,9 +61,9 @@ protected:
String stdin_buf;
- String get_global_settings_path() const;
-
public:
+ OS_Unix();
+
virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
virtual String get_stdin_string(bool p_block);
@@ -97,7 +95,7 @@ public:
virtual void delay_usec(uint32_t p_usec) const;
virtual uint64_t get_ticks_usec() const;
- virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id = NULL, String *r_pipe = NULL, int *r_exitcode = NULL);
+ virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id = NULL, String *r_pipe = NULL, int *r_exitcode = NULL, bool read_stderr = false);
virtual Error kill(const ProcessID &p_pid);
virtual int get_process_id() const;
@@ -109,11 +107,8 @@ public:
virtual void debug_break();
- virtual String get_installed_templates_path() const;
virtual String get_executable_path() const;
- virtual String get_data_dir() const;
-
- //virtual void run( MainLoop * p_main_loop );
+ virtual String get_user_data_dir() const;
};
class UnixTerminalLogger : public StdLogger {
diff --git a/drivers/wasapi/audio_driver_wasapi.cpp b/drivers/wasapi/audio_driver_wasapi.cpp
index eb86491dec..0671ee408e 100644
--- a/drivers/wasapi/audio_driver_wasapi.cpp
+++ b/drivers/wasapi/audio_driver_wasapi.cpp
@@ -39,7 +39,7 @@ const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator);
const IID IID_IAudioClient = __uuidof(IAudioClient);
const IID IID_IAudioRenderClient = __uuidof(IAudioRenderClient);
-Error AudioDriverWASAPI::init_device() {
+Error AudioDriverWASAPI::init_device(bool reinit) {
WAVEFORMATEX *pwfex;
IMMDeviceEnumerator *enumerator = NULL;
@@ -51,10 +51,24 @@ Error AudioDriverWASAPI::init_device() {
ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);
hr = enumerator->GetDefaultAudioEndpoint(eRender, eConsole, &device);
- ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);
+ if (reinit) {
+ // In case we're trying to re-initialize the device prevent throwing this error on the console,
+ // otherwise if there is currently no devie available this will spam the console.
+ if (hr != S_OK) {
+ return ERR_CANT_OPEN;
+ }
+ } else {
+ ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);
+ }
hr = device->Activate(IID_IAudioClient, CLSCTX_ALL, NULL, (void **)&audio_client);
- ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);
+ if (reinit) {
+ if (hr != S_OK) {
+ return ERR_CANT_OPEN;
+ }
+ } else {
+ ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);
+ }
hr = audio_client->GetMixFormat(&pwfex);
ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);
@@ -152,7 +166,9 @@ Error AudioDriverWASAPI::finish_device() {
Error AudioDriverWASAPI::init() {
Error err = init_device();
- ERR_FAIL_COND_V(err != OK, err);
+ if (err != OK) {
+ ERR_PRINT("WASAPI: init_device error");
+ }
active = false;
exit_thread = false;
@@ -209,7 +225,7 @@ void AudioDriverWASAPI::thread_func(void *p_udata) {
unsigned int left_frames = ad->buffer_frames;
unsigned int buffer_idx = 0;
- while (left_frames > 0) {
+ while (left_frames > 0 && ad->audio_client) {
WaitForSingleObject(ad->event, 1000);
UINT32 cur_frames;
@@ -271,9 +287,9 @@ void AudioDriverWASAPI::thread_func(void *p_udata) {
} else if (hr == AUDCLNT_E_DEVICE_INVALIDATED) {
// Device is not valid anymore, reopen it
- Error err = ad->reopen();
+ Error err = ad->finish_device();
if (err != OK) {
- ad->exit_thread = true;
+ ERR_PRINT("WASAPI: finish_device error");
} else {
// We reopened the device and samples_in may have resized, so invalidate the current left_frames
left_frames = 0;
@@ -285,9 +301,9 @@ void AudioDriverWASAPI::thread_func(void *p_udata) {
} else if (hr == AUDCLNT_E_DEVICE_INVALIDATED) {
// Device is not valid anymore, reopen it
- Error err = ad->reopen();
+ Error err = ad->finish_device();
if (err != OK) {
- ad->exit_thread = true;
+ ERR_PRINT("WASAPI: finish_device error");
} else {
// We reopened the device and samples_in may have resized, so invalidate the current left_frames
left_frames = 0;
@@ -296,6 +312,13 @@ void AudioDriverWASAPI::thread_func(void *p_udata) {
ERR_PRINT("WASAPI: GetCurrentPadding error");
}
}
+
+ if (!ad->audio_client) {
+ Error err = ad->init_device(true);
+ if (err == OK) {
+ ad->start();
+ }
+ }
}
ad->thread_exited = true;
@@ -303,11 +326,13 @@ void AudioDriverWASAPI::thread_func(void *p_udata) {
void AudioDriverWASAPI::start() {
- HRESULT hr = audio_client->Start();
- if (hr != S_OK) {
- ERR_PRINT("WASAPI: Start failed");
- } else {
- active = true;
+ if (audio_client) {
+ HRESULT hr = audio_client->Start();
+ if (hr != S_OK) {
+ ERR_PRINT("WASAPI: Start failed");
+ } else {
+ active = true;
+ }
}
}
diff --git a/drivers/wasapi/audio_driver_wasapi.h b/drivers/wasapi/audio_driver_wasapi.h
index fab8ab3250..87a2db724c 100644
--- a/drivers/wasapi/audio_driver_wasapi.h
+++ b/drivers/wasapi/audio_driver_wasapi.h
@@ -64,7 +64,7 @@ class AudioDriverWASAPI : public AudioDriver {
static void thread_func(void *p_udata);
- Error init_device();
+ Error init_device(bool reinit = false);
Error finish_device();
Error reopen();
diff --git a/drivers/windows/dir_access_windows.cpp b/drivers/windows/dir_access_windows.cpp
index 8d6e78dbee..0bc4201ba3 100644
--- a/drivers/windows/dir_access_windows.cpp
+++ b/drivers/windows/dir_access_windows.cpp
@@ -164,7 +164,7 @@ Error DirAccessWindows::make_dir(String p_dir) {
p_dir = fix_path(p_dir);
if (p_dir.is_rel_path())
- p_dir = get_current_dir().plus_file(p_dir);
+ p_dir = current_dir.plus_file(p_dir);
p_dir = p_dir.replace("/", "\\");