summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gles2/rasterizer_canvas_gles2.cpp41
-rw-r--r--drivers/gles2/rasterizer_canvas_gles2.h1
-rw-r--r--drivers/gles2/rasterizer_scene_gles2.cpp219
-rw-r--r--drivers/gles2/rasterizer_scene_gles2.h10
-rw-r--r--drivers/gles2/rasterizer_storage_gles2.cpp336
-rw-r--r--drivers/gles2/rasterizer_storage_gles2.h18
-rw-r--r--drivers/gles2/shader_compiler_gles2.cpp5
-rw-r--r--drivers/gles2/shader_gles2.cpp535
-rw-r--r--drivers/gles2/shader_gles2.h275
-rw-r--r--drivers/gles2/shaders/canvas.glsl18
-rw-r--r--drivers/gles2/shaders/canvas_shadow.glsl2
-rw-r--r--drivers/gles2/shaders/cubemap_filter.glsl13
-rw-r--r--drivers/gles2/shaders/scene.glsl60
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp4
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp3
-rw-r--r--drivers/gles3/shader_gles3.cpp9
-rw-r--r--drivers/gles3/shaders/canvas.glsl4
-rw-r--r--drivers/gles3/shaders/canvas_shadow.glsl2
-rw-r--r--drivers/gles3/shaders/scene.glsl54
-rw-r--r--drivers/gles3/shaders/screen_space_reflection.glsl2
-rw-r--r--drivers/unix/file_access_unix.cpp2
-rw-r--r--drivers/unix/syslog_logger.h2
-rw-r--r--drivers/wasapi/audio_driver_wasapi.cpp27
23 files changed, 847 insertions, 795 deletions
diff --git a/drivers/gles2/rasterizer_canvas_gles2.cpp b/drivers/gles2/rasterizer_canvas_gles2.cpp
index bf210ef2b2..5d336d2a25 100644
--- a/drivers/gles2/rasterizer_canvas_gles2.cpp
+++ b/drivers/gles2/rasterizer_canvas_gles2.cpp
@@ -112,25 +112,21 @@ void RasterizerCanvasGLES2::_set_uniforms() {
void RasterizerCanvasGLES2::canvas_begin() {
state.canvas_shader.bind();
- bool transparent = false;
+ state.using_transparent_rt = false;
if (storage->frame.current_rt) {
glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->fbo);
- glColorMask(1, 1, 1, 1);
- transparent = storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT];
+ state.using_transparent_rt = storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT];
}
if (storage->frame.clear_request) {
- glColorMask(true, true, true, true);
glClearColor(storage->frame.clear_request_color.r,
storage->frame.clear_request_color.g,
storage->frame.clear_request_color.b,
- transparent ? storage->frame.clear_request_color.a : 1.0);
+ state.using_transparent_rt ? storage->frame.clear_request_color.a : 1.0);
glClear(GL_COLOR_BUFFER_BIT);
storage->frame.clear_request = false;
}
- glColorMask(1, 1, 1, transparent ? 1 : 0);
-
/*
if (storage->frame.current_rt) {
glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->fbo);
@@ -186,7 +182,7 @@ void RasterizerCanvasGLES2::canvas_end() {
state.using_texture_rect = false;
state.using_skeleton = false;
state.using_ninepatch = false;
- glColorMask(1, 1, 1, 1);
+ state.using_transparent_rt = false;
}
RasterizerStorageGLES2::Texture *RasterizerCanvasGLES2::_bind_canvas_texture(const RID &p_texture, const RID &p_normal_map) {
@@ -503,6 +499,23 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
glDisableVertexAttribArray(VS::ARRAY_COLOR);
glVertexAttrib4fv(VS::ARRAY_COLOR, r->modulate.components);
+ bool can_tile = true;
+ if (r->texture.is_valid() && r->flags & CANVAS_RECT_TILE && !storage->config.support_npot_repeat_mipmap) {
+ // workaround for when setting tiling does not work due to hardware limitation
+
+ RasterizerStorageGLES2::Texture *texture = storage->texture_owner.getornull(r->texture);
+
+ if (texture) {
+
+ texture = texture->get_ptr();
+
+ if (next_power_of_2(texture->alloc_width) != (unsigned int)texture->alloc_width && next_power_of_2(texture->alloc_height) != (unsigned int)texture->alloc_height) {
+ state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_FORCE_REPEAT, true);
+ can_tile = false;
+ }
+ }
+ }
+
// On some widespread Nvidia cards, the normal draw method can produce some
// flickering in draw_rect and especially TileMap rendering (tiles randomly flicker).
// See GH-9913.
@@ -563,7 +576,7 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
bool untile = false;
- if (r->flags & CANVAS_RECT_TILE && !(texture->flags & VS::TEXTURE_FLAG_REPEAT)) {
+ if (can_tile && r->flags & CANVAS_RECT_TILE && !(texture->flags & VS::TEXTURE_FLAG_REPEAT)) {
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
untile = true;
@@ -620,7 +633,7 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
bool untile = false;
- if (r->flags & CANVAS_RECT_TILE && !(tex->flags & VS::TEXTURE_FLAG_REPEAT)) {
+ if (can_tile && r->flags & CANVAS_RECT_TILE && !(tex->flags & VS::TEXTURE_FLAG_REPEAT)) {
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
untile = true;
@@ -668,6 +681,9 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
+
+ state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_FORCE_REPEAT, false);
+
} break;
case Item::Command::TYPE_NINEPATCH: {
@@ -1189,6 +1205,8 @@ void RasterizerCanvasGLES2::_copy_screen(const Rect2 &p_rect) {
storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_COPY_SECTION, true);
}
+ storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_NO_ALPHA, !state.using_transparent_rt);
+
glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->copy_screen_effect.fbo);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->color);
@@ -1218,6 +1236,7 @@ void RasterizerCanvasGLES2::_copy_screen(const Rect2 &p_rect) {
_draw_polygon(indexpos, 6, 4, vertpos, uvpos, NULL, false);
storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_COPY_SECTION, false);
+ storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_NO_ALPHA, false);
glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->fbo); //back to front
glEnable(GL_BLEND);
@@ -2000,6 +2019,7 @@ void RasterizerCanvasGLES2::initialize() {
state.canvas_shader.init();
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_TEXTURE_RECT, true);
+ state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_RGBA_SHADOWS, storage->config.use_rgba_2d_shadows);
state.canvas_shader.bind();
@@ -2008,6 +2028,7 @@ void RasterizerCanvasGLES2::initialize() {
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_PIXEL_SNAP, GLOBAL_DEF("rendering/quality/2d/use_pixel_snap", false));
state.using_light = NULL;
+ state.using_transparent_rt = false;
}
void RasterizerCanvasGLES2::finalize() {
diff --git a/drivers/gles2/rasterizer_canvas_gles2.h b/drivers/gles2/rasterizer_canvas_gles2.h
index 0d069ebabc..af41e91e0c 100644
--- a/drivers/gles2/rasterizer_canvas_gles2.h
+++ b/drivers/gles2/rasterizer_canvas_gles2.h
@@ -93,6 +93,7 @@ public:
Transform vp;
Light *using_light;
bool using_shadow;
+ bool using_transparent_rt;
} state;
diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp
index 3920a5f96a..e6f46776c0 100644
--- a/drivers/gles2/rasterizer_scene_gles2.cpp
+++ b/drivers/gles2/rasterizer_scene_gles2.cpp
@@ -42,8 +42,6 @@
#define glClearDepth glClearDepthf
#endif
-#define _DEPTH_COMPONENT24_OES 0x81A6
-
static const GLenum _cube_side_enum[6] = {
GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
@@ -62,6 +60,7 @@ RID RasterizerSceneGLES2::shadow_atlas_create() {
ShadowAtlas *shadow_atlas = memnew(ShadowAtlas);
shadow_atlas->fbo = 0;
shadow_atlas->depth = 0;
+ shadow_atlas->color = 0;
shadow_atlas->size = 0;
shadow_atlas->smallest_subdiv = 0;
@@ -84,11 +83,19 @@ void RasterizerSceneGLES2::shadow_atlas_set_size(RID p_atlas, int p_size) {
// erase the old atlast
if (shadow_atlas->fbo) {
- glDeleteTextures(1, &shadow_atlas->depth);
+ if (storage->config.use_rgba_3d_shadows) {
+ glDeleteRenderbuffers(1, &shadow_atlas->depth);
+ } else {
+ glDeleteTextures(1, &shadow_atlas->depth);
+ }
glDeleteFramebuffers(1, &shadow_atlas->fbo);
+ if (shadow_atlas->color) {
+ glDeleteTextures(1, &shadow_atlas->color);
+ }
shadow_atlas->fbo = 0;
shadow_atlas->depth = 0;
+ shadow_atlas->color = 0;
}
// erase shadow atlast references from lights
@@ -108,17 +115,36 @@ void RasterizerSceneGLES2::shadow_atlas_set_size(RID p_atlas, int p_size) {
// create a depth texture
glActiveTexture(GL_TEXTURE0);
- glGenTextures(1, &shadow_atlas->depth);
- glBindTexture(GL_TEXTURE_2D, shadow_atlas->depth);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, shadow_atlas->size, shadow_atlas->size, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ if (storage->config.use_rgba_3d_shadows) {
+
+ //maximum compatibility, renderbuffer and RGBA shadow
+ glGenRenderbuffers(1, &shadow_atlas->depth);
+ glBindRenderbuffer(GL_RENDERBUFFER, directional_shadow.depth);
+ glRenderbufferStorage(GL_RENDERBUFFER, storage->config.depth_internalformat, shadow_atlas->size, shadow_atlas->size);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, shadow_atlas->depth);
+
+ glGenTextures(1, &shadow_atlas->color);
+ glBindTexture(GL_TEXTURE_2D, shadow_atlas->color);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, shadow_atlas->size, shadow_atlas->size, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, shadow_atlas->color, 0);
+ } else {
+ //just depth texture
+ glGenTextures(1, &shadow_atlas->depth);
+ glBindTexture(GL_TEXTURE_2D, shadow_atlas->depth);
+ glTexImage2D(GL_TEXTURE_2D, 0, storage->config.depth_internalformat, shadow_atlas->size, shadow_atlas->size, 0, GL_DEPTH_COMPONENT, storage->config.depth_type, NULL);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, shadow_atlas->depth, 0);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, shadow_atlas->depth, 0);
+ }
glViewport(0, 0, shadow_atlas->size, shadow_atlas->size);
glDepthMask(GL_TRUE);
@@ -143,7 +169,7 @@ void RasterizerSceneGLES2::shadow_atlas_set_quadrant_subdivision(RID p_atlas, in
subdiv = int(Math::sqrt((float)subdiv));
- if (shadow_atlas->quadrants[p_quadrant].shadows.size() == subdiv)
+ if (shadow_atlas->quadrants[p_quadrant].shadows.size() == (int)subdiv)
return;
// erase all data from the quadrant
@@ -459,10 +485,11 @@ RID RasterizerSceneGLES2::reflection_probe_instance_create(RID p_probe) {
for (int i = 0; i < 6; i++) {
glGenFramebuffers(1, &rpi->fbo[i]);
+ glGenTextures(1, &rpi->color[i]);
}
- glGenFramebuffers(1, &rpi->fbo_blur);
glGenRenderbuffers(1, &rpi->depth);
+
rpi->cubemap = 0;
//glGenTextures(1, &rpi->cubemap);
@@ -510,9 +537,14 @@ bool RasterizerSceneGLES2::reflection_probe_instance_begin_render(RID p_instance
GLenum type = GL_UNSIGNED_BYTE;
glActiveTexture(GL_TEXTURE0);
+
+ glBindRenderbuffer(GL_RENDERBUFFER, rpi->depth);
+ glRenderbufferStorage(GL_RENDERBUFFER, storage->config.depth_internalformat, size, size);
+
if (rpi->cubemap != 0) {
glDeleteTextures(1, &rpi->cubemap);
}
+
glGenTextures(1, &rpi->cubemap);
glBindTexture(GL_TEXTURE_CUBE_MAP, rpi->cubemap);
#if 1
@@ -523,17 +555,15 @@ bool RasterizerSceneGLES2::reflection_probe_instance_begin_render(RID p_instance
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
- glBindRenderbuffer(GL_RENDERBUFFER, rpi->depth); //resize depth buffer
-#ifdef JAVASCRIPT_ENABLED
- glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, size, size);
-#else
- glRenderbufferStorage(GL_RENDERBUFFER, _DEPTH_COMPONENT24_OES, size, size);
-#endif
-
+ //Generate framebuffers for rendering
for (int i = 0; i < 6; i++) {
glBindFramebuffer(GL_FRAMEBUFFER, rpi->fbo[i]);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _cube_side_enum[i], rpi->cubemap, 0);
+ glBindTexture(GL_TEXTURE_2D, rpi->color[i]);
+ glTexImage2D(GL_TEXTURE_2D, 0, internal_format, size, size, 0, format, type, NULL);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rpi->color[i], 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rpi->depth);
+ GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ ERR_CONTINUE(status != GL_FRAMEBUFFER_COMPLETE);
}
#else
@@ -550,8 +580,6 @@ bool RasterizerSceneGLES2::reflection_probe_instance_begin_render(RID p_instance
//adjust framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, rpi->fbo[i]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _cube_side_enum[i], rpi->cubemap, 0);
- glBindRenderbuffer(GL_RENDERBUFFER, rpi->depth);
- glRenderbufferStorage(GL_RENDERBUFFER, _DEPTH_COMPONENT24_OES, size, size);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rpi->depth);
#ifdef DEBUG_ENABLED
@@ -570,6 +598,8 @@ bool RasterizerSceneGLES2::reflection_probe_instance_begin_render(RID p_instance
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES2::system_fbo);
}
return true;
@@ -579,6 +609,7 @@ bool RasterizerSceneGLES2::reflection_probe_instance_postprocess_step(RID p_inst
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance);
ERR_FAIL_COND_V(!rpi, false);
+ ERR_FAIL_COND_V(rpi->current_resolution == 0, false);
int size = rpi->probe_ptr->resolution;
@@ -596,16 +627,23 @@ bool RasterizerSceneGLES2::reflection_probe_instance_postprocess_step(RID p_inst
}
}
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, rpi->cubemap);
+ glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //use linear, no mipmaps so it does not read from what is being written to
+
+ //first of all, copy rendered textures to cubemap
+ for (int i = 0; i < 6; i++) {
+ glBindFramebuffer(GL_FRAMEBUFFER, rpi->fbo[i]);
+ glViewport(0, 0, size, size);
+ glCopyTexImage2D(_cube_side_enum[i], 0, GL_RGB, 0, 0, size, size, 0);
+ }
+ //do filtering
//vdc cache
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, storage->resources.radical_inverse_vdc_cache_tex);
- glBindFramebuffer(GL_FRAMEBUFFER, rpi->fbo_blur);
// now render to the framebuffer, mipmap level for mipmap level
int lod = 1;
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_CUBE_MAP, rpi->cubemap);
- glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //use linear, no mipmaps so it does not read from what is being written to
size >>= 1;
int mipmaps = 6;
@@ -613,13 +651,20 @@ bool RasterizerSceneGLES2::reflection_probe_instance_postprocess_step(RID p_inst
storage->shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES2::USE_SOURCE_PANORAMA, false);
storage->shaders.cubemap_filter.bind();
+ glBindFramebuffer(GL_FRAMEBUFFER, storage->resources.mipmap_blur_fbo);
+
//blur
while (size >= 1) {
+ glActiveTexture(GL_TEXTURE3);
+ glBindTexture(GL_TEXTURE_2D, storage->resources.mipmap_blur_color);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, size, size, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, storage->resources.mipmap_blur_color, 0);
+ glViewport(0, 0, size, size);
+ glActiveTexture(GL_TEXTURE0);
+
for (int i = 0; i < 6; i++) {
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _cube_side_enum[i], rpi->cubemap, lod);
- glViewport(0, 0, size, size);
storage->bind_quad_array();
storage->shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES2::FACE_ID, i);
float roughness = CLAMP(lod / (float)(mipmaps - 1), 0, 1);
@@ -627,6 +672,7 @@ bool RasterizerSceneGLES2::reflection_probe_instance_postprocess_step(RID p_inst
storage->shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES2::Z_FLIP, false);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ glCopyTexImage2D(_cube_side_enum[i], lod, GL_RGB, 0, 0, size, size, 0);
}
size >>= 1;
@@ -635,9 +681,14 @@ bool RasterizerSceneGLES2::reflection_probe_instance_postprocess_step(RID p_inst
}
// restore ranges
-
+ glActiveTexture(GL_TEXTURE0);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glActiveTexture(GL_TEXTURE3); //back to panorama
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES2::system_fbo);
return true;
}
@@ -1183,9 +1234,14 @@ bool RasterizerSceneGLES2::_setup_material(RasterizerStorageGLES2::Material *p_m
glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->copy_screen_effect.color);
}
+ if (p_material->shader->spatial.uses_depth_texture && storage->frame.current_rt) {
+ glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 4);
+ glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->depth);
+ }
+
bool shader_rebind = state.scene_shader.bind();
- if (p_material->shader->spatial.no_depth_test) {
+ if (p_material->shader->spatial.no_depth_test || p_material->shader->spatial.uses_depth_texture) {
glDisable(GL_DEPTH_TEST);
} else {
glEnable(GL_DEPTH_TEST);
@@ -1195,10 +1251,10 @@ bool RasterizerSceneGLES2::_setup_material(RasterizerStorageGLES2::Material *p_m
case RasterizerStorageGLES2::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS:
case RasterizerStorageGLES2::Shader::Spatial::DEPTH_DRAW_OPAQUE: {
- glDepthMask(!p_alpha_pass);
+ glDepthMask(!p_alpha_pass && !p_material->shader->spatial.uses_depth_texture);
} break;
case RasterizerStorageGLES2::Shader::Spatial::DEPTH_DRAW_ALWAYS: {
- glDepthMask(GL_TRUE);
+ glDepthMask(GL_TRUE && !p_material->shader->spatial.uses_depth_texture);
} break;
case RasterizerStorageGLES2::Shader::Spatial::DEPTH_DRAW_NEVER: {
glDepthMask(GL_FALSE);
@@ -1221,9 +1277,9 @@ bool RasterizerSceneGLES2::_setup_material(RasterizerStorageGLES2::Material *p_m
}
int tc = p_material->textures.size();
- Pair<StringName, RID> *textures = p_material->textures.ptrw();
+ const Pair<StringName, RID> *textures = p_material->textures.ptr();
- ShaderLanguage::ShaderNode::Uniform::Hint *texture_hints = p_material->shader->texture_hints.ptrw();
+ const ShaderLanguage::ShaderNode::Uniform::Hint *texture_hints = p_material->shader->texture_hints.ptr();
state.scene_shader.set_uniform(SceneShaderGLES2::SKELETON_TEXTURE_SIZE, p_skeleton_tex_size);
@@ -1746,7 +1802,11 @@ void RasterizerSceneGLES2::_setup_light_type(LightInstance *p_light, ShadowAtlas
if (!state.render_no_shadows && p_light->light_ptr->shadow) {
state.scene_shader.set_conditional(SceneShaderGLES2::USE_SHADOW, true);
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 3);
- glBindTexture(GL_TEXTURE_2D, directional_shadow.depth);
+ if (storage->config.use_rgba_3d_shadows) {
+ glBindTexture(GL_TEXTURE_2D, directional_shadow.color);
+ } else {
+ glBindTexture(GL_TEXTURE_2D, directional_shadow.depth);
+ }
state.scene_shader.set_conditional(SceneShaderGLES2::SHADOW_MODE_PCF_5, shadow_filter_mode == SHADOW_FILTER_PCF5);
state.scene_shader.set_conditional(SceneShaderGLES2::SHADOW_MODE_PCF_13, shadow_filter_mode == SHADOW_FILTER_PCF13);
}
@@ -1758,7 +1818,11 @@ void RasterizerSceneGLES2::_setup_light_type(LightInstance *p_light, ShadowAtlas
if (!state.render_no_shadows && shadow_atlas && p_light->light_ptr->shadow) {
state.scene_shader.set_conditional(SceneShaderGLES2::USE_SHADOW, true);
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 3);
- glBindTexture(GL_TEXTURE_2D, shadow_atlas->depth);
+ if (storage->config.use_rgba_3d_shadows) {
+ glBindTexture(GL_TEXTURE_2D, shadow_atlas->color);
+ } else {
+ glBindTexture(GL_TEXTURE_2D, shadow_atlas->depth);
+ }
state.scene_shader.set_conditional(SceneShaderGLES2::SHADOW_MODE_PCF_5, shadow_filter_mode == SHADOW_FILTER_PCF5);
state.scene_shader.set_conditional(SceneShaderGLES2::SHADOW_MODE_PCF_13, shadow_filter_mode == SHADOW_FILTER_PCF13);
}
@@ -1769,7 +1833,11 @@ void RasterizerSceneGLES2::_setup_light_type(LightInstance *p_light, ShadowAtlas
if (!state.render_no_shadows && shadow_atlas && p_light->light_ptr->shadow) {
state.scene_shader.set_conditional(SceneShaderGLES2::USE_SHADOW, true);
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 3);
- glBindTexture(GL_TEXTURE_2D, shadow_atlas->depth);
+ if (storage->config.use_rgba_3d_shadows) {
+ glBindTexture(GL_TEXTURE_2D, shadow_atlas->color);
+ } else {
+ glBindTexture(GL_TEXTURE_2D, shadow_atlas->depth);
+ }
state.scene_shader.set_conditional(SceneShaderGLES2::SHADOW_MODE_PCF_5, shadow_filter_mode == SHADOW_FILTER_PCF5);
state.scene_shader.set_conditional(SceneShaderGLES2::SHADOW_MODE_PCF_13, shadow_filter_mode == SHADOW_FILTER_PCF13);
}
@@ -2036,7 +2104,7 @@ void RasterizerSceneGLES2::_setup_refprobes(ReflectionProbeInstance *p_refprobe1
state.scene_shader.set_uniform(SceneShaderGLES2::REFPROBE2_USE_BOX_PROJECT, p_refprobe2->probe_ptr->box_projection);
state.scene_shader.set_uniform(SceneShaderGLES2::REFPROBE2_BOX_EXTENTS, p_refprobe2->probe_ptr->extents);
state.scene_shader.set_uniform(SceneShaderGLES2::REFPROBE2_BOX_OFFSET, p_refprobe2->probe_ptr->origin_offset);
- state.scene_shader.set_uniform(SceneShaderGLES2::REFPROBE2_EXTERIOR, !p_refprobe2->probe_ptr->interior);
+ state.scene_shader.set_uniform(SceneShaderGLES2::REFPROBE2_EXTERIOR, p_refprobe2->probe_ptr->interior);
state.scene_shader.set_uniform(SceneShaderGLES2::REFPROBE2_INTENSITY, p_refprobe2->probe_ptr->intensity);
Color ambient;
@@ -2359,7 +2427,7 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
} else {
state.scene_shader.set_uniform(SceneShaderGLES2::BG_ENERGY, 1.0);
state.scene_shader.set_uniform(SceneShaderGLES2::AMBIENT_SKY_CONTRIBUTION, 1.0);
- state.scene_shader.set_uniform(SceneShaderGLES2::AMBIENT_COLOR, Color(1.0, 1.0, 1.0, 1.0));
+ state.scene_shader.set_uniform(SceneShaderGLES2::AMBIENT_COLOR, state.default_ambient);
state.scene_shader.set_uniform(SceneShaderGLES2::AMBIENT_ENERGY, 1.0);
}
@@ -2471,7 +2539,6 @@ void RasterizerSceneGLES2::_draw_sky(RasterizerStorageGLES2::Sky *p_sky, const C
glDisable(GL_CULL_FACE);
glDisable(GL_BLEND);
glDepthFunc(GL_LEQUAL);
- glColorMask(1, 1, 1, 1);
// Camera
CameraMatrix camera;
@@ -2673,7 +2740,7 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
// clear color
- Color clear_color(0, 0, 0, 0);
+ Color clear_color(0, 0, 0, 1);
if (storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) {
clear_color = Color(0, 0, 0, 0);
@@ -2694,6 +2761,8 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
glClearColor(clear_color.r, clear_color.g, clear_color.b, clear_color.a);
}
+ state.default_ambient = Color(clear_color.r, clear_color.g, clear_color.b, 1.0);
+
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1);
@@ -2731,6 +2800,7 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
if (probe_interior) {
env_radiance_tex = 0; //do not use radiance texture on interiors
+ state.default_ambient = Color(0, 0, 0, 1); //black as default ambient for interior
}
// render opaque things first
@@ -2919,7 +2989,7 @@ void RasterizerSceneGLES2::render_shadow(RID p_light, RID p_shadow_atlas, int p_
if (light->type == VS::LIGHT_OMNI) {
// cubemap only
- if (light->omni_shadow_mode == VS::LIGHT_OMNI_SHADOW_CUBE && storage->config.support_write_depth) {
+ if (light->omni_shadow_mode == VS::LIGHT_OMNI_SHADOW_CUBE && storage->config.support_shadow_cubemaps) {
int cubemap_index = shadow_cubemaps.size() - 1;
// find an appropriate cubemap to render to
@@ -2988,7 +3058,9 @@ void RasterizerSceneGLES2::render_shadow(RID p_light, RID p_shadow_atlas, int p_
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glDepthMask(GL_TRUE);
- glColorMask(0, 0, 0, 0);
+ if (!storage->config.use_rgba_3d_shadows) {
+ glColorMask(0, 0, 0, 0);
+ }
if (custom_vp_size) {
glViewport(0, 0, custom_vp_size, custom_vp_size);
@@ -3015,7 +3087,7 @@ void RasterizerSceneGLES2::render_shadow(RID p_light, RID p_shadow_atlas, int p_
state.scene_shader.set_conditional(SceneShaderGLES2::RENDER_DEPTH_DUAL_PARABOLOID, false);
// convert cubemap to dual paraboloid if needed
- if (light->type == VS::LIGHT_OMNI && (light->omni_shadow_mode == VS::LIGHT_OMNI_SHADOW_CUBE && storage->config.support_write_depth) && p_pass == 5) {
+ if (light->type == VS::LIGHT_OMNI && (light->omni_shadow_mode == VS::LIGHT_OMNI_SHADOW_CUBE && storage->config.support_shadow_cubemaps) && p_pass == 5) {
ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas);
glBindFramebuffer(GL_FRAMEBUFFER, shadow_atlas->fbo);
@@ -3064,7 +3136,9 @@ void RasterizerSceneGLES2::render_shadow(RID p_light, RID p_shadow_atlas, int p_
if (storage->frame.current_rt) {
glViewport(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height);
}
- glColorMask(1, 1, 1, 1);
+ if (!storage->config.use_rgba_3d_shadows) {
+ glColorMask(1, 1, 1, 1);
+ }
}
void RasterizerSceneGLES2::set_scene_pass(uint64_t p_pass) {
@@ -3102,6 +3176,16 @@ bool RasterizerSceneGLES2::free(RID p_rid) {
ReflectionProbeInstance *reflection_instance = reflection_probe_instance_owner.get(p_rid);
+ for (int i = 0; i < 6; i++) {
+ glDeleteFramebuffers(1, &reflection_instance->fbo[i]);
+ glDeleteTextures(1, &reflection_instance->color[i]);
+ }
+
+ if (reflection_instance->cubemap != 0) {
+ glDeleteTextures(1, &reflection_instance->cubemap);
+ }
+ glDeleteRenderbuffers(1, &reflection_instance->depth);
+
reflection_probe_release_atlas_index(p_rid);
reflection_probe_instance_owner.free(p_rid);
memdelete(reflection_instance);
@@ -3118,6 +3202,8 @@ void RasterizerSceneGLES2::set_debug_draw_mode(VS::ViewportDebugDraw p_debug_dra
void RasterizerSceneGLES2::initialize() {
state.scene_shader.init();
+
+ state.scene_shader.set_conditional(SceneShaderGLES2::USE_RGBA_SHADOWS, storage->config.use_rgba_3d_shadows);
state.cube_to_dp_shader.init();
render_list.init();
@@ -3179,7 +3265,7 @@ void RasterizerSceneGLES2::initialize() {
}
// cubemaps for shadows
- if (storage->config.support_write_depth) { //not going to be used
+ if (storage->config.support_shadow_cubemaps) { //not going to be used
int max_shadow_cubemap_sampler_size = 512;
int cube_size = max_shadow_cubemap_sampler_size;
@@ -3196,7 +3282,8 @@ void RasterizerSceneGLES2::initialize() {
glBindTexture(GL_TEXTURE_CUBE_MAP, cube.cubemap);
for (int i = 0; i < 6; i++) {
- glTexImage2D(_cube_side_enum[i], 0, GL_DEPTH_COMPONENT, cube_size, cube_size, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
+
+ glTexImage2D(_cube_side_enum[i], 0, storage->config.depth_internalformat, cube_size, cube_size, 0, GL_DEPTH_COMPONENT, storage->config.depth_type, NULL);
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
@@ -3227,17 +3314,35 @@ void RasterizerSceneGLES2::initialize() {
glGenFramebuffers(1, &directional_shadow.fbo);
glBindFramebuffer(GL_FRAMEBUFFER, directional_shadow.fbo);
- glGenTextures(1, &directional_shadow.depth);
- glBindTexture(GL_TEXTURE_2D, directional_shadow.depth);
+ if (storage->config.use_rgba_3d_shadows) {
+ //maximum compatibility, renderbuffer and RGBA shadow
+ glGenRenderbuffers(1, &directional_shadow.depth);
+ glBindRenderbuffer(GL_RENDERBUFFER, directional_shadow.depth);
+ glRenderbufferStorage(GL_RENDERBUFFER, storage->config.depth_internalformat, directional_shadow.size, directional_shadow.size);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, directional_shadow.depth);
+
+ glGenTextures(1, &directional_shadow.color);
+ glBindTexture(GL_TEXTURE_2D, directional_shadow.color);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, directional_shadow.size, directional_shadow.size, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, directional_shadow.color, 0);
+ } else {
+ //just a depth buffer
+ glGenTextures(1, &directional_shadow.depth);
+ glBindTexture(GL_TEXTURE_2D, directional_shadow.depth);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, directional_shadow.size, directional_shadow.size, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
+ glTexImage2D(GL_TEXTURE_2D, 0, storage->config.depth_internalformat, directional_shadow.size, directional_shadow.size, 0, GL_DEPTH_COMPONENT, storage->config.depth_type, NULL);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, directional_shadow.depth, 0);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, directional_shadow.depth, 0);
+ }
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
diff --git a/drivers/gles2/rasterizer_scene_gles2.h b/drivers/gles2/rasterizer_scene_gles2.h
index 0d917f4da2..f23e45b52f 100644
--- a/drivers/gles2/rasterizer_scene_gles2.h
+++ b/drivers/gles2/rasterizer_scene_gles2.h
@@ -103,6 +103,7 @@ public:
GLuint sky_verts;
GLuint immediate_buffer;
+ Color default_ambient;
// ResolveShaderGLES3 resolve_shader;
// ScreenSpaceReflectionShaderGLES3 ssr_shader;
@@ -255,6 +256,7 @@ public:
GLuint fbo;
GLuint depth;
+ GLuint color;
Map<RID, uint32_t> shadow_owners;
};
@@ -278,6 +280,7 @@ public:
struct DirectionalShadow {
GLuint fbo;
GLuint depth;
+ GLuint color;
int light_count;
int size;
@@ -310,10 +313,9 @@ public:
int reflection_index;
GLuint fbo[6];
- GLuint cubemap;
+ GLuint color[6];
GLuint depth;
-
- GLuint fbo_blur;
+ GLuint cubemap;
int current_resolution;
mutable bool dirty;
@@ -473,7 +475,7 @@ public:
virtual void light_instance_set_transform(RID p_light_instance, const Transform &p_transform);
virtual void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_bias_scale = 1.0);
virtual void light_instance_mark_visible(RID p_light_instance);
- virtual bool light_instances_can_render_shadow_cube() const { return storage->config.support_write_depth; }
+ virtual bool light_instances_can_render_shadow_cube() const { return storage->config.support_shadow_cubemaps; }
LightInstance **render_light_instances;
int render_directional_lights;
diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp
index 0227cd2b34..afb3f651c7 100644
--- a/drivers/gles2/rasterizer_storage_gles2.cpp
+++ b/drivers/gles2/rasterizer_storage_gles2.cpp
@@ -54,10 +54,10 @@ GLuint RasterizerStorageGLES2::system_fbo = 0;
#define _EXT_TEXTURE_CUBE_MAP_SEAMLESS 0x884F
-#define _DEPTH_COMPONENT24_OES 0x81A6
-
#define _RED_OES 0x1903
+#define _DEPTH_COMPONENT24_OES 0x81A6
+
void RasterizerStorageGLES2::bind_quad_array() const {
glBindBuffer(GL_ARRAY_BUFFER, resources.quadie);
glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, 0);
@@ -67,7 +67,7 @@ void RasterizerStorageGLES2::bind_quad_array() const {
glEnableVertexAttribArray(VS::ARRAY_TEX_UV);
}
-Ref<Image> RasterizerStorageGLES2::_get_gl_image_and_format(const Ref<Image> &p_image, Image::Format p_format, uint32_t p_flags, Image::Format &r_real_format, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type, bool &r_compressed) const {
+Ref<Image> RasterizerStorageGLES2::_get_gl_image_and_format(const Ref<Image> &p_image, Image::Format p_format, uint32_t p_flags, Image::Format &r_real_format, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type, bool &r_compressed, bool p_will_need_resize) const {
r_gl_format = 0;
Ref<Image> image = p_image;
@@ -195,7 +195,7 @@ Ref<Image> RasterizerStorageGLES2::_get_gl_image_and_format(const Ref<Image> &p_
} break;
case Image::FORMAT_DXT1: {
- if (config.s3tc_supported) {
+ if (config.s3tc_supported && !p_will_need_resize) {
r_gl_internal_format = _EXT_COMPRESSED_RGBA_S3TC_DXT1_EXT;
r_gl_format = GL_RGBA;
r_gl_type = GL_UNSIGNED_BYTE;
@@ -207,7 +207,7 @@ Ref<Image> RasterizerStorageGLES2::_get_gl_image_and_format(const Ref<Image> &p_
} break;
case Image::FORMAT_DXT3: {
- if (config.s3tc_supported) {
+ if (config.s3tc_supported && !p_will_need_resize) {
r_gl_internal_format = _EXT_COMPRESSED_RGBA_S3TC_DXT3_EXT;
r_gl_format = GL_RGBA;
r_gl_type = GL_UNSIGNED_BYTE;
@@ -219,7 +219,7 @@ Ref<Image> RasterizerStorageGLES2::_get_gl_image_and_format(const Ref<Image> &p_
} break;
case Image::FORMAT_DXT5: {
- if (config.s3tc_supported) {
+ if (config.s3tc_supported && !p_will_need_resize) {
r_gl_internal_format = _EXT_COMPRESSED_RGBA_S3TC_DXT5_EXT;
r_gl_format = GL_RGBA;
r_gl_type = GL_UNSIGNED_BYTE;
@@ -269,7 +269,7 @@ Ref<Image> RasterizerStorageGLES2::_get_gl_image_and_format(const Ref<Image> &p_
} break;
case Image::FORMAT_ETC: {
- if (config.etc1_supported) {
+ if (config.etc1_supported && !p_will_need_resize) {
r_gl_internal_format = _EXT_ETC1_RGB8_OES;
r_gl_format = GL_RGBA;
r_gl_type = GL_UNSIGNED_BYTE;
@@ -315,17 +315,38 @@ Ref<Image> RasterizerStorageGLES2::_get_gl_image_and_format(const Ref<Image> &p_
if (need_decompress) {
if (!image.is_null()) {
+
image = image->duplicate();
+ print_line("decompressing...");
image->decompress();
ERR_FAIL_COND_V(image->is_compressed(), image);
- image->convert(Image::FORMAT_RGBA8);
+ switch (image->get_format()) {
+ case Image::FORMAT_RGB8: {
+ r_gl_format = GL_RGB;
+ r_gl_internal_format = GL_RGB;
+ r_gl_type = GL_UNSIGNED_BYTE;
+ r_real_format = Image::FORMAT_RGB8;
+ r_compressed = false;
+ } break;
+ case Image::FORMAT_RGBA8: {
+ r_gl_format = GL_RGBA;
+ r_gl_internal_format = GL_RGBA;
+ r_gl_type = GL_UNSIGNED_BYTE;
+ r_real_format = Image::FORMAT_RGBA8;
+ r_compressed = false;
+ } break;
+ default: {
+ image->convert(Image::FORMAT_RGBA8);
+ r_gl_format = GL_RGBA;
+ r_gl_internal_format = GL_RGBA;
+ r_gl_type = GL_UNSIGNED_BYTE;
+ r_real_format = Image::FORMAT_RGBA8;
+ r_compressed = false;
+
+ } break;
+ }
}
- r_gl_format = GL_RGBA;
- r_gl_internal_format = GL_RGBA;
- r_gl_type = GL_UNSIGNED_BYTE;
- r_real_format = Image::FORMAT_RGBA8;
-
return image;
}
@@ -395,11 +416,31 @@ void RasterizerStorageGLES2::texture_allocate(RID p_texture, int p_width, int p_
}
}
- Image::Format real_format;
- _get_gl_image_and_format(Ref<Image>(), texture->format, texture->flags, real_format, format, internal_format, type, compressed);
-
texture->alloc_width = texture->width;
texture->alloc_height = texture->height;
+ texture->resize_to_po2 = false;
+ if (!config.support_npot_repeat_mipmap) {
+ int po2_width = next_power_of_2(p_width);
+ int po2_height = next_power_of_2(p_height);
+
+ bool is_po2 = p_width == po2_width && p_height == po2_height;
+
+ if (!is_po2 && (p_flags & VS::TEXTURE_FLAG_REPEAT || p_flags & VS::TEXTURE_FLAG_MIPMAPS)) {
+
+ if (p_flags & VS::TEXTURE_FLAG_USED_FOR_STREAMING) {
+ //not supported
+ ERR_PRINTS("Streaming texture for non power of 2 or has mipmaps on this hardware: " + texture->path + "'. Mipmaps and repeat disabled.");
+ texture->flags &= ~(VS::TEXTURE_FLAG_REPEAT | VS::TEXTURE_FLAG_MIPMAPS);
+ } else {
+ texture->alloc_height = po2_height;
+ texture->alloc_width = po2_width;
+ texture->resize_to_po2 = true;
+ }
+ }
+ }
+
+ Image::Format real_format;
+ _get_gl_image_and_format(Ref<Image>(), texture->format, texture->flags, real_format, format, internal_format, type, compressed, texture->resize_to_po2);
texture->gl_format_cache = format;
texture->gl_type_cache = type;
@@ -414,7 +455,7 @@ void RasterizerStorageGLES2::texture_allocate(RID p_texture, int p_width, int p_
if (p_flags & VS::TEXTURE_FLAG_USED_FOR_STREAMING) {
//prealloc if video
- glTexImage2D(texture->target, 0, internal_format, p_width, p_height, 0, format, type, NULL);
+ glTexImage2D(texture->target, 0, internal_format, texture->alloc_width, texture->alloc_height, 0, format, type, NULL);
}
texture->active = true;
@@ -439,7 +480,18 @@ void RasterizerStorageGLES2::texture_set_data(RID p_texture, const Ref<Image> &p
}
Image::Format real_format;
- Ref<Image> img = _get_gl_image_and_format(p_image, p_image->get_format(), texture->flags, real_format, format, internal_format, type, compressed);
+ Ref<Image> img = _get_gl_image_and_format(p_image, p_image->get_format(), texture->flags, real_format, format, internal_format, type, compressed, texture->resize_to_po2);
+
+ if (texture->resize_to_po2) {
+ if (p_image->is_compressed()) {
+ ERR_PRINTS("Texture '" + texture->path + "' was required to be a power of 2 (because it uses either mipmaps or repeat), so it was decompressed. This will hurt performance and memory usage.");
+ }
+
+ if (img == p_image) {
+ img = img->duplicate();
+ }
+ img->resize_to_po2(false);
+ }
if (config.shrink_textures_x2 && (p_image->has_mipmaps() || !p_image->is_compressed()) && !(texture->flags & VS::TEXTURE_FLAG_USED_FOR_STREAMING)) {
@@ -575,7 +627,7 @@ Ref<Image> RasterizerStorageGLES2::texture_get_data(RID p_texture, int p_layer)
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);
+ _get_gl_image_and_format(Ref<Image>(), texture->format, texture->flags, real_format, gl_format, gl_internal_format, gl_type, compressed, false);
PoolVector<uint8_t> data;
@@ -620,7 +672,7 @@ Ref<Image> RasterizerStorageGLES2::texture_get_data(RID p_texture, int p_layer)
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);
+ _get_gl_image_and_format(Ref<Image>(), texture->format, texture->flags, real_format, gl_format, gl_internal_format, gl_type, compressed, texture->resize_to_po2);
PoolVector<uint8_t> data;
@@ -974,18 +1026,8 @@ void RasterizerStorageGLES2::sky_set_texture(RID p_sky, RID p_panorama, int p_ra
glGenTextures(1, &sky->radiance);
glBindTexture(GL_TEXTURE_CUBE_MAP, sky->radiance);
- // Now we create a new framebuffer. The new cubemap images will be used as
- // attachements for it, so we can fill them by issuing draw calls.
- GLuint tmp_fb;
-
int size = p_radiance_size / 4; //divide by four because its a cubemap (this is an approximation because GLES3 uses a dual paraboloid)
- int lod = 0;
-
- int mipmaps = 6;
-
- int mm_level = mipmaps;
-
GLenum internal_format = GL_RGB;
GLenum format = GL_RGB;
GLenum type = GL_UNSIGNED_BYTE;
@@ -998,6 +1040,12 @@ void RasterizerStorageGLES2::sky_set_texture(RID p_sky, RID p_panorama, int p_ra
}
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
+ //no filters for now
+ glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
#else
while (size >= 1) {
@@ -1011,34 +1059,50 @@ void RasterizerStorageGLES2::sky_set_texture(RID p_sky, RID p_panorama, int p_ra
}
#endif
//framebuffer
- glGenFramebuffers(1, &tmp_fb);
- glBindFramebuffer(GL_FRAMEBUFFER, tmp_fb);
-
- shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES2::USE_SOURCE_PANORAMA, texture->target == GL_TEXTURE_2D);
- shaders.cubemap_filter.bind();
- lod = 0;
- mm_level = mipmaps;
+ glBindFramebuffer(GL_FRAMEBUFFER, resources.mipmap_blur_fbo);
+ int mipmaps = 6;
+ int lod = 0;
+ int mm_level = mipmaps;
size = p_radiance_size;
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES2::USE_SOURCE_PANORAMA, true);
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES2::USE_DIRECT_WRITE, true);
+ shaders.cubemap_filter.bind();
- // now render to the framebuffer, mipmap level for mipmap level
+ // third, render to the framebuffer using separate textures, then copy to mipmaps
while (size >= 1) {
+ //make framebuffer size the texture size, need to use a separate texture for compatibility
+ glActiveTexture(GL_TEXTURE3);
+ glBindTexture(GL_TEXTURE_2D, resources.mipmap_blur_color);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, size, size, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resources.mipmap_blur_color, 0);
+ if (lod == 1) {
+ //bind panorama for smaller lods
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, sky->radiance);
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES2::USE_SOURCE_PANORAMA, false);
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES2::USE_DIRECT_WRITE, false);
+ shaders.cubemap_filter.bind();
+ }
+ glViewport(0, 0, size, size);
+ bind_quad_array();
- for (int i = 0; i < 6; i++) {
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _cube_side_enum[i], sky->radiance, lod);
-
- glViewport(0, 0, size, size);
+ glActiveTexture(GL_TEXTURE2); //back to panorama
- bind_quad_array();
+ for (int i = 0; i < 6; i++) {
shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES2::FACE_ID, i);
- float roughness = mm_level ? lod / (float)(mipmaps - 1) : 1;
+ float roughness = mm_level >= 0 ? lod / (float)(mipmaps - 1) : 1;
roughness = MIN(1.0, roughness); //keep max at 1
shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES2::ROUGHNESS, roughness);
+ shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES2::Z_FLIP, false);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ glCopyTexImage2D(_cube_side_enum[i], lod, GL_RGB, 0, 0, size, size, 0);
}
size >>= 1;
@@ -1048,16 +1112,28 @@ void RasterizerStorageGLES2::sky_set_texture(RID p_sky, RID p_panorama, int p_ra
lod++;
}
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES2::USE_SOURCE_PANORAMA, false);
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES2::USE_DIRECT_WRITE, false);
+
// restore ranges
+ glActiveTexture(GL_TEXTURE2); //back to panorama
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glActiveTexture(GL_TEXTURE3); //back to panorama
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
// Framebuffer did its job. thank mr framebuffer
+ glActiveTexture(GL_TEXTURE0); //back to panorama
glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES2::system_fbo);
- glDeleteFramebuffers(1, &tmp_fb);
}
/* SHADER API */
@@ -1230,6 +1306,22 @@ void RasterizerStorageGLES2::_update_shader(Shader *p_shader) const {
actions = &shaders.actions_scene;
actions->uniforms = &p_shader->uniforms;
+
+ if (p_shader->spatial.uses_screen_texture && p_shader->spatial.uses_depth_texture) {
+ static bool show_warning = true; //show warning only once
+ if (show_warning) {
+ ERR_PRINT("Using both SCREEN_TEXTURE and DEPTH_TEXTURE is not supported in GLES2");
+ show_warning = false;
+ }
+ }
+
+ if (p_shader->spatial.uses_depth_texture && !config.support_depth_texture) {
+ static bool show_warning = true; //show warning only once
+ if (show_warning) {
+ ERR_PRINT("Using DEPTH_TEXTURE is not permitted on this hardware, operation will fail.");
+ show_warning = false;
+ }
+ }
} break;
default: {
@@ -2205,6 +2297,8 @@ void RasterizerStorageGLES2::mesh_add_surface(RID p_mesh, uint32_t p_format, VS:
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, surface->index_id);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_array_size, ir.ptr(), GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ } else {
+ surface->index_id = 0;
}
// TODO generate wireframes
@@ -2231,7 +2325,7 @@ void RasterizerStorageGLES2::mesh_add_surface(RID p_mesh, uint32_t p_format, VS:
}
mesh->surfaces.push_back(surface);
- mesh->instance_change_notify(true, false);
+ mesh->instance_change_notify(true, true);
info.vertex_mem += surface->total_data_size;
}
@@ -2375,7 +2469,6 @@ AABB RasterizerStorageGLES2::mesh_surface_get_aabb(RID p_mesh, int p_surface) co
}
Vector<PoolVector<uint8_t> > RasterizerStorageGLES2::mesh_surface_get_blend_shapes(RID p_mesh, int p_surface) const {
- WARN_PRINT("GLES2 mesh_surface_get_blend_shapes is not implemented");
return Vector<PoolVector<uint8_t> >();
}
Vector<AABB> RasterizerStorageGLES2::mesh_surface_get_skeleton_aabb(RID p_mesh, int p_surface) const {
@@ -3599,6 +3692,7 @@ RID RasterizerStorageGLES2::reflection_probe_create() {
reflection_probe->intensity = 1.0;
reflection_probe->interior_ambient = Color();
reflection_probe->interior_ambient_energy = 1.0;
+ reflection_probe->interior_ambient_probe_contrib = 0.0;
reflection_probe->max_distance = 0;
reflection_probe->extents = Vector3(1, 1, 1);
reflection_probe->origin_offset = Vector3(0, 0, 0);
@@ -3684,6 +3778,7 @@ void RasterizerStorageGLES2::reflection_probe_set_as_interior(RID p_probe, bool
ERR_FAIL_COND(!reflection_probe);
reflection_probe->interior = p_enable;
+ reflection_probe->instance_change_notify(true, false);
}
void RasterizerStorageGLES2::reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) {
@@ -4200,7 +4295,12 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) {
glGenTextures(1, &rt->color);
glBindTexture(GL_TEXTURE_2D, rt->color);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rt->width, rt->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+
+ if (rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) {
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rt->width, rt->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ } else {
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, rt->width, rt->height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+ }
if (texture->flags & VS::TEXTURE_FLAG_FILTER) {
@@ -4218,21 +4318,36 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) {
// depth
- glGenRenderbuffers(1, &rt->depth);
- glBindRenderbuffer(GL_RENDERBUFFER, rt->depth);
-#ifdef JAVASCRIPT_ENABLED
- glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, rt->width, rt->height);
-#else
- glRenderbufferStorage(GL_RENDERBUFFER, _DEPTH_COMPONENT24_OES, rt->width, rt->height);
-#endif
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth);
+ if (config.support_depth_texture) {
+ glGenTextures(1, &rt->depth);
+ glBindTexture(GL_TEXTURE_2D, rt->depth);
+ glTexImage2D(GL_TEXTURE_2D, 0, config.depth_internalformat, rt->width, rt->height, 0, GL_DEPTH_COMPONENT, config.depth_type, NULL);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->depth, 0);
+ } else {
+ glGenRenderbuffers(1, &rt->depth);
+ glBindRenderbuffer(GL_RENDERBUFFER, rt->depth);
+
+ glRenderbufferStorage(GL_RENDERBUFFER, config.depth_internalformat, rt->width, rt->height);
+
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth);
+ }
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
- glDeleteRenderbuffers(1, &rt->fbo);
- glDeleteTextures(1, &rt->depth);
+ glDeleteFramebuffers(1, &rt->fbo);
+ if (config.support_depth_texture) {
+ glDeleteTextures(1, &rt->depth);
+ } else {
+ glDeleteRenderbuffers(1, &rt->depth);
+ }
glDeleteTextures(1, &rt->color);
rt->fbo = 0;
rt->width = 0;
@@ -4264,13 +4379,15 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) {
// copy texscreen buffers
if (!(rt->flags[RasterizerStorage::RENDER_TARGET_NO_SAMPLING])) {
- int w = rt->width;
- int h = rt->height;
-
glGenTextures(1, &rt->copy_screen_effect.color);
glBindTexture(GL_TEXTURE_2D, rt->copy_screen_effect.color);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ if (rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) {
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rt->width, rt->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ } else {
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, rt->width, rt->height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+ }
+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
@@ -4302,7 +4419,12 @@ void RasterizerStorageGLES2::_render_target_clear(RenderTarget *rt) {
}
if (rt->depth) {
- glDeleteRenderbuffers(1, &rt->depth);
+ if (config.support_depth_texture) {
+ glDeleteTextures(1, &rt->depth);
+ } else {
+ glDeleteRenderbuffers(1, &rt->depth);
+ }
+
rt->depth = 0;
}
@@ -4313,7 +4435,6 @@ void RasterizerStorageGLES2::_render_target_clear(RenderTarget *rt) {
tex->height = 0;
tex->active = false;
- // TODO hardcoded texscreen copy effect
if (rt->copy_screen_effect.color) {
glDeleteFramebuffers(1, &rt->copy_screen_effect.fbo);
rt->copy_screen_effect.fbo = 0;
@@ -4443,13 +4564,8 @@ RID RasterizerStorageGLES2::canvas_light_shadow_buffer_create(int p_width) {
glGenRenderbuffers(1, &cls->depth);
glBindRenderbuffer(GL_RENDERBUFFER, cls->depth);
-#ifdef JAVASCRIPT_ENABLED
- glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, cls->size, cls->height);
-#else
- glRenderbufferStorage(GL_RENDERBUFFER, _DEPTH_COMPONENT24_OES, cls->size, cls->height);
-#endif
+ glRenderbufferStorage(GL_RENDERBUFFER, config.depth_internalformat, cls->size, cls->height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, cls->depth);
- glBindRenderbuffer(GL_RENDERBUFFER, 0);
glGenTextures(1, &cls->distance);
glBindTexture(GL_TEXTURE_2D, cls->distance);
@@ -4827,6 +4943,9 @@ bool RasterizerStorageGLES2::free(RID p_rid) {
bool RasterizerStorageGLES2::has_os_feature(const String &p_feature) const {
+ if (p_feature == "pvrtc")
+ return config.pvrtc_supported;
+
if (p_feature == "s3tc")
return config.s3tc_supported;
@@ -4876,16 +4995,30 @@ void RasterizerStorageGLES2::initialize() {
#ifdef GLES_OVER_GL
config.float_texture_supported = true;
config.s3tc_supported = true;
+ config.pvrtc_supported = false;
config.etc1_supported = false;
+ config.support_npot_repeat_mipmap = true;
+ config.depth_internalformat = GL_DEPTH_COMPONENT;
+ config.depth_type = GL_UNSIGNED_INT;
+
#else
config.float_texture_supported = config.extensions.has("GL_ARB_texture_float") || config.extensions.has("GL_OES_texture_float");
config.s3tc_supported = config.extensions.has("GL_EXT_texture_compression_s3tc") || config.extensions.has("WEBGL_compressed_texture_s3tc");
config.etc1_supported = config.extensions.has("GL_OES_compressed_ETC1_RGB8_texture") || config.extensions.has("WEBGL_compressed_texture_etc1");
+ config.pvrtc_supported = config.extensions.has("IMG_texture_compression_pvrtc");
+ config.support_npot_repeat_mipmap = config.extensions.has("GL_OES_texture_npot");
+
#endif
#ifdef GLES_OVER_GL
config.use_rgba_2d_shadows = false;
+ config.support_depth_texture = true;
+ config.use_rgba_3d_shadows = false;
+ config.support_depth_cubemaps = true;
#else
config.use_rgba_2d_shadows = !(config.float_texture_supported && config.extensions.has("GL_EXT_texture_rg"));
+ config.support_depth_texture = config.extensions.has("GL_OES_depth_texture");
+ config.use_rgba_3d_shadows = !config.support_depth_texture;
+ config.support_depth_cubemaps = config.extensions.has("GL_OES_depth_texture_cube_map");
#endif
#ifdef GLES_OVER_GL
@@ -4896,6 +5029,8 @@ void RasterizerStorageGLES2::initialize() {
#ifdef GLES_OVER_GL
config.support_write_depth = true;
+#elif defined(JAVASCRIPT_ENABLED)
+ config.support_write_depth = false;
#else
config.support_write_depth = config.extensions.has("GL_EXT_frag_depth");
#endif
@@ -4907,6 +5042,55 @@ void RasterizerStorageGLES2::initialize() {
config.support_half_float_vertices = true;
#endif
+ //determine formats for depth textures (or renderbuffers)
+ if (config.support_depth_texture) {
+ // Will use texture for depth
+ // have to manually see if we can create a valid framebuffer texture using UNSIGNED_INT,
+ // as there is no extension to test for this.
+ GLuint fbo;
+ glGenFramebuffers(1, &fbo);
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ GLuint depth;
+ glGenTextures(1, &depth);
+ glBindTexture(GL_TEXTURE_2D, depth);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 32, 32, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth, 0);
+
+ GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+
+ if (status == GL_FRAMEBUFFER_COMPLETE) {
+ config.depth_internalformat = GL_DEPTH_COMPONENT;
+ config.depth_type = GL_UNSIGNED_INT;
+ } else {
+ config.depth_internalformat = GL_DEPTH_COMPONENT16;
+ config.depth_type = GL_UNSIGNED_SHORT;
+ }
+
+ glBindFramebuffer(GL_FRAMEBUFFER, system_fbo);
+ glDeleteFramebuffers(1, &fbo);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glDeleteTextures(1, &depth);
+
+ } else {
+ // Will use renderbuffer for depth
+ if (config.extensions.has("GL_OES_depth24")) {
+ config.depth_internalformat = _DEPTH_COMPONENT24_OES;
+ config.depth_type = GL_UNSIGNED_INT;
+ } else {
+ config.depth_internalformat = GL_DEPTH_COMPONENT16;
+ config.depth_type = GL_UNSIGNED_SHORT;
+ }
+ }
+
+ //picky requirements for these
+ config.support_shadow_cubemaps = config.support_depth_texture && config.support_write_depth && config.support_depth_cubemaps;
+
frame.count = 0;
frame.delta = 0;
frame.current_rt = NULL;
@@ -4917,7 +5101,7 @@ void RasterizerStorageGLES2::initialize() {
shaders.copy.init();
shaders.cubemap_filter.init();
- bool ggx_hq = GLOBAL_GET("rendering/quality/reflections/high_quality_ggx.mobile");
+ bool ggx_hq = GLOBAL_GET("rendering/quality/reflections/high_quality_ggx");
shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES2::LOW_QUALITY, !ggx_hq);
{
@@ -5037,10 +5221,20 @@ void RasterizerStorageGLES2::initialize() {
}
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 512, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, radical_inverse);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); //need this for proper sampling
glBindTexture(GL_TEXTURE_2D, 0);
}
+ {
+
+ glGenFramebuffers(1, &resources.mipmap_blur_fbo);
+ glGenTextures(1, &resources.mipmap_blur_color);
+ }
+
#ifdef GLES_OVER_GL
//this needs to be enabled manually in OpenGL 2.1
diff --git a/drivers/gles2/rasterizer_storage_gles2.h b/drivers/gles2/rasterizer_storage_gles2.h
index a0fa2aacc5..92885b47e1 100644
--- a/drivers/gles2/rasterizer_storage_gles2.h
+++ b/drivers/gles2/rasterizer_storage_gles2.h
@@ -72,16 +72,26 @@ public:
bool float_texture_supported;
bool s3tc_supported;
bool etc1_supported;
+ bool pvrtc_supported;
bool keep_original_textures;
bool force_vertex_shading;
bool use_rgba_2d_shadows;
+ bool use_rgba_3d_shadows;
bool support_32_bits_indices;
bool support_write_depth;
bool support_half_float_vertices;
+ bool support_npot_repeat_mipmap;
+ bool support_depth_texture;
+ bool support_depth_cubemaps;
+
+ bool support_shadow_cubemaps;
+
+ GLuint depth_internalformat;
+ GLuint depth_type;
} config;
struct Resources {
@@ -91,6 +101,9 @@ public:
GLuint normal_tex;
GLuint aniso_tex;
+ GLuint mipmap_blur_fbo;
+ GLuint mipmap_blur_color;
+
GLuint radical_inverse_vdc_cache_tex;
bool use_rgba_2d_shadows;
@@ -240,6 +253,8 @@ public:
int mipmaps;
+ bool resize_to_po2;
+
bool active;
GLenum tex_id;
@@ -275,6 +290,7 @@ public:
ignore_mipmaps(false),
compressed(false),
mipmaps(0),
+ resize_to_po2(false),
active(false),
tex_id(0),
stored_cube_sides(0),
@@ -313,7 +329,7 @@ public:
mutable RID_Owner<Texture> texture_owner;
- Ref<Image> _get_gl_image_and_format(const Ref<Image> &p_image, Image::Format p_format, uint32_t p_flags, Image::Format &r_real_format, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type, bool &r_compressed) const;
+ Ref<Image> _get_gl_image_and_format(const Ref<Image> &p_image, Image::Format p_format, uint32_t p_flags, Image::Format &r_real_format, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type, bool &r_compressed, bool p_will_need_resize) const;
virtual RID texture_create();
virtual void texture_allocate(RID p_texture, int p_width, int p_height, int p_depth_3d, Image::Format p_format, VS::TextureType p_type, uint32_t p_flags = VS::TEXTURE_FLAGS_DEFAULT);
diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp
index 15897fe587..d00b03fb8a 100644
--- a/drivers/gles2/shader_compiler_gles2.cpp
+++ b/drivers/gles2/shader_compiler_gles2.cpp
@@ -770,7 +770,7 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
/** CANVAS ITEM SHADER **/
actions[VS::SHADER_CANVAS_ITEM].renames["VERTEX"] = "outvec.xy";
- actions[VS::SHADER_CANVAS_ITEM].renames["UV"] = "uv_interp";
+ actions[VS::SHADER_CANVAS_ITEM].renames["UV"] = "uv";
actions[VS::SHADER_CANVAS_ITEM].renames["POINT_SIZE"] = "gl_PointSize";
actions[VS::SHADER_CANVAS_ITEM].renames["WORLD_MATRIX"] = "modelview_matrix";
@@ -859,7 +859,7 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
actions[VS::SHADER_SPATIAL].renames["INSTANCE_CUSTOM"] = "instance_custom";
actions[VS::SHADER_SPATIAL].renames["SCREEN_UV"] = "screen_uv";
actions[VS::SHADER_SPATIAL].renames["SCREEN_TEXTURE"] = "screen_texture";
- actions[VS::SHADER_SPATIAL].renames["DEPTH_TEXTURE"] = "depth_buffer";
+ actions[VS::SHADER_SPATIAL].renames["DEPTH_TEXTURE"] = "depth_texture";
// Defined in GLES3, but not available in GLES2
//actions[VS::SHADER_SPATIAL].renames["DEPTH"] = "gl_FragDepth";
actions[VS::SHADER_SPATIAL].renames["ALPHA_SCISSOR"] = "alpha_scissor";
@@ -895,6 +895,7 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
actions[VS::SHADER_SPATIAL].usage_defines["SSS_STRENGTH"] = "#define ENABLE_SSS\n";
actions[VS::SHADER_SPATIAL].usage_defines["TRANSMISSION"] = "#define TRANSMISSION_USED\n";
actions[VS::SHADER_SPATIAL].usage_defines["SCREEN_TEXTURE"] = "#define SCREEN_TEXTURE_USED\n";
+ actions[VS::SHADER_SPATIAL].usage_defines["DEPTH_TEXTURE"] = "#define DEPTH_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";
diff --git a/drivers/gles2/shader_gles2.cpp b/drivers/gles2/shader_gles2.cpp
index 012d1538b6..6856035470 100644
--- a/drivers/gles2/shader_gles2.cpp
+++ b/drivers/gles2/shader_gles2.cpp
@@ -69,51 +69,6 @@ ShaderGLES2 *ShaderGLES2::active = NULL;
#endif
-void ShaderGLES2::bind_uniforms() {
- if (!uniforms_dirty)
- return;
-
- // regular uniforms
-
- const Map<uint32_t, Variant>::Element *E = uniform_defaults.front();
-
- while (E) {
- int idx = E->key();
- int location = version->uniform_location[idx];
-
- if (location < 0) {
- E = E->next();
- continue;
- }
-
- Variant v;
-
- v = E->value();
-
- _set_uniform_variant(location, v);
- E = E->next();
- }
-
- // camera uniforms
-
- const Map<uint32_t, CameraMatrix>::Element *C = uniform_cameras.front();
-
- while (C) {
- int idx = C->key();
- int location = version->uniform_location[idx];
-
- if (location < 0) {
- C = C->next();
- continue;
- }
-
- glUniformMatrix4fv(location, 1, GL_FALSE, &(C->get().matrix[0][0]));
- C = C->next();
- }
-
- uniforms_dirty = false;
-}
-
GLint ShaderGLES2::get_uniform_location(int p_index) const {
ERR_FAIL_COND_V(!version, -1);
@@ -139,28 +94,6 @@ bool ShaderGLES2::bind() {
glUseProgram(version->id);
- // find out uniform names and locations
-
- int count;
- glGetProgramiv(version->id, GL_ACTIVE_UNIFORMS, &count);
- version->uniform_names.resize(count);
-
- for (int i = 0; i < count; i++) {
- GLchar uniform_name[1024];
- int len = 0;
- GLint size = 0;
- GLenum type;
-
- glGetActiveUniform(version->id, i, 1024, &len, &size, &type, uniform_name);
-
- uniform_name[len] = '\0';
- String name = String((const char *)uniform_name);
-
- version->uniform_names.write[i] = name;
- }
-
- bind_uniforms();
-
DEBUG_TEST_ERROR("use program");
active = this;
@@ -513,6 +446,7 @@ ShaderGLES2::Version *ShaderGLES2::get_current_version() {
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;
+ glUniform1i(location, i);
}
}
@@ -732,342 +666,317 @@ void ShaderGLES2::use_material(void *p_material) {
if (E->get().texture_order >= 0)
continue; // this is a texture, doesn't go here
- Map<StringName, Variant>::Element *V = material->params.find(E->key());
+ Map<StringName, GLint>::Element *L = v->custom_uniform_locations.find(E->key());
+ if (!L || L->get() < 0)
+ continue; //uniform not valid
- Pair<ShaderLanguage::DataType, Vector<ShaderLanguage::ConstantNode::Value> > value;
+ GLuint location = L->get();
- value.first = E->get().type;
- value.second = E->get().default_value;
+ Map<StringName, Variant>::Element *V = material->params.find(E->key());
if (V) {
- value.second = Vector<ShaderLanguage::ConstantNode::Value>();
- value.second.resize(E->get().default_value.size());
switch (E->get().type) {
case ShaderLanguage::TYPE_BOOL: {
- if (value.second.size() < 1)
- value.second.resize(1);
- value.second.write[0].boolean = V->get();
+
+ bool boolean = V->get();
+ glUniform1i(location, boolean ? 1 : 0);
} break;
case ShaderLanguage::TYPE_BVEC2: {
- if (value.second.size() < 2)
- value.second.resize(2);
int flags = V->get();
- value.second.write[0].boolean = flags & 1;
- value.second.write[1].boolean = flags & 2;
+ glUniform2i(location, (flags & 1) ? 1 : 0, (flags & 2) ? 1 : 0);
} break;
case ShaderLanguage::TYPE_BVEC3: {
- if (value.second.size() < 3)
- value.second.resize(3);
+
int flags = V->get();
- value.second.write[0].boolean = flags & 1;
- value.second.write[1].boolean = flags & 2;
- value.second.write[2].boolean = flags & 4;
+ glUniform3i(location, (flags & 1) ? 1 : 0, (flags & 2) ? 1 : 0, (flags & 4) ? 1 : 0);
} break;
case ShaderLanguage::TYPE_BVEC4: {
- if (value.second.size() < 4)
- value.second.resize(4);
int flags = V->get();
- value.second.write[0].boolean = flags & 1;
- value.second.write[1].boolean = flags & 2;
- value.second.write[2].boolean = flags & 4;
- value.second.write[3].boolean = flags & 8;
+ glUniform4i(location, (flags & 1) ? 1 : 0, (flags & 2) ? 1 : 0, (flags & 4) ? 1 : 0, (flags & 8) ? 1 : 0);
} break;
- case ShaderLanguage::TYPE_INT: {
- if (value.second.size() < 1)
- value.second.resize(1);
- int val = V->get();
- value.second.write[0].sint = val;
+ case ShaderLanguage::TYPE_INT:
+ case ShaderLanguage::TYPE_UINT: {
+ int value = V->get();
+ glUniform1i(location, value);
} break;
- case ShaderLanguage::TYPE_IVEC2: {
- if (value.second.size() < 2)
- value.second.resize(2);
- PoolIntArray val = V->get();
- for (int i = 0; i < val.size(); i++) {
- value.second.write[i].sint = val[i];
+ case ShaderLanguage::TYPE_IVEC2:
+ case ShaderLanguage::TYPE_UVEC2: {
+
+ Array r = V->get();
+ const int count = 2;
+ if (r.size() == count) {
+ int values[count];
+ for (int i = 0; i < count; i++) {
+ values[i] = r[i];
+ }
+ glUniform2i(location, values[0], values[1]);
}
+
} break;
- case ShaderLanguage::TYPE_IVEC3: {
- if (value.second.size() < 3)
- value.second.resize(3);
- PoolIntArray val = V->get();
- for (int i = 0; i < val.size(); i++) {
- value.second.write[i].sint = val[i];
+ case ShaderLanguage::TYPE_IVEC3:
+ case ShaderLanguage::TYPE_UVEC3: {
+ Array r = V->get();
+ const int count = 3;
+ if (r.size() == count) {
+ int values[count];
+ for (int i = 0; i < count; i++) {
+ values[i] = r[i];
+ }
+ glUniform3i(location, values[0], values[1], values[2]);
}
} break;
- case ShaderLanguage::TYPE_IVEC4: {
- if (value.second.size() < 4)
- value.second.resize(4);
- PoolIntArray val = V->get();
- for (int i = 0; i < val.size(); i++) {
- value.second.write[i].sint = val[i];
+ case ShaderLanguage::TYPE_IVEC4:
+ case ShaderLanguage::TYPE_UVEC4: {
+ Array r = V->get();
+ const int count = 4;
+ if (r.size() == count) {
+ int values[count];
+ for (int i = 0; i < count; i++) {
+ values[i] = r[i];
+ }
+ glUniform4i(location, values[0], values[1], values[2], values[3]);
}
} break;
- case ShaderLanguage::TYPE_UINT: {
- if (value.second.size() < 1)
- value.second.resize(1);
- uint32_t val = V->get();
- value.second.write[0].uint = val;
+ case ShaderLanguage::TYPE_FLOAT: {
+ float value = V->get();
+ glUniform1f(location, value);
+
} break;
- case ShaderLanguage::TYPE_UVEC2: {
- if (value.second.size() < 2)
- value.second.resize(2);
- PoolIntArray val = V->get();
- for (int i = 0; i < val.size(); i++) {
- value.second.write[i].uint = val[i];
- }
+ case ShaderLanguage::TYPE_VEC2: {
+ Vector2 value = V->get();
+ glUniform2f(location, value.x, value.y);
+ } break;
+ case ShaderLanguage::TYPE_VEC3: {
+ Vector3 value = V->get();
+ glUniform3f(location, value.x, value.y, value.z);
} break;
- case ShaderLanguage::TYPE_UVEC3: {
- if (value.second.size() < 3)
- value.second.resize(3);
- PoolIntArray val = V->get();
- for (int i = 0; i < val.size(); i++) {
- value.second.write[i].uint = val[i];
+ case ShaderLanguage::TYPE_VEC4: {
+ if (V->get().get_type() == Variant::COLOR) {
+ Color value = V->get();
+ glUniform4f(location, value.r, value.g, value.b, value.a);
+ } else if (V->get().get_type() == Variant::QUAT) {
+ Quat value = V->get();
+ glUniform4f(location, value.x, value.y, value.z, value.w);
+ } else {
+ Plane value = V->get();
+ glUniform4f(location, value.normal.x, value.normal.y, value.normal.z, value.d);
}
} break;
- case ShaderLanguage::TYPE_UVEC4: {
- if (value.second.size() < 4)
- value.second.resize(4);
- PoolIntArray val = V->get();
- for (int i = 0; i < val.size(); i++) {
- value.second.write[i].uint = val[i];
- }
+ case ShaderLanguage::TYPE_MAT2: {
+
+ Transform2D tr = V->get();
+ GLfloat matrix[4] = {
+ /* build a 16x16 matrix */
+ tr.elements[0][0],
+ tr.elements[0][1],
+ tr.elements[1][0],
+ tr.elements[1][1],
+ };
+ glUniformMatrix2fv(location, 1, GL_FALSE, matrix);
} break;
- case ShaderLanguage::TYPE_FLOAT: {
- if (value.second.size() < 1)
- value.second.resize(1);
- value.second.write[0].real = V->get();
+ case ShaderLanguage::TYPE_MAT3: {
+ Basis val = V->get();
+
+ GLfloat mat[9] = {
+ val.elements[0][0],
+ val.elements[1][0],
+ val.elements[2][0],
+ val.elements[0][1],
+ val.elements[1][1],
+ val.elements[2][1],
+ val.elements[0][2],
+ val.elements[1][2],
+ val.elements[2][2],
+ };
+
+ glUniformMatrix3fv(location, 1, GL_FALSE, mat);
+
+ } break;
+
+ case ShaderLanguage::TYPE_MAT4: {
+
+ Transform2D tr = V->get();
+ GLfloat matrix[16] = { /* build a 16x16 matrix */
+ tr.elements[0][0],
+ tr.elements[0][1],
+ 0,
+ 0,
+ tr.elements[1][0],
+ tr.elements[1][1],
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ tr.elements[2][0],
+ tr.elements[2][1],
+ 0,
+ 1
+ };
+
+ glUniformMatrix4fv(location, 1, GL_FALSE, matrix);
+
+ } break;
+
+ default: {
+ ERR_PRINT("type missing, bug?");
+ } break;
+ }
+ } else if (E->get().default_value.size()) {
+ const Vector<ShaderLanguage::ConstantNode::Value> &values = E->get().default_value;
+ switch (E->get().type) {
+ case ShaderLanguage::TYPE_BOOL: {
+ glUniform1i(location, values[0].boolean);
+ } break;
+
+ case ShaderLanguage::TYPE_BVEC2: {
+ glUniform2i(location, values[0].boolean, values[1].boolean);
+ } break;
+
+ case ShaderLanguage::TYPE_BVEC3: {
+ glUniform3i(location, values[0].boolean, values[1].boolean, values[2].boolean);
+ } break;
+
+ case ShaderLanguage::TYPE_BVEC4: {
+ glUniform4i(location, values[0].boolean, values[1].boolean, values[2].boolean, values[3].boolean);
+ } break;
+
+ case ShaderLanguage::TYPE_INT: {
+ glUniform1i(location, values[0].sint);
+ } break;
+
+ case ShaderLanguage::TYPE_IVEC2: {
+ glUniform2i(location, values[0].sint, values[1].sint);
+ } break;
+
+ case ShaderLanguage::TYPE_IVEC3: {
+ glUniform3i(location, values[0].sint, values[1].sint, values[2].sint);
+ } break;
+
+ case ShaderLanguage::TYPE_IVEC4: {
+ glUniform4i(location, values[0].sint, values[1].sint, values[2].sint, values[3].sint);
+ } break;
+
+ case ShaderLanguage::TYPE_UINT: {
+ glUniform1i(location, values[0].uint);
+ } break;
+
+ case ShaderLanguage::TYPE_UVEC2: {
+ glUniform2i(location, values[0].uint, values[1].uint);
+ } break;
+ case ShaderLanguage::TYPE_UVEC3: {
+ glUniform3i(location, values[0].uint, values[1].uint, values[2].uint);
+ } break;
+
+ case ShaderLanguage::TYPE_UVEC4: {
+ glUniform4i(location, values[0].uint, values[1].uint, values[2].uint, values[3].uint);
+ } break;
+
+ case ShaderLanguage::TYPE_FLOAT: {
+ glUniform1f(location, values[0].real);
} break;
case ShaderLanguage::TYPE_VEC2: {
- if (value.second.size() < 2)
- value.second.resize(2);
- Vector2 val = V->get();
- value.second.write[0].real = val.x;
- value.second.write[1].real = val.y;
+ glUniform2f(location, values[0].real, values[1].real);
} break;
case ShaderLanguage::TYPE_VEC3: {
- if (value.second.size() < 3)
- value.second.resize(3);
- Vector3 val = V->get();
- value.second.write[0].real = val.x;
- value.second.write[1].real = val.y;
- value.second.write[2].real = val.z;
+ glUniform3f(location, values[0].real, values[1].real, values[2].real);
} break;
case ShaderLanguage::TYPE_VEC4: {
- if (value.second.size() < 4)
- value.second.resize(4);
- if (V->get().get_type() == Variant::PLANE) {
- Plane val = V->get();
- value.second.write[0].real = val.normal.x;
- value.second.write[1].real = val.normal.y;
- value.second.write[2].real = val.normal.z;
- value.second.write[3].real = val.d;
- } else {
- Color val = V->get();
- value.second.write[0].real = val.r;
- value.second.write[1].real = val.g;
- value.second.write[2].real = val.b;
- value.second.write[3].real = val.a;
- }
-
+ glUniform4f(location, values[0].real, values[1].real, values[2].real, values[3].real);
} break;
case ShaderLanguage::TYPE_MAT2: {
- Transform2D val = V->get();
+ GLfloat mat[4];
- if (value.second.size() < 4) {
- value.second.resize(4);
+ for (int i = 0; i < 4; i++) {
+ mat[i] = values[i].real;
}
- value.second.write[0].real = val.elements[0][0];
- value.second.write[1].real = val.elements[0][1];
- value.second.write[2].real = val.elements[1][0];
- value.second.write[3].real = val.elements[1][1];
-
+ glUniformMatrix2fv(location, 1, GL_FALSE, mat);
} break;
case ShaderLanguage::TYPE_MAT3: {
- Basis val = V->get();
+ GLfloat mat[9];
- if (value.second.size() < 9) {
- value.second.resize(9);
+ for (int i = 0; i < 9; i++) {
+ mat[i] = values[i].real;
}
- value.second.write[0].real = val.elements[0][0];
- value.second.write[1].real = val.elements[0][1];
- value.second.write[2].real = val.elements[0][2];
- value.second.write[3].real = val.elements[1][0];
- value.second.write[4].real = val.elements[1][1];
- value.second.write[5].real = val.elements[1][2];
- value.second.write[6].real = val.elements[2][0];
- value.second.write[7].real = val.elements[2][1];
- value.second.write[8].real = val.elements[2][2];
+ glUniformMatrix3fv(location, 1, GL_FALSE, mat);
+
} break;
case ShaderLanguage::TYPE_MAT4: {
- Transform val = V->get();
+ GLfloat mat[16];
- if (value.second.size() < 16) {
- value.second.resize(16);
+ for (int i = 0; i < 16; i++) {
+ mat[i] = values[i].real;
}
- value.second.write[0].real = val.basis.elements[0][0];
- value.second.write[1].real = val.basis.elements[0][1];
- value.second.write[2].real = val.basis.elements[0][2];
- value.second.write[3].real = 0;
- value.second.write[4].real = val.basis.elements[1][0];
- value.second.write[5].real = val.basis.elements[1][1];
- value.second.write[6].real = val.basis.elements[1][2];
- value.second.write[7].real = 0;
- value.second.write[8].real = val.basis.elements[2][0];
- value.second.write[9].real = val.basis.elements[2][1];
- value.second.write[10].real = val.basis.elements[2][2];
- value.second.write[11].real = 0;
- value.second.write[12].real = val.origin[0];
- value.second.write[13].real = val.origin[1];
- value.second.write[14].real = val.origin[2];
- value.second.write[15].real = 1;
+ glUniformMatrix4fv(location, 1, GL_FALSE, mat);
+
} break;
- default: {
+ case ShaderLanguage::TYPE_SAMPLER2D: {
} break;
- }
- } else {
- if (value.second.size() == 0) {
- // No default value set... weird, let's just use zero for everything
- size_t default_arg_size = 1;
- bool is_float = false;
- switch (E->get().type) {
- case ShaderLanguage::TYPE_BOOL:
- case ShaderLanguage::TYPE_INT:
- case ShaderLanguage::TYPE_UINT: {
- default_arg_size = 1;
- } break;
-
- case ShaderLanguage::TYPE_FLOAT: {
- default_arg_size = 1;
- is_float = true;
- } break;
-
- case ShaderLanguage::TYPE_BVEC2:
- case ShaderLanguage::TYPE_IVEC2:
- case ShaderLanguage::TYPE_UVEC2: {
- default_arg_size = 2;
- } break;
-
- case ShaderLanguage::TYPE_VEC2: {
- default_arg_size = 2;
- is_float = true;
- } break;
-
- case ShaderLanguage::TYPE_BVEC3:
- case ShaderLanguage::TYPE_IVEC3:
- case ShaderLanguage::TYPE_UVEC3: {
- default_arg_size = 3;
- } break;
-
- case ShaderLanguage::TYPE_VEC3: {
- default_arg_size = 3;
- is_float = true;
- } break;
-
- case ShaderLanguage::TYPE_BVEC4:
- case ShaderLanguage::TYPE_IVEC4:
- case ShaderLanguage::TYPE_UVEC4: {
- default_arg_size = 4;
- } break;
-
- case ShaderLanguage::TYPE_VEC4: {
- default_arg_size = 4;
- is_float = true;
- } break;
-
- default: {
- // TODO matricies and all that stuff
- default_arg_size = 1;
- } break;
- }
-
- value.second.resize(default_arg_size);
-
- for (size_t i = 0; i < default_arg_size; i++) {
- if (is_float) {
- value.second.write[i].real = 0.0;
- } else {
- value.second.write[i].uint = 0;
- }
- }
- }
- }
- GLint location;
- if (v->custom_uniform_locations.has(E->key())) {
- location = v->custom_uniform_locations[E->key()];
- } else {
- int idx = v->uniform_names.find(E->key()); // TODO maybe put those in a Map?
- if (idx < 0) {
- location = -1;
- } else {
- location = v->uniform_location[idx];
- }
- }
+ case ShaderLanguage::TYPE_ISAMPLER2D: {
- _set_uniform_value(location, value);
- }
+ } break;
- // bind textures
- int tc = material->textures.size();
- Pair<StringName, RID> *textures = material->textures.ptrw();
+ case ShaderLanguage::TYPE_USAMPLER2D: {
- for (int i = 0; i < tc; i++) {
+ } break;
- Pair<ShaderLanguage::DataType, Vector<ShaderLanguage::ConstantNode::Value> > value;
- value.first = ShaderLanguage::TYPE_INT;
- value.second.resize(1);
- value.second.write[0].sint = i;
+ case ShaderLanguage::TYPE_SAMPLERCUBE: {
- // GLint location = get_uniform_location(textures[i].first);
+ } break;
- // if (location < 0) {
- // location = material->shader->uniform_locations[textures[i].first];
- // }
- GLint location = -1;
- if (v->custom_uniform_locations.has(textures[i].first)) {
- location = v->custom_uniform_locations[textures[i].first];
- } else {
- location = get_uniform_location(textures[i].first);
- }
+ case ShaderLanguage::TYPE_SAMPLER2DARRAY:
+ case ShaderLanguage::TYPE_ISAMPLER2DARRAY:
+ case ShaderLanguage::TYPE_USAMPLER2DARRAY:
+ case ShaderLanguage::TYPE_SAMPLER3D:
+ case ShaderLanguage::TYPE_ISAMPLER3D:
+ case ShaderLanguage::TYPE_USAMPLER3D: {
+ // Not implemented in GLES2
+ } break;
- _set_uniform_value(location, value);
+ case ShaderLanguage::TYPE_VOID: {
+ // Nothing to do?
+ } break;
+ default: {
+ ERR_PRINT("type missing, bug?");
+ } break;
+ }
+ }
}
}
-void ShaderGLES2::set_base_material_tex_index(int p_idx) {
-}
-
ShaderGLES2::ShaderGLES2() {
version = NULL;
last_custom_code = 1;
diff --git a/drivers/gles2/shader_gles2.h b/drivers/gles2/shader_gles2.h
index d493880d0b..ebea40e10e 100644
--- a/drivers/gles2/shader_gles2.h
+++ b/drivers/gles2/shader_gles2.h
@@ -1,4 +1,4 @@
-/*************************************************************************/
+/*************************************************************************/
/* shader_gles2.h */
/*************************************************************************/
/* This file is part of: */
@@ -112,7 +112,6 @@ private:
GLuint id;
GLuint vert_id;
GLuint frag_id;
- Vector<StringName> uniform_names;
GLint *uniform_location;
Vector<GLint> texture_uniform_locations;
Map<StringName, GLint> custom_uniform_locations;
@@ -177,9 +176,6 @@ private:
int max_image_units;
- Map<uint32_t, Variant> uniform_defaults;
- Map<uint32_t, CameraMatrix> uniform_cameras;
-
Map<StringName, Pair<ShaderLanguage::DataType, Vector<ShaderLanguage::ConstantNode::Value> > > uniform_values;
protected:
@@ -212,246 +208,11 @@ public:
static _FORCE_INLINE_ ShaderGLES2 *get_active() { return active; }
bool bind();
void unbind();
- void bind_uniforms();
inline GLuint get_program() const { return version ? version->id : 0; }
void clear_caches();
- _FORCE_INLINE_ void _set_uniform_value(GLint p_uniform, const Pair<ShaderLanguage::DataType, Vector<ShaderLanguage::ConstantNode::Value> > &value) {
- if (p_uniform < 0)
- return;
-
- const Vector<ShaderLanguage::ConstantNode::Value> &values = value.second;
-
- switch (value.first) {
- case ShaderLanguage::TYPE_BOOL: {
- glUniform1i(p_uniform, values[0].boolean);
- } break;
-
- case ShaderLanguage::TYPE_BVEC2: {
- glUniform2i(p_uniform, values[0].boolean, values[1].boolean);
- } break;
-
- case ShaderLanguage::TYPE_BVEC3: {
- glUniform3i(p_uniform, values[0].boolean, values[1].boolean, values[2].boolean);
- } break;
-
- case ShaderLanguage::TYPE_BVEC4: {
- glUniform4i(p_uniform, values[0].boolean, values[1].boolean, values[2].boolean, values[3].boolean);
- } break;
-
- case ShaderLanguage::TYPE_INT: {
- glUniform1i(p_uniform, values[0].sint);
- } break;
-
- case ShaderLanguage::TYPE_IVEC2: {
- glUniform2i(p_uniform, values[0].sint, values[1].sint);
- } break;
-
- case ShaderLanguage::TYPE_IVEC3: {
- glUniform3i(p_uniform, values[0].sint, values[1].sint, values[2].sint);
- } break;
-
- case ShaderLanguage::TYPE_IVEC4: {
- glUniform4i(p_uniform, values[0].sint, values[1].sint, values[2].sint, values[3].sint);
- } break;
-
- case ShaderLanguage::TYPE_UINT: {
- glUniform1i(p_uniform, values[0].uint);
- } break;
-
- case ShaderLanguage::TYPE_UVEC2: {
- glUniform2i(p_uniform, values[0].uint, values[1].uint);
- } break;
-
- case ShaderLanguage::TYPE_UVEC3: {
- glUniform3i(p_uniform, values[0].uint, values[1].uint, values[2].uint);
- } break;
-
- case ShaderLanguage::TYPE_UVEC4: {
- glUniform4i(p_uniform, values[0].uint, values[1].uint, values[2].uint, values[3].uint);
- } break;
-
- case ShaderLanguage::TYPE_FLOAT: {
- glUniform1f(p_uniform, values[0].real);
- } break;
-
- case ShaderLanguage::TYPE_VEC2: {
- glUniform2f(p_uniform, values[0].real, values[1].real);
- } break;
-
- case ShaderLanguage::TYPE_VEC3: {
- glUniform3f(p_uniform, values[0].real, values[1].real, values[2].real);
- } break;
-
- case ShaderLanguage::TYPE_VEC4: {
- glUniform4f(p_uniform, values[0].real, values[1].real, values[2].real, values[3].real);
- } break;
-
- case ShaderLanguage::TYPE_MAT2: {
- GLfloat mat[4];
-
- for (int i = 0; i < 4; i++) {
- mat[i] = values[i].real;
- }
-
- glUniformMatrix2fv(p_uniform, 1, GL_FALSE, mat);
- } break;
-
- case ShaderLanguage::TYPE_MAT3: {
- GLfloat mat[9];
-
- for (int i = 0; i < 9; i++) {
- mat[i] = values[i].real;
- }
-
- glUniformMatrix3fv(p_uniform, 1, GL_FALSE, mat);
-
- } break;
-
- case ShaderLanguage::TYPE_MAT4: {
- GLfloat mat[16];
-
- for (int i = 0; i < 16; i++) {
- mat[i] = values[i].real;
- }
-
- glUniformMatrix4fv(p_uniform, 1, GL_FALSE, mat);
-
- } break;
-
- case ShaderLanguage::TYPE_SAMPLER2D: {
-
- } break;
-
- case ShaderLanguage::TYPE_ISAMPLER2D: {
-
- } break;
-
- case ShaderLanguage::TYPE_USAMPLER2D: {
-
- } break;
-
- case ShaderLanguage::TYPE_SAMPLERCUBE: {
-
- } break;
-
- case ShaderLanguage::TYPE_SAMPLER2DARRAY:
- case ShaderLanguage::TYPE_ISAMPLER2DARRAY:
- case ShaderLanguage::TYPE_USAMPLER2DARRAY:
- case ShaderLanguage::TYPE_SAMPLER3D:
- case ShaderLanguage::TYPE_ISAMPLER3D:
- case ShaderLanguage::TYPE_USAMPLER3D: {
- // Not implemented in GLES2
- } break;
-
- case ShaderLanguage::TYPE_VOID: {
- // Nothing to do?
- } break;
- }
- }
-
- _FORCE_INLINE_ void _set_uniform_variant(GLint p_uniform, const Variant &p_value) {
-
- if (p_uniform < 0)
- return; // do none
- switch (p_value.get_type()) {
-
- case Variant::BOOL:
- case Variant::INT: {
-
- int val = p_value;
- glUniform1i(p_uniform, val);
- } break;
- case Variant::REAL: {
-
- real_t val = p_value;
- glUniform1f(p_uniform, val);
- } break;
- case Variant::COLOR: {
-
- Color val = p_value;
- glUniform4f(p_uniform, val.r, val.g, val.b, val.a);
- } break;
- case Variant::VECTOR2: {
-
- Vector2 val = p_value;
- glUniform2f(p_uniform, val.x, val.y);
- } break;
- case Variant::VECTOR3: {
-
- Vector3 val = p_value;
- glUniform3f(p_uniform, val.x, val.y, val.z);
- } break;
- case Variant::PLANE: {
-
- Plane val = p_value;
- glUniform4f(p_uniform, val.normal.x, val.normal.y, val.normal.z, val.d);
- } break;
- case Variant::QUAT: {
-
- Quat val = p_value;
- glUniform4f(p_uniform, val.x, val.y, val.z, val.w);
- } break;
-
- case Variant::TRANSFORM2D: {
-
- Transform2D tr = p_value;
- GLfloat matrix[16] = { /* build a 16x16 matrix */
- tr.elements[0][0],
- tr.elements[0][1],
- 0,
- 0,
- tr.elements[1][0],
- tr.elements[1][1],
- 0,
- 0,
- 0,
- 0,
- 1,
- 0,
- tr.elements[2][0],
- tr.elements[2][1],
- 0,
- 1
- };
-
- glUniformMatrix4fv(p_uniform, 1, false, matrix);
-
- } break;
- case Variant::BASIS:
- case Variant::TRANSFORM: {
-
- Transform tr = p_value;
- GLfloat matrix[16] = { /* build a 16x16 matrix */
- tr.basis.elements[0][0],
- tr.basis.elements[1][0],
- tr.basis.elements[2][0],
- 0,
- tr.basis.elements[0][1],
- tr.basis.elements[1][1],
- tr.basis.elements[2][1],
- 0,
- tr.basis.elements[0][2],
- tr.basis.elements[1][2],
- tr.basis.elements[2][2],
- 0,
- tr.origin.x,
- tr.origin.y,
- tr.origin.z,
- 1
- };
-
- glUniformMatrix4fv(p_uniform, 1, false, matrix);
- } break;
- case Variant::OBJECT: {
-
- } break;
- default: { ERR_FAIL(); } // do nothing
- }
- }
-
uint32_t create_custom_shader();
void set_custom_shader_code(uint32_t p_code_id,
const String &p_vertex,
@@ -468,18 +229,6 @@ public:
uint32_t get_version_key() const { return conditional_version.version; }
- void set_uniform_default(int p_idx, const Variant &p_value) {
-
- if (p_value.get_type() == Variant::NIL) {
-
- uniform_defaults.erase(p_idx);
- } else {
-
- uniform_defaults[p_idx] = p_value;
- }
- uniforms_dirty = true;
- }
-
// this void* is actually a RasterizerStorageGLES2::Material, but C++ doesn't
// like forward declared nested classes.
void use_material(void *p_material);
@@ -487,31 +236,9 @@ public:
_FORCE_INLINE_ uint32_t get_version() const { return new_conditional_version.version; }
_FORCE_INLINE_ bool is_version_valid() const { return version && version->ok; }
- void set_uniform_camera(int p_idx, const CameraMatrix &p_mat) {
-
- uniform_cameras[p_idx] = p_mat;
- uniforms_dirty = true;
- }
-
- _FORCE_INLINE_ void set_texture_uniform(int p_idx, const Variant &p_value) {
-
- ERR_FAIL_COND(!version);
- ERR_FAIL_INDEX(p_idx, version->texture_uniform_locations.size());
- _set_uniform_variant(version->texture_uniform_locations[p_idx], p_value);
- }
-
- _FORCE_INLINE_ GLint get_texture_uniform_location(int p_idx) {
-
- ERR_FAIL_COND_V(!version, -1);
- ERR_FAIL_INDEX_V(p_idx, version->texture_uniform_locations.size(), -1);
- return version->texture_uniform_locations[p_idx];
- }
-
virtual void init() = 0;
void finish();
- void set_base_material_tex_index(int p_idx);
-
void add_custom_define(const String &p_define) {
custom_defines.push_back(p_define.utf8());
}
diff --git a/drivers/gles2/shaders/canvas.glsl b/drivers/gles2/shaders/canvas.glsl
index e74c7d7166..b13801946f 100644
--- a/drivers/gles2/shaders/canvas.glsl
+++ b/drivers/gles2/shaders/canvas.glsl
@@ -107,6 +107,7 @@ vec2 select(vec2 a, vec2 b, bvec2 c) {
void main() {
vec4 color = color_attrib;
+ vec2 uv;
#ifdef USE_INSTANCING
mat4 extra_matrix_instance = extra_matrix * transpose(mat4(instance_xform0, instance_xform1, instance_xform2, vec4(0.0, 0.0, 0.0, 1.0)));
@@ -121,9 +122,9 @@ void main() {
#ifdef USE_TEXTURE_RECT
if (dst_rect.z < 0.0) { // Transpose is encoded as negative dst_rect.z
- uv_interp = src_rect.xy + abs(src_rect.zw) * vertex.yx;
+ uv = src_rect.xy + abs(src_rect.zw) * vertex.yx;
} else {
- uv_interp = src_rect.xy + abs(src_rect.zw) * vertex;
+ uv = src_rect.xy + abs(src_rect.zw) * vertex;
}
vec4 outvec = vec4(0.0, 0.0, 0.0, 1.0);
@@ -140,7 +141,7 @@ void main() {
#else
vec4 outvec = vec4(vertex.xy, 0.0, 1.0);
- uv_interp = uv_attrib;
+ uv = uv_attrib;
#endif
{
@@ -189,6 +190,7 @@ VERTEX_SHADER_CODE
#endif
+ uv_interp = uv;
gl_Position = projection_matrix * outvec;
#ifdef USE_LIGHTING
@@ -345,10 +347,14 @@ void main() {
vec4 color = color_interp;
vec2 uv = uv_interp;
+#ifdef USE_FORCE_REPEAT
+ //needs to use this to workaround GLES2/WebGL1 forcing tiling that textures that dont support it
+ uv = mod(uv, vec2(1.0, 1.0));
+#endif
#if !defined(COLOR_USED)
//default behavior, texture by color
- color *= texture2D(color_texture, uv_interp);
+ color *= texture2D(color_texture, uv);
#endif
#ifdef SCREEN_UV_USED
@@ -365,7 +371,7 @@ void main() {
#endif
if (use_default_normal) {
- normal.xy = texture2D(normal_texture, uv_interp).xy * 2.0 - 1.0;
+ normal.xy = texture2D(normal_texture, uv).xy * 2.0 - 1.0;
normal.z = sqrt(1.0 - dot(normal.xy, normal.xy));
normal_used = true;
} else {
@@ -480,7 +486,7 @@ FRAGMENT_SHADER_CODE
#ifdef USE_RGBA_SHADOWS
-#define SHADOW_DEPTH(m_tex, m_uv) dot(texture2D((m_tex), (m_uv)), vec4(1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1))
+#define SHADOW_DEPTH(m_tex, m_uv) dot(texture2D((m_tex), (m_uv)), vec4(1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1.0))
#else
diff --git a/drivers/gles2/shaders/canvas_shadow.glsl b/drivers/gles2/shaders/canvas_shadow.glsl
index d39212826e..01b2c59325 100644
--- a/drivers/gles2/shaders/canvas_shadow.glsl
+++ b/drivers/gles2/shaders/canvas_shadow.glsl
@@ -48,7 +48,7 @@ void main() {
#ifdef USE_RGBA_SHADOWS
highp vec4 comp = fract(depth * vec4(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0));
- comp -= comp.xxyz * vec4(0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0);
+ comp -= comp.xxyz * vec4(0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0);
gl_FragColor = comp;
#else
diff --git a/drivers/gles2/shaders/cubemap_filter.glsl b/drivers/gles2/shaders/cubemap_filter.glsl
index 7643297a14..a6902836ed 100644
--- a/drivers/gles2/shaders/cubemap_filter.glsl
+++ b/drivers/gles2/shaders/cubemap_filter.glsl
@@ -187,6 +187,18 @@ void main() {
vec2 uv = (uv_interp * 2.0) - 1.0;
vec3 N = texelCoordToVec(uv, face_id);
+#ifdef USE_DIRECT_WRITE
+
+#ifdef USE_SOURCE_PANORAMA
+
+ gl_FragColor = vec4(texturePanorama(source_panorama, N).rgb, 1.0);
+#else
+
+ gl_FragColor = vec4(textureCube(source_cube, N).rgb, 1.0);
+#endif //USE_SOURCE_PANORAMA
+
+#else
+
vec4 sum = vec4(0.0);
for (int sample_num = 0; sample_num < SAMPLE_COUNT; sample_num++) {
@@ -221,4 +233,5 @@ void main() {
sum.rgb = mix((vec3(1.0) + a) * pow(sum.rgb, vec3(1.0 / 2.4)) - a, 12.92 * sum.rgb, vec3(lessThan(sum.rgb, vec3(0.0031308))));
gl_FragColor = vec4(sum.rgb, 1.0);
+#endif
}
diff --git a/drivers/gles2/shaders/scene.glsl b/drivers/gles2/shaders/scene.glsl
index 6f6f827d60..371ea8498a 100644
--- a/drivers/gles2/shaders/scene.glsl
+++ b/drivers/gles2/shaders/scene.glsl
@@ -96,6 +96,10 @@ uniform float light_normal_bias;
// varyings
//
+#if defined(RENDER_DEPTH) && defined(USE_RGBA_SHADOWS)
+varying highp vec4 position_interp;
+#endif
+
varying highp vec3 vertex_interp;
varying vec3 normal_interp;
@@ -355,7 +359,7 @@ void main() {
uv2_interp = uv2_attrib;
#endif
-#ifdef OVERRIDE_POSITION
+#if defined(OVERRIDE_POSITION)
highp vec4 position;
#endif
@@ -647,11 +651,15 @@ VERTEX_SHADER_CODE
#endif //use vertex lighting
-#ifdef OVERRIDE_POSITION
+#if defined(OVERRIDE_POSITION)
gl_Position = position;
#else
gl_Position = projection_matrix * vec4(vertex_interp, 1.0);
#endif
+
+#if defined(RENDER_DEPTH) && defined(USE_RGBA_SHADOWS)
+ position_interp = gl_Position;
+#endif
}
/* clang-format off */
@@ -724,6 +732,9 @@ uniform vec2 screen_pixel_size;
#if defined(SCREEN_TEXTURE_USED)
uniform highp sampler2D screen_texture; //texunit:-4
#endif
+#if defined(DEPTH_TEXTURE_USED)
+uniform highp sampler2D depth_texture; //texunit:-4
+#endif
#ifdef USE_REFLECTION_PROBE1
@@ -901,6 +912,8 @@ uniform float ambient_energy;
#ifdef USE_LIGHTING
+uniform highp vec4 shadow_color;
+
#ifdef USE_VERTEX_LIGHTING
//get from vertex
@@ -913,7 +926,7 @@ uniform highp vec3 light_direction; //may be used by fog, so leave here
//done in fragment
// general for all lights
uniform highp vec4 light_color;
-uniform highp vec4 shadow_color;
+
uniform highp float light_specular;
// directional
@@ -970,6 +983,10 @@ uniform vec4 light_clamp;
// varyings
//
+#if defined(RENDER_DEPTH) && defined(USE_RGBA_SHADOWS)
+varying highp vec4 position_interp;
+#endif
+
varying highp vec3 vertex_interp;
varying vec3 normal_interp;
@@ -1330,8 +1347,18 @@ LIGHT_SHADER_CODE
#ifdef USE_SHADOW
-#define SAMPLE_SHADOW_TEXEL(p_shadow, p_pos, p_depth) step(p_depth, texture2D(p_shadow, p_pos).r)
-#define SAMPLE_SHADOW_TEXEL_PROJ(p_shadow, p_pos) step(p_pos.z, texture2DProj(p_shadow, p_pos).r)
+#ifdef USE_RGBA_SHADOWS
+
+#define SHADOW_DEPTH(m_val) dot(m_val, vec4(1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1.0))
+
+#else
+
+#define SHADOW_DEPTH(m_val) (m_val).r
+
+#endif
+
+#define SAMPLE_SHADOW_TEXEL(p_shadow, p_pos, p_depth) step(p_depth, SHADOW_DEPTH(texture2D(p_shadow, p_pos)))
+#define SAMPLE_SHADOW_TEXEL_PROJ(p_shadow, p_pos) step(p_pos.z, SHADOW_DEPTH(texture2DProj(p_shadow, p_pos)))
float sample_shadow(highp sampler2D shadow, highp vec4 spos) {
@@ -1593,14 +1620,14 @@ FRAGMENT_SHADER_CODE
#ifdef USE_LIGHTMAP_CAPTURE
{
vec3 cone_dirs[12] = vec3[](
- vec3(0, 0, 1),
- vec3(0.866025, 0, 0.5),
+ vec3(0.0, 0.0, 1.0),
+ vec3(0.866025, 0.0, 0.5),
vec3(0.267617, 0.823639, 0.5),
vec3(-0.700629, 0.509037, 0.5),
vec3(-0.700629, -0.509037, 0.5),
vec3(0.267617, -0.823639, 0.5),
- vec3(0, 0, -1),
- vec3(0.866025, 0, -0.5),
+ vec3(0.0, 0.0, -1.0),
+ vec3(0.866025, 0.0, -0.5),
vec3(0.267617, 0.823639, -0.5),
vec3(-0.700629, 0.509037, -0.5),
vec3(-0.700629, -0.509037, -0.5),
@@ -1807,7 +1834,7 @@ FRAGMENT_SHADER_CODE
#if !defined(LIGHT_USE_PSSM4) && !defined(LIGHT_USE_PSSM2)
- light_att *= sample_shadow(light_directional_shadow, shadow_coord);
+ light_att *= mix(shadow_color.rgb, vec3(1.0), sample_shadow(light_directional_shadow, shadow_coord));
#endif //orthogonal
#else //fragment version of pssm
@@ -2057,7 +2084,6 @@ FRAGMENT_SHADER_CODE
gl_FragColor.rgb *= (1.0 - fog_interp.a);
#endif // BASE_PASS
-
#else //pixel based fog
float fog_amount = 0.0;
@@ -2101,5 +2127,15 @@ FRAGMENT_SHADER_CODE
#endif // defined(FOG_DEPTH_ENABLED) || defined(FOG_HEIGHT_ENABLED)
-#endif // not RENDER_DEPTH
+#else // not RENDER_DEPTH
+//depth render
+#ifdef USE_RGBA_SHADOWS
+
+ highp float depth = ((position_interp.z / position_interp.w) + 1.0) * 0.5 + 0.0; // bias
+ highp vec4 comp = fract(depth * vec4(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0));
+ comp -= comp.xxyz * vec4(0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0);
+ gl_FragColor = comp;
+
+#endif
+#endif
}
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index dee01db4a5..e645e39f3f 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -2349,7 +2349,7 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G
if (p_depth_pass) {
- if (has_blend_alpha || p_material->shader->spatial.uses_depth_texture || (has_base_alpha && p_material->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS))
+ if (has_blend_alpha || p_material->shader->spatial.uses_depth_texture || (has_base_alpha && p_material->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) || p_material->shader->spatial.depth_draw_mode == RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_NEVER || p_material->shader->spatial.no_depth_test)
return; //bye
if (!p_material->shader->spatial.uses_alpha_scissor && !p_material->shader->spatial.writes_modelview_or_projection && !p_material->shader->spatial.uses_vertex && !p_material->shader->spatial.uses_discard && p_material->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) {
@@ -5053,7 +5053,7 @@ void RasterizerSceneGLES3::initialize() {
state.scene_shader.add_custom_define("#define MAX_LIGHT_DATA_STRUCTS " + itos(state.max_ubo_lights) + "\n");
state.scene_shader.add_custom_define("#define MAX_FORWARD_LIGHTS " + itos(state.max_forward_lights_per_object) + "\n");
- state.max_ubo_reflections = MIN(RenderList::MAX_REFLECTIONS, max_ubo_size / sizeof(ReflectionProbeDataUBO));
+ state.max_ubo_reflections = MIN((int)RenderList::MAX_REFLECTIONS, max_ubo_size / sizeof(ReflectionProbeDataUBO));
state.reflection_array_tmp = (uint8_t *)memalloc(sizeof(ReflectionProbeDataUBO) * state.max_ubo_reflections);
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index 5189017437..ccd5fff99f 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -3620,7 +3620,7 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh, uint32_t p_format, VS:
}
mesh->surfaces.push_back(surface);
- mesh->instance_change_notify(true, false);
+ mesh->instance_change_notify(true, true);
info.vertex_mem += surface->total_data_size;
}
@@ -5522,6 +5522,7 @@ void RasterizerStorageGLES3::reflection_probe_set_as_interior(RID p_probe, bool
ERR_FAIL_COND(!reflection_probe);
reflection_probe->interior = p_enable;
+ reflection_probe->instance_change_notify(true, false);
}
void RasterizerStorageGLES3::reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) {
diff --git a/drivers/gles3/shader_gles3.cpp b/drivers/gles3/shader_gles3.cpp
index 2db0223edd..fa7cc00230 100644
--- a/drivers/gles3/shader_gles3.cpp
+++ b/drivers/gles3/shader_gles3.cpp
@@ -133,15 +133,6 @@ bool ShaderGLES3::bind() {
active = this;
uniforms_dirty = true;
- /*
- * why on earth is this code here?
- for (int i=0;i<texunit_pair_count;i++) {
-
- glUniform1i(texunit_pairs[i].location, texunit_pairs[i].index);
- DEBUG_TEST_ERROR("Uniform 1 i");
- }
-
-*/
return true;
}
diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl
index 88368516c1..6c1806a657 100644
--- a/drivers/gles3/shaders/canvas.glsl
+++ b/drivers/gles3/shaders/canvas.glsl
@@ -495,7 +495,7 @@ FRAGMENT_SHADER_CODE
#endif
}
#ifdef DEBUG_ENCODED_32
- highp float enc32 = dot(color, highp vec4(1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1));
+ highp float enc32 = dot(color, highp vec4(1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1.0));
color = vec4(vec3(enc32), 1.0);
#endif
@@ -589,7 +589,7 @@ FRAGMENT_SHADER_CODE
#ifdef USE_RGBA_SHADOWS
-#define SHADOW_DEPTH(m_tex, m_uv) dot(texture((m_tex), (m_uv)), vec4(1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1))
+#define SHADOW_DEPTH(m_tex, m_uv) dot(texture((m_tex), (m_uv)), vec4(1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1.0))
#else
diff --git a/drivers/gles3/shaders/canvas_shadow.glsl b/drivers/gles3/shaders/canvas_shadow.glsl
index 68d0713385..13fff7f4d1 100644
--- a/drivers/gles3/shaders/canvas_shadow.glsl
+++ b/drivers/gles3/shaders/canvas_shadow.glsl
@@ -36,7 +36,7 @@ void main() {
#ifdef USE_RGBA_SHADOWS
highp vec4 comp = fract(depth * vec4(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0));
- comp -= comp.xxyz * vec4(0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0);
+ comp -= comp.xxyz * vec4(0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0);
distance_buf = comp;
#else
diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index 1a8ad5e1ef..3b06b08dec 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -44,7 +44,7 @@ layout(location = 5) in vec2 uv2_attrib;
#ifdef USE_SKELETON
layout(location = 6) in uvec4 bone_indices; // attrib:6
-layout(location = 7) in vec4 bone_weights; // attrib:7
+layout(location = 7) in highp vec4 bone_weights; // attrib:7
#endif
#ifdef USE_INSTANCING
@@ -314,7 +314,7 @@ void main() {
highp vec4 vertex = vertex_attrib; // vec4(vertex_attrib.xyz * data_attrib.x,1.0);
- mat4 world_matrix = world_transform;
+ highp mat4 world_matrix = world_transform;
#ifdef USE_INSTANCING
@@ -395,44 +395,46 @@ void main() {
ivec4 bone_indicesi = ivec4(bone_indices); // cast to signed int
ivec2 tex_ofs = ivec2(bone_indicesi.x % 256, (bone_indicesi.x / 256) * 3);
- highp mat3x4 m;
- m = mat3x4(
+ highp mat4 m;
+ m = mat4(
texelFetch(skeleton_texture, tex_ofs, 0),
texelFetch(skeleton_texture, tex_ofs + ivec2(0, 1), 0),
- texelFetch(skeleton_texture, tex_ofs + ivec2(0, 2), 0)) *
+ texelFetch(skeleton_texture, tex_ofs + ivec2(0, 2), 0),
+ vec4(0.0, 0.0, 0.0, 1.0)) *
bone_weights.x;
tex_ofs = ivec2(bone_indicesi.y % 256, (bone_indicesi.y / 256) * 3);
- m += mat3x4(
+ m += mat4(
texelFetch(skeleton_texture, tex_ofs, 0),
texelFetch(skeleton_texture, tex_ofs + ivec2(0, 1), 0),
- texelFetch(skeleton_texture, tex_ofs + ivec2(0, 2), 0)) *
+ texelFetch(skeleton_texture, tex_ofs + ivec2(0, 2), 0),
+ vec4(0.0, 0.0, 0.0, 1.0)) *
bone_weights.y;
tex_ofs = ivec2(bone_indicesi.z % 256, (bone_indicesi.z / 256) * 3);
- m += mat3x4(
+ m += mat4(
texelFetch(skeleton_texture, tex_ofs, 0),
texelFetch(skeleton_texture, tex_ofs + ivec2(0, 1), 0),
- texelFetch(skeleton_texture, tex_ofs + ivec2(0, 2), 0)) *
+ texelFetch(skeleton_texture, tex_ofs + ivec2(0, 2), 0),
+ vec4(0.0, 0.0, 0.0, 1.0)) *
bone_weights.z;
tex_ofs = ivec2(bone_indicesi.w % 256, (bone_indicesi.w / 256) * 3);
- m += mat3x4(
+ m += mat4(
texelFetch(skeleton_texture, tex_ofs, 0),
texelFetch(skeleton_texture, tex_ofs + ivec2(0, 1), 0),
- texelFetch(skeleton_texture, tex_ofs + ivec2(0, 2), 0)) *
+ texelFetch(skeleton_texture, tex_ofs + ivec2(0, 2), 0),
+ vec4(0.0, 0.0, 0.0, 1.0)) *
bone_weights.w;
- mat4 bone_matrix = transpose(mat4(m[0], m[1], m[2], vec4(0.0, 0.0, 0.0, 1.0)));
-
- world_matrix = bone_matrix * world_matrix;
+ world_matrix = transpose(m) * world_matrix;
}
#endif
- mat4 modelview = camera_inverse_matrix * world_matrix;
+ highp mat4 modelview = camera_inverse_matrix * world_matrix;
{
/* clang-format off */
@@ -1519,8 +1521,8 @@ void gi_probe_compute(mediump sampler3D probe, mat4 probe_xform, vec3 bounds, ve
#define MAX_CONE_DIRS 6
vec3 cone_dirs[MAX_CONE_DIRS] = vec3[](
- vec3(0, 0, 1),
- vec3(0.866025, 0, 0.5),
+ vec3(0.0, 0.0, 1.0),
+ vec3(0.866025, 0.0, 0.5),
vec3(0.267617, 0.823639, 0.5),
vec3(-0.700629, 0.509037, 0.5),
vec3(-0.700629, -0.509037, 0.5),
@@ -1534,10 +1536,10 @@ void gi_probe_compute(mediump sampler3D probe, mat4 probe_xform, vec3 bounds, ve
#define MAX_CONE_DIRS 4
vec3 cone_dirs[MAX_CONE_DIRS] = vec3[](
- vec3(0.707107, 0, 0.707107),
- vec3(0, 0.707107, 0.707107),
- vec3(-0.707107, 0, 0.707107),
- vec3(0, -0.707107, 0.707107));
+ vec3(0.707107, 0.0, 0.707107),
+ vec3(0.0, 0.707107, 0.707107),
+ vec3(-0.707107, 0.0, 0.707107),
+ vec3(0.0, -0.707107, 0.707107));
float cone_weights[MAX_CONE_DIRS] = float[](0.25, 0.25, 0.25, 0.25);
float cone_angle_tan = 0.98269;
@@ -1573,7 +1575,7 @@ void gi_probes_compute(vec3 pos, vec3 normal, float roughness, inout vec3 out_sp
vec3 ref_vec = normalize(reflect(normalize(pos), normal));
//find arbitrary tangent and bitangent, then build a matrix
- vec3 v0 = abs(normal.z) < 0.999 ? vec3(0, 0, 1) : vec3(0, 1, 0);
+ vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0);
vec3 tangent = normalize(cross(v0, normal));
vec3 bitangent = normalize(cross(tangent, normal));
mat3 normal_mat = mat3(tangent, bitangent, normal);
@@ -1961,14 +1963,14 @@ FRAGMENT_SHADER_CODE
#ifdef USE_LIGHTMAP_CAPTURE
{
vec3 cone_dirs[12] = vec3[](
- vec3(0, 0, 1),
- vec3(0.866025, 0, 0.5),
+ vec3(0.0, 0.0, 1.0),
+ vec3(0.866025, 0.0, 0.5),
vec3(0.267617, 0.823639, 0.5),
vec3(-0.700629, 0.509037, 0.5),
vec3(-0.700629, -0.509037, 0.5),
vec3(0.267617, -0.823639, 0.5),
- vec3(0, 0, -1),
- vec3(0.866025, 0, -0.5),
+ vec3(0.0, 0.0, -1.0),
+ vec3(0.866025, 0.0, -0.5),
vec3(0.267617, 0.823639, -0.5),
vec3(-0.700629, 0.509037, -0.5),
vec3(-0.700629, -0.509037, -0.5),
diff --git a/drivers/gles3/shaders/screen_space_reflection.glsl b/drivers/gles3/shaders/screen_space_reflection.glsl
index 86546319a0..39f1ea6155 100644
--- a/drivers/gles3/shaders/screen_space_reflection.glsl
+++ b/drivers/gles3/shaders/screen_space_reflection.glsl
@@ -77,7 +77,7 @@ void main() {
return;
}
//ray_dir = normalize(view_dir - normal * dot(normal,view_dir) * 2.0);
- //ray_dir = normalize(vec3(1, 1, -1));
+ //ray_dir = normalize(vec3(1.0, 1.0, -1.0));
////////////////
diff --git a/drivers/unix/file_access_unix.cpp b/drivers/unix/file_access_unix.cpp
index 072ffd96e7..6e045817bc 100644
--- a/drivers/unix/file_access_unix.cpp
+++ b/drivers/unix/file_access_unix.cpp
@@ -246,7 +246,7 @@ void FileAccessUnix::store_8(uint8_t p_dest) {
void FileAccessUnix::store_buffer(const uint8_t *p_src, int p_length) {
ERR_FAIL_COND(!f);
- ERR_FAIL_COND(fwrite(p_src, 1, p_length, f) != p_length);
+ ERR_FAIL_COND((int)fwrite(p_src, 1, p_length, f) != p_length);
}
bool FileAccessUnix::file_exists(const String &p_path) {
diff --git a/drivers/unix/syslog_logger.h b/drivers/unix/syslog_logger.h
index 5cfe3964f6..49a34dacc3 100644
--- a/drivers/unix/syslog_logger.h
+++ b/drivers/unix/syslog_logger.h
@@ -37,7 +37,7 @@
class SyslogLogger : public Logger {
public:
- virtual void logv(const char *p_format, va_list p_list, bool p_err);
+ virtual void logv(const char *p_format, va_list p_list, bool p_err) _PRINTF_FORMAT_ATTRIBUTE_2_0;
virtual void print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type);
virtual ~SyslogLogger();
diff --git a/drivers/wasapi/audio_driver_wasapi.cpp b/drivers/wasapi/audio_driver_wasapi.cpp
index 38012f8f76..c97849ef07 100644
--- a/drivers/wasapi/audio_driver_wasapi.cpp
+++ b/drivers/wasapi/audio_driver_wasapi.cpp
@@ -238,6 +238,32 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_c
hr = p_device->audio_client->GetMixFormat(&pwfex);
ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);
+ print_verbose("WASAPI: wFormatTag = " + itos(pwfex->wFormatTag));
+ print_verbose("WASAPI: nChannels = " + itos(pwfex->nChannels));
+ print_verbose("WASAPI: nSamplesPerSec = " + itos(pwfex->nSamplesPerSec));
+ print_verbose("WASAPI: nAvgBytesPerSec = " + itos(pwfex->nAvgBytesPerSec));
+ print_verbose("WASAPI: nBlockAlign = " + itos(pwfex->nBlockAlign));
+ print_verbose("WASAPI: wBitsPerSample = " + itos(pwfex->wBitsPerSample));
+ print_verbose("WASAPI: cbSize = " + itos(pwfex->cbSize));
+
+ WAVEFORMATEX *closest = NULL;
+ hr = p_device->audio_client->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED, pwfex, &closest);
+ if (hr == S_FALSE) {
+ WARN_PRINT("WASAPI: Mix format is not supported by the Device");
+ if (closest) {
+ print_verbose("WASAPI: closest->wFormatTag = " + itos(closest->wFormatTag));
+ print_verbose("WASAPI: closest->nChannels = " + itos(closest->nChannels));
+ print_verbose("WASAPI: closest->nSamplesPerSec = " + itos(closest->nSamplesPerSec));
+ print_verbose("WASAPI: closest->nAvgBytesPerSec = " + itos(closest->nAvgBytesPerSec));
+ print_verbose("WASAPI: closest->nBlockAlign = " + itos(closest->nBlockAlign));
+ print_verbose("WASAPI: closest->wBitsPerSample = " + itos(closest->wBitsPerSample));
+ print_verbose("WASAPI: closest->cbSize = " + itos(closest->cbSize));
+
+ WARN_PRINT("WASAPI: Using closest match instead");
+ pwfex = closest;
+ }
+ }
+
// Since we're using WASAPI Shared Mode we can't control any of these, we just tag along
p_device->channels = pwfex->nChannels;
p_device->format_tag = pwfex->wFormatTag;
@@ -270,6 +296,7 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_c
}
hr = p_device->audio_client->Initialize(AUDCLNT_SHAREMODE_SHARED, streamflags, p_capture ? REFTIMES_PER_SEC : 0, 0, pwfex, NULL);
+ ERR_EXPLAIN("WASAPI: Initialize failed with error 0x" + String::num_uint64(hr, 16));
ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);
if (p_capture) {