summaryrefslogtreecommitdiff
path: root/drivers/gles2
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gles2')
-rw-r--r--drivers/gles2/rasterizer_canvas_gles2.cpp2
-rw-r--r--drivers/gles2/rasterizer_gles2.cpp7
-rw-r--r--drivers/gles2/rasterizer_scene_gles2.cpp78
-rw-r--r--drivers/gles2/rasterizer_scene_gles2.h33
-rw-r--r--drivers/gles2/rasterizer_storage_gles2.cpp72
-rw-r--r--drivers/gles2/rasterizer_storage_gles2.h48
-rw-r--r--drivers/gles2/shader_compiler_gles2.cpp7
-rw-r--r--drivers/gles2/shader_gles2.cpp14
-rw-r--r--drivers/gles2/shaders/canvas.glsl3
-rw-r--r--drivers/gles2/shaders/copy.glsl22
-rw-r--r--drivers/gles2/shaders/scene.glsl227
11 files changed, 419 insertions, 94 deletions
diff --git a/drivers/gles2/rasterizer_canvas_gles2.cpp b/drivers/gles2/rasterizer_canvas_gles2.cpp
index 18b5dd3483..9227c04e71 100644
--- a/drivers/gles2/rasterizer_canvas_gles2.cpp
+++ b/drivers/gles2/rasterizer_canvas_gles2.cpp
@@ -1111,6 +1111,7 @@ void RasterizerCanvasGLES2::initialize() {
// polygon buffer
{
uint32_t poly_size = GLOBAL_DEF("rendering/limits/buffers/canvas_polygon_buffer_size_kb", 128);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/buffers/canvas_polygon_buffer_size_kb", PropertyInfo(Variant::INT, "rendering/limits/buffers/canvas_polygon_buffer_size_kb", PROPERTY_HINT_RANGE, "0,256,1,or_greater"));
poly_size *= 1024;
poly_size = MAX(poly_size, (2 + 2 + 4) * 4 * sizeof(float));
glGenBuffers(1, &data.polygon_buffer);
@@ -1122,6 +1123,7 @@ void RasterizerCanvasGLES2::initialize() {
glBindBuffer(GL_ARRAY_BUFFER, 0);
uint32_t index_size = GLOBAL_DEF("rendering/limits/buffers/canvas_polygon_index_size_kb", 128);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/buffers/canvas_polygon_index_size_kb", PropertyInfo(Variant::INT, "rendering/limits/buffers/canvas_polygon_index_size_kb", PROPERTY_HINT_RANGE, "0,256,1,or_greater"));
index_size *= 1024; // kb
glGenBuffers(1, &data.polygon_index_buffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer);
diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp
index 5f4b5428e8..175587b1bb 100644
--- a/drivers/gles2/rasterizer_gles2.cpp
+++ b/drivers/gles2/rasterizer_gles2.cpp
@@ -74,6 +74,11 @@
#include <EGL/eglext.h>
#endif
+#if defined(MINGW_ENABLED) || defined(_MSC_VER)
+#define strcpy strcpy_s
+#endif
+
+#ifndef IPHONE_ENABLED
static void GLAPIENTRY _gl_debug_print(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const GLvoid *userParam) {
if (type == _EXT_DEBUG_TYPE_OTHER_ARB)
@@ -83,6 +88,7 @@ static void GLAPIENTRY _gl_debug_print(GLenum source, GLenum type, GLuint id, GL
return; //these are ultimately annoying, so removing for now
char debSource[256], debType[256], debSev[256];
+
if (source == _EXT_DEBUG_SOURCE_API_ARB)
strcpy(debSource, "OpenGL");
else if (source == _EXT_DEBUG_SOURCE_WINDOW_SYSTEM_ARB)
@@ -120,6 +126,7 @@ static void GLAPIENTRY _gl_debug_print(GLenum source, GLenum type, GLuint id, GL
ERR_PRINTS(output);
}
+#endif // IPHONE_ENABLED
typedef void (*DEBUGPROCARB)(GLenum source,
GLenum type,
diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp
index 15f1aa44be..91280d966a 100644
--- a/drivers/gles2/rasterizer_scene_gles2.cpp
+++ b/drivers/gles2/rasterizer_scene_gles2.cpp
@@ -742,20 +742,38 @@ void RasterizerSceneGLES2::environment_set_adjustment(RID p_env, bool p_enable,
}
void RasterizerSceneGLES2::environment_set_fog(RID p_env, bool p_enable, const Color &p_color, const Color &p_sun_color, float p_sun_amount) {
+
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
+
+ env->fog_enabled = p_enable;
+ env->fog_color = p_color;
+ env->fog_sun_color = p_sun_color;
+ env->fog_sun_amount = p_sun_amount;
}
void RasterizerSceneGLES2::environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_curve, bool p_transmit, float p_transmit_curve) {
+
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
+
+ env->fog_depth_enabled = p_enable;
+ env->fog_depth_begin = p_depth_begin;
+ env->fog_depth_curve = p_depth_curve;
+ env->fog_transmit_enabled = p_transmit;
+ env->fog_transmit_curve = p_transmit_curve;
}
void RasterizerSceneGLES2::environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve) {
+
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
-}
+ env->fog_height_enabled = p_enable;
+ env->fog_height_min = p_min_height;
+ env->fog_height_max = p_max_height;
+ env->fog_height_curve = p_height_curve;
+}
bool RasterizerSceneGLES2::is_environment(RID p_env) {
return environment_owner.owns(p_env);
}
@@ -1191,6 +1209,8 @@ bool RasterizerSceneGLES2::_setup_material(RasterizerStorageGLES2::Material *p_m
state.scene_shader.set_uniform(SceneShaderGLES2::SKELETON_TEXTURE_SIZE, p_skeleton_tex_size);
+ state.current_main_tex = 0;
+
for (int i = 0; i < tc; i++) {
glActiveTexture(GL_TEXTURE0 + i);
@@ -1221,6 +1241,9 @@ bool RasterizerSceneGLES2::_setup_material(RasterizerStorageGLES2::Material *p_m
t = t->get_ptr();
glBindTexture(t->target, t->tex_id);
+ if (i == 0) {
+ state.current_main_tex = t->tex_id;
+ }
}
state.scene_shader.use_material((void *)p_material);
@@ -2031,6 +2054,15 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
glDisable(GL_BLEND);
}
+ float fog_max_distance = 0;
+ bool using_fog = false;
+ if (p_env && !p_shadow && p_env->fog_enabled && (p_env->fog_depth_enabled || p_env->fog_height_enabled)) {
+ state.scene_shader.set_conditional(SceneShaderGLES2::FOG_DEPTH_ENABLED, p_env->fog_depth_enabled);
+ state.scene_shader.set_conditional(SceneShaderGLES2::FOG_HEIGHT_ENABLED, p_env->fog_height_enabled);
+ fog_max_distance = p_projection.get_z_far();
+ using_fog = true;
+ }
+
RasterizerStorageGLES2::Texture *prev_lightmap = NULL;
float lightmap_energy = 1.0;
bool prev_use_lightmap_capture = false;
@@ -2142,7 +2174,7 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
}
//condition to enable vertex lighting on this object
- bool vertex_lit = light && (material->shader->spatial.uses_vertex_lighting || storage->config.force_vertex_shading) && !unshaded;
+ bool vertex_lit = (material->shader->spatial.uses_vertex_lighting || storage->config.force_vertex_shading) && ((!unshaded && light) || using_fog); //fog forces vertex lighting because it still applies even if unshaded or no fog
if (vertex_lit != prev_vertex_lit) {
state.scene_shader.set_conditional(SceneShaderGLES2::USE_VERTEX_LIGHTING, vertex_lit);
@@ -2268,10 +2300,34 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
rebind_light = true;
rebind_reflection = true;
rebind_lightmap = true;
+
+ if (using_fog) {
+
+ state.scene_shader.set_uniform(SceneShaderGLES2::FOG_COLOR_BASE, p_env->fog_color);
+ Color sun_color_amount = p_env->fog_sun_color;
+ sun_color_amount.a = p_env->fog_sun_amount;
+
+ state.scene_shader.set_uniform(SceneShaderGLES2::FOG_SUN_COLOR_AMOUNT, sun_color_amount);
+ state.scene_shader.set_uniform(SceneShaderGLES2::FOG_TRANSMIT_ENABLED, p_env->fog_transmit_enabled);
+ state.scene_shader.set_uniform(SceneShaderGLES2::FOG_TRANSMIT_CURVE, p_env->fog_transmit_curve);
+
+ if (p_env->fog_depth_enabled) {
+ state.scene_shader.set_uniform(SceneShaderGLES2::FOG_DEPTH_BEGIN, p_env->fog_depth_begin);
+ state.scene_shader.set_uniform(SceneShaderGLES2::FOG_DEPTH_CURVE, p_env->fog_depth_curve);
+ state.scene_shader.set_uniform(SceneShaderGLES2::FOG_MAX_DISTANCE, fog_max_distance);
+ }
+
+ if (p_env->fog_height_enabled) {
+ state.scene_shader.set_uniform(SceneShaderGLES2::FOG_HEIGHT_MIN, p_env->fog_height_min);
+ state.scene_shader.set_uniform(SceneShaderGLES2::FOG_HEIGHT_MAX, p_env->fog_height_max);
+ state.scene_shader.set_uniform(SceneShaderGLES2::FOG_HEIGHT_MAX, p_env->fog_height_max);
+ state.scene_shader.set_uniform(SceneShaderGLES2::FOG_HEIGHT_CURVE, p_env->fog_height_curve);
+ }
+ }
}
- state.scene_shader.set_uniform(SceneShaderGLES2::CAMERA_MATRIX, view_transform_inverse);
- state.scene_shader.set_uniform(SceneShaderGLES2::CAMERA_INVERSE_MATRIX, p_view_transform);
+ state.scene_shader.set_uniform(SceneShaderGLES2::CAMERA_MATRIX, p_view_transform);
+ state.scene_shader.set_uniform(SceneShaderGLES2::CAMERA_INVERSE_MATRIX, view_transform_inverse);
state.scene_shader.set_uniform(SceneShaderGLES2::PROJECTION_MATRIX, p_projection);
state.scene_shader.set_uniform(SceneShaderGLES2::PROJECTION_INVERSE_MATRIX, projection_inverse);
@@ -2328,6 +2384,8 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
state.scene_shader.set_conditional(SceneShaderGLES2::USE_REFLECTION_PROBE2, false);
state.scene_shader.set_conditional(SceneShaderGLES2::USE_LIGHTMAP, false);
state.scene_shader.set_conditional(SceneShaderGLES2::USE_LIGHTMAP_CAPTURE, false);
+ state.scene_shader.set_conditional(SceneShaderGLES2::FOG_DEPTH_ENABLED, false);
+ state.scene_shader.set_conditional(SceneShaderGLES2::FOG_HEIGHT_ENABLED, false);
}
void RasterizerSceneGLES2::_draw_sky(RasterizerStorageGLES2::Sky *p_sky, const CameraMatrix &p_projection, const Transform &p_transform, bool p_vflip, float p_custom_fov, float p_energy) {
@@ -2402,13 +2460,20 @@ void RasterizerSceneGLES2::_draw_sky(RasterizerStorageGLES2::Sky *p_sky, const C
glEnableVertexAttribArray(VS::ARRAY_VERTEX);
glEnableVertexAttribArray(VS::ARRAY_TEX_UV);
+ storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_ASYM_PANO, asymmetrical);
+ storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_PANORAMA, !asymmetrical);
storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_MULTIPLIER, true);
storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_CUBEMAP, false);
- storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_PANORAMA, true);
storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_COPY_SECTION, false);
storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_CUSTOM_ALPHA, false);
storage->shaders.copy.bind();
storage->shaders.copy.set_uniform(CopyShaderGLES2::MULTIPLIER, p_energy);
+ if (asymmetrical) {
+ // pack the bits we need from our projection matrix
+ storage->shaders.copy.set_uniform(CopyShaderGLES2::ASYM_PROJ, camera.matrix[2][0], camera.matrix[0][0], camera.matrix[2][1], camera.matrix[1][1]);
+ ///@TODO I couldn't get mat3 + p_transform.basis to work, that would be better here.
+ storage->shaders.copy.set_uniform(CopyShaderGLES2::PANO_TRANSFORM, p_transform);
+ }
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
@@ -2416,6 +2481,8 @@ void RasterizerSceneGLES2::_draw_sky(RasterizerStorageGLES2::Sky *p_sky, const C
glDisableVertexAttribArray(VS::ARRAY_TEX_UV);
glBindBuffer(GL_ARRAY_BUFFER, 0);
+ storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_ASYM_PANO, false);
+ storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_PANORAMA, false);
storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_MULTIPLIER, false);
storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_CUBEMAP, false);
}
@@ -2984,6 +3051,7 @@ void RasterizerSceneGLES2::initialize() {
{
uint32_t immediate_buffer_size = GLOBAL_DEF("rendering/limits/buffers/immediate_buffer_size_kb", 2048);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/buffers/immediate_buffer_size_kb", PropertyInfo(Variant::INT, "rendering/limits/buffers/immediate_buffer_size_kb", PROPERTY_HINT_RANGE, "0,8192,1,or_greater"));
glGenBuffers(1, &state.immediate_buffer);
glBindBuffer(GL_ARRAY_BUFFER, state.immediate_buffer);
diff --git a/drivers/gles2/rasterizer_scene_gles2.h b/drivers/gles2/rasterizer_scene_gles2.h
index 14b9116952..33ac99366d 100644
--- a/drivers/gles2/rasterizer_scene_gles2.h
+++ b/drivers/gles2/rasterizer_scene_gles2.h
@@ -353,6 +353,21 @@ public:
int canvas_max_layer;
+ bool fog_enabled;
+ Color fog_color;
+ Color fog_sun_color;
+ float fog_sun_amount;
+
+ bool fog_depth_enabled;
+ float fog_depth_begin;
+ float fog_depth_curve;
+ bool fog_transmit_enabled;
+ float fog_transmit_curve;
+ bool fog_height_enabled;
+ float fog_height_min;
+ float fog_height_max;
+ float fog_height_curve;
+
Environment() {
bg_mode = VS::ENV_BG_CLEAR_COLOR;
sky_custom_fov = 0.0;
@@ -361,6 +376,24 @@ public:
ambient_energy = 1.0;
ambient_sky_contribution = 0.0;
canvas_max_layer = 0;
+
+ fog_enabled = false;
+ fog_color = Color(0.5, 0.5, 0.5);
+ fog_sun_color = Color(0.8, 0.8, 0.0);
+ fog_sun_amount = 0;
+
+ fog_depth_enabled = true;
+
+ fog_depth_begin = 10;
+ fog_depth_curve = 1;
+
+ fog_transmit_enabled = true;
+ fog_transmit_curve = 1;
+
+ fog_height_enabled = false;
+ fog_height_min = 0;
+ fog_height_max = 100;
+ fog_height_curve = 1;
}
};
diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp
index d5865064cf..ff6216cf7a 100644
--- a/drivers/gles2/rasterizer_storage_gles2.cpp
+++ b/drivers/gles2/rasterizer_storage_gles2.cpp
@@ -613,8 +613,72 @@ Ref<Image> RasterizerStorageGLES2::texture_get_data(RID p_texture, int p_layer)
return Ref<Image>(img);
#else
- ERR_EXPLAIN("Sorry, It's not possible to obtain images back in OpenGL ES");
- ERR_FAIL_V(Ref<Image>());
+ Image::Format real_format;
+ GLenum gl_format;
+ GLenum gl_internal_format;
+ GLenum gl_type;
+ bool compressed;
+ _get_gl_image_and_format(Ref<Image>(), texture->format, texture->flags, real_format, gl_format, gl_internal_format, gl_type, compressed);
+
+ PoolVector<uint8_t> data;
+
+ int data_size = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, Image::FORMAT_RGBA8, false);
+
+ data.resize(data_size * 2); //add some memory at the end, just in case for buggy drivers
+ PoolVector<uint8_t>::Write wb = data.write();
+
+ GLuint temp_framebuffer;
+ glGenFramebuffers(1, &temp_framebuffer);
+
+ GLuint temp_color_texture;
+ glGenTextures(1, &temp_color_texture);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, temp_framebuffer);
+
+ glBindTexture(GL_TEXTURE_2D, temp_color_texture);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture->alloc_width, texture->alloc_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, temp_color_texture, 0);
+
+ glDepthMask(GL_FALSE);
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_CULL_FACE);
+ glDisable(GL_BLEND);
+ glDepthFunc(GL_LEQUAL);
+ glColorMask(1, 1, 1, 1);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, texture->tex_id);
+
+ glViewport(0, 0, texture->alloc_width, texture->alloc_height);
+
+ shaders.copy.bind();
+
+ glClearColor(0.0, 0.0, 0.0, 0.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+ bind_quad_array();
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ glReadPixels(0, 0, texture->alloc_width, texture->alloc_height, GL_RGBA, GL_UNSIGNED_BYTE, &wb[0]);
+
+ glDeleteTextures(1, &temp_color_texture);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glDeleteFramebuffers(1, &temp_framebuffer);
+
+ wb = PoolVector<uint8_t>::Write();
+
+ data.resize(data_size);
+
+ Image *img = memnew(Image(texture->alloc_width, texture->alloc_height, false, Image::FORMAT_RGBA8, data));
+ if (!texture->compressed) {
+ img->convert(real_format);
+ }
+
+ return Ref<Image>(img);
+
#endif
}
@@ -1538,7 +1602,7 @@ void RasterizerStorageGLES2::_update_material(Material *p_material) {
if (p_material->shader && p_material->shader->mode == VS::SHADER_SPATIAL) {
if (p_material->shader->spatial.blend_mode == Shader::Spatial::BLEND_MODE_MIX &&
- (!p_material->shader->spatial.uses_alpha || (p_material->shader->spatial.uses_alpha && p_material->shader->spatial.depth_draw_mode == Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS))) {
+ (!p_material->shader->spatial.uses_alpha || p_material->shader->spatial.depth_draw_mode == Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS)) {
can_cast_shadow = true;
}
@@ -4394,6 +4458,7 @@ void RasterizerStorageGLES2::initialize() {
}
}
+ config.keep_original_textures = false;
config.shrink_textures_x2 = false;
config.float_texture_supported = config.extensions.has("GL_ARB_texture_float") || config.extensions.has("GL_OES_texture_float");
@@ -4541,6 +4606,7 @@ void RasterizerStorageGLES2::initialize() {
#endif
config.force_vertex_shading = GLOBAL_GET("rendering/quality/shading/force_vertex_shading");
+ config.use_fast_texture_filter = GLOBAL_GET("rendering/quality/filters/use_nearest_mipmap_filter");
}
void RasterizerStorageGLES2::finalize() {
diff --git a/drivers/gles2/rasterizer_storage_gles2.h b/drivers/gles2/rasterizer_storage_gles2.h
index b42e2dfb1f..c9731011fb 100644
--- a/drivers/gles2/rasterizer_storage_gles2.h
+++ b/drivers/gles2/rasterizer_storage_gles2.h
@@ -43,7 +43,6 @@
/*
#include "shaders/blend_shape.glsl.gen.h"
#include "shaders/canvas.glsl.gen.h"
-#include "shaders/copy.glsl.gen.h"
#include "shaders/particles.glsl.gen.h"
*/
@@ -61,20 +60,12 @@ public:
bool shrink_textures_x2;
bool use_fast_texture_filter;
- // bool use_anisotropic_filter;
-
- bool hdr_supported;
-
- bool use_rgba_2d_shadows;
-
- // float anisotropic_level;
int max_texture_image_units;
int max_texture_size;
- bool generate_wireframes;
-
- bool use_texture_array_environment;
+ // TODO implement wireframe in GLES2
+ // bool generate_wireframes;
Set<String> extensions;
@@ -84,7 +75,6 @@ public:
bool keep_original_textures;
- bool no_depth_prepass;
bool force_vertex_shading;
} config;
@@ -273,31 +263,28 @@ public:
void *detect_normal_ud;
Texture() {
- flags = 0;
- width = 0;
- height = 0;
alloc_width = 0;
alloc_height = 0;
- format = Image::FORMAT_L8;
-
target = 0;
- data_size = 0;
- total_data_size = 0;
+ stored_cube_sides = 0;
ignore_mipmaps = false;
-
- compressed = false;
-
- active = false;
-
+ render_target = NULL;
+ flags = width = height = 0;
tex_id = 0;
-
- stored_cube_sides = 0;
-
+ data_size = 0;
+ format = Image::FORMAT_L8;
+ active = false;
+ compressed = false;
+ total_data_size = 0;
+ mipmaps = 0;
+ detect_3d = NULL;
+ detect_3d_ud = NULL;
+ detect_srgb = NULL;
+ detect_srgb_ud = NULL;
+ detect_normal = NULL;
+ detect_normal_ud = NULL;
proxy = NULL;
-
- render_target = NULL;
-
redraw_if_visible = false;
}
@@ -430,6 +417,7 @@ public:
int light_mode;
*/
+
bool uses_screen_texture;
bool uses_screen_uv;
bool uses_time;
diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp
index 082c520480..723c44f2f6 100644
--- a/drivers/gles2/shader_compiler_gles2.cpp
+++ b/drivers/gles2/shader_compiler_gles2.cpp
@@ -80,11 +80,8 @@ static String _opstr(SL::Operator p_op) {
static String _mkid(const String &p_id) {
- StringBuffer<> id;
- id += "m_";
- id += p_id;
-
- return id.as_string();
+ String id = "m_" + p_id;
+ return id.replace("__", "_dus_"); //doubleunderscore is reserverd in glsl
}
static String f2sp0(float p_float) {
diff --git a/drivers/gles2/shader_gles2.cpp b/drivers/gles2/shader_gles2.cpp
index 628a57c06d..c5a67d4e75 100644
--- a/drivers/gles2/shader_gles2.cpp
+++ b/drivers/gles2/shader_gles2.cpp
@@ -196,6 +196,12 @@ static void _display_error_with_code(const String &p_error, const Vector<const c
ERR_PRINTS(p_error);
}
+static String _mkid(const String &p_id) {
+
+ String id = "m_" + p_id;
+ return id.replace("__", "_dus_"); //doubleunderscore is reserverd in glsl
+}
+
ShaderGLES2::Version *ShaderGLES2::get_current_version() {
Version *_v = version_map.getptr(conditional_version);
@@ -492,15 +498,15 @@ ShaderGLES2::Version *ShaderGLES2::get_current_version() {
if (cc) {
// uniforms
for (int i = 0; i < cc->custom_uniforms.size(); i++) {
- StringName native_uniform_name = "m_" + cc->custom_uniforms[i];
- GLint location = glGetUniformLocation(v.id, ((String)native_uniform_name).ascii().get_data());
+ String native_uniform_name = _mkid(cc->custom_uniforms[i]);
+ GLint location = glGetUniformLocation(v.id, (native_uniform_name).ascii().get_data());
v.custom_uniform_locations[cc->custom_uniforms[i]] = location;
}
// textures
for (int i = 0; i < cc->texture_uniforms.size(); i++) {
- StringName native_uniform_name = "m_" + cc->texture_uniforms[i];
- GLint location = glGetUniformLocation(v.id, ((String)native_uniform_name).ascii().get_data());
+ String native_uniform_name = _mkid(cc->texture_uniforms[i]);
+ GLint location = glGetUniformLocation(v.id, (native_uniform_name).ascii().get_data());
v.custom_uniform_locations[cc->texture_uniforms[i]] = location;
}
}
diff --git a/drivers/gles2/shaders/canvas.glsl b/drivers/gles2/shaders/canvas.glsl
index b990384949..79d4eb2243 100644
--- a/drivers/gles2/shaders/canvas.glsl
+++ b/drivers/gles2/shaders/canvas.glsl
@@ -148,7 +148,10 @@ void main() {
vec4 color = color_interp;
+#if !defined(COLOR_USED)
+ //default behavior, texture by color
color *= texture2D(color_texture, uv_interp);
+#endif
#ifdef SCREEN_UV_USED
vec2 screen_uv = gl_FragCoord.xy * screen_pixel_size;
diff --git a/drivers/gles2/shaders/copy.glsl b/drivers/gles2/shaders/copy.glsl
index 16bbde196d..0b8da4f875 100644
--- a/drivers/gles2/shaders/copy.glsl
+++ b/drivers/gles2/shaders/copy.glsl
@@ -35,6 +35,8 @@ void main() {
#if defined(USE_CUBEMAP) || defined(USE_PANORAMA)
cube_interp = cube_in;
+#elif defined(USE_ASYM_PANO)
+ uv_interp = vertex_attrib.xy;
#else
uv_interp = uv_in;
#endif
@@ -68,6 +70,11 @@ varying vec2 uv_interp;
#endif
/* clang-format on */
+#ifdef USE_ASYM_PANO
+uniform highp mat4 pano_transform;
+uniform highp vec4 asym_proj;
+#endif
+
#ifdef USE_CUBEMAP
uniform samplerCube source_cube; // texunit:0
#else
@@ -108,6 +115,21 @@ void main() {
vec4 color = texturePanorama(source, normalize(cube_interp));
+#elif defined(USE_ASYM_PANO)
+
+ // When an asymmetrical projection matrix is used (applicable for stereoscopic rendering i.e. VR) we need to do this calculation per fragment to get a perspective correct result.
+ // Note that we're ignoring the x-offset for IPD, with Z sufficiently in the distance it becomes neglectible, as a result we could probably just set cube_normal.z to -1.
+ // The Matrix[2][0] (= asym_proj.x) and Matrix[2][1] (= asym_proj.z) values are what provide the right shift in the image.
+
+ vec3 cube_normal;
+ cube_normal.z = -1000000.0;
+ cube_normal.x = (cube_normal.z * (-uv_interp.x - asym_proj.x)) / asym_proj.y;
+ cube_normal.y = (cube_normal.z * (-uv_interp.y - asym_proj.z)) / asym_proj.a;
+ cube_normal = mat3(pano_transform) * cube_normal;
+ cube_normal.z = -cube_normal.z;
+
+ vec4 color = texturePanorama(source, normalize(cube_normal.xyz));
+
#elif defined(USE_CUBEMAP)
vec4 color = textureCube(source_cube, normalize(cube_interp));
#else
diff --git a/drivers/gles2/shaders/scene.glsl b/drivers/gles2/shaders/scene.glsl
index a798244f01..c2a4a2d4b3 100644
--- a/drivers/gles2/shaders/scene.glsl
+++ b/drivers/gles2/shaders/scene.glsl
@@ -75,12 +75,12 @@ attribute highp vec4 instance_custom_data; // attrib:12
// uniforms
//
-uniform mat4 camera_matrix;
-uniform mat4 camera_inverse_matrix;
-uniform mat4 projection_matrix;
-uniform mat4 projection_inverse_matrix;
+uniform highp mat4 camera_matrix;
+uniform highp mat4 camera_inverse_matrix;
+uniform highp mat4 projection_matrix;
+uniform highp mat4 projection_inverse_matrix;
-uniform mat4 world_transform;
+uniform highp mat4 world_transform;
uniform highp float time;
@@ -156,22 +156,22 @@ varying highp vec3 diffuse_interp;
varying highp vec3 specular_interp;
// general for all lights
-uniform vec4 light_color;
-uniform float light_specular;
+uniform highp vec4 light_color;
+uniform highp float light_specular;
// directional
-uniform vec3 light_direction;
+uniform highp vec3 light_direction;
// omni
-uniform vec3 light_position;
+uniform highp vec3 light_position;
-uniform float light_range;
-uniform float light_attenuation;
+uniform highp float light_range;
+uniform highp float light_attenuation;
// spot
-uniform float light_spot_attenuation;
-uniform float light_spot_range;
-uniform float light_spot_angle;
+uniform highp float light_spot_attenuation;
+uniform highp float light_spot_range;
+uniform highp float light_spot_angle;
void light_compute(
vec3 N,
@@ -262,9 +262,9 @@ void light_compute(
#ifdef USE_REFLECTION_PROBE1
-uniform mat4 refprobe1_local_matrix;
+uniform highp mat4 refprobe1_local_matrix;
varying mediump vec4 refprobe1_reflection_normal_blend;
-uniform vec3 refprobe1_box_extents;
+uniform highp vec3 refprobe1_box_extents;
#ifndef USE_LIGHTMAP
varying mediump vec3 refprobe1_ambient_normal;
@@ -274,9 +274,9 @@ varying mediump vec3 refprobe1_ambient_normal;
#ifdef USE_REFLECTION_PROBE2
-uniform mat4 refprobe2_local_matrix;
+uniform highp mat4 refprobe2_local_matrix;
varying mediump vec4 refprobe2_reflection_normal_blend;
-uniform vec3 refprobe2_box_extents;
+uniform highp vec3 refprobe2_box_extents;
#ifndef USE_LIGHTMAP
varying mediump vec3 refprobe2_ambient_normal;
@@ -286,6 +286,32 @@ varying mediump vec3 refprobe2_ambient_normal;
#endif //vertex lighting for refprobes
+#if defined(FOG_DEPTH_ENABLED) || defined(FOG_HEIGHT_ENABLED)
+
+varying vec4 fog_interp;
+
+uniform mediump vec4 fog_color_base;
+#ifdef LIGHT_MODE_DIRECTIONAL
+uniform mediump vec4 fog_sun_color_amount;
+#endif
+
+uniform bool fog_transmit_enabled;
+uniform mediump float fog_transmit_curve;
+
+#ifdef FOG_DEPTH_ENABLED
+uniform highp float fog_depth_begin;
+uniform mediump float fog_depth_curve;
+uniform mediump float fog_max_distance;
+#endif
+
+#ifdef FOG_HEIGHT_ENABLED
+uniform highp float fog_height_min;
+uniform highp float fog_height_max;
+uniform mediump float fog_height_curve;
+#endif
+
+#endif //fog
+
void main() {
highp vec4 vertex = vertex_attrib;
@@ -333,7 +359,7 @@ void main() {
normal = normalize((world_matrix * vec4(normal, 0.0)).xyz);
#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP)
- tangent = normalize((world_matrix * vec4(tangent, 0.0)), xyz);
+ tangent = normalize((world_matrix * vec4(tangent, 0.0)).xyz);
binormal = normalize((world_matrix * vec4(binormal, 0.0)).xyz);
#endif
#endif
@@ -379,7 +405,7 @@ void main() {
#endif
- mat4 modelview = camera_matrix * world_matrix;
+ mat4 modelview = camera_inverse_matrix * world_matrix;
float roughness = 1.0;
#define world_transform world_matrix
@@ -406,11 +432,11 @@ VERTEX_SHADER_CODE
#endif
#if !defined(SKIP_TRANSFORM_USED) && defined(VERTEX_WORLD_COORDS_USED)
- vertex = camera_matrix * vertex;
- normal = normalize((camera_matrix * vec4(normal, 0.0)).xyz);
+ vertex = camera_inverse_matrix * vertex;
+ normal = normalize((camera_inverse_matrix * vec4(normal, 0.0)).xyz);
#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP)
- tangent = normalize((camera_matrix * vec4(tangent, 0.0)).xyz);
- binormal = normalize((camera_matrix * vec4(binormal, 0.0)).xyz);
+ tangent = normalize((camera_inverse_matrix * vec4(tangent, 0.0)).xyz);
+ binormal = normalize((camera_inverse_matrix * vec4(binormal, 0.0)).xyz);
#endif
#endif
@@ -583,6 +609,37 @@ VERTEX_SHADER_CODE
#endif //USE_REFLECTION_PROBE2
+#if defined(FOG_DEPTH_ENABLED) || defined(FOG_HEIGHT_ENABLED)
+
+ float fog_amount = 0.0;
+
+#ifdef LIGHT_MODE_DIRECTIONAL
+
+ vec3 fog_color = mix(fog_color_base.rgb, fog_sun_color_amount.rgb, fog_sun_color_amount.a * pow(max(dot(normalize(vertex_interp), light_direction), 0.0), 8.0));
+#else
+ vec3 fog_color = fog_color_base.rgb;
+#endif
+
+#ifdef FOG_DEPTH_ENABLED
+
+ {
+
+ float fog_z = smoothstep(fog_depth_begin, fog_max_distance, length(vertex));
+
+ fog_amount = pow(fog_z, fog_depth_curve);
+ }
+#endif
+
+#ifdef FOG_HEIGHT_ENABLED
+ {
+ float y = (camera_matrix * vec4(vertex_interp, 1.0)).y;
+ fog_amount = max(fog_amount, pow(smoothstep(fog_height_min, fog_height_max, y), fog_height_curve));
+ }
+#endif
+ fog_interp = vec4(fog_color, fog_amount);
+
+#endif //fog
+
#endif //use vertex lighting
gl_Position = projection_matrix * vec4(vertex_interp, 1.0);
}
@@ -613,13 +670,13 @@ precision highp int;
// uniforms
//
-uniform mat4 camera_matrix;
+uniform highp mat4 camera_matrix;
/* clang-format on */
-uniform mat4 camera_inverse_matrix;
-uniform mat4 projection_matrix;
-uniform mat4 projection_inverse_matrix;
+uniform highp mat4 camera_inverse_matrix;
+uniform highp mat4 projection_matrix;
+uniform highp mat4 projection_inverse_matrix;
-uniform mat4 world_transform;
+uniform highp mat4 world_transform;
uniform highp float time;
@@ -646,9 +703,9 @@ varying mediump vec3 refprobe1_ambient_normal;
#else
uniform bool refprobe1_use_box_project;
-uniform vec3 refprobe1_box_extents;
+uniform highp vec3 refprobe1_box_extents;
uniform vec3 refprobe1_box_offset;
-uniform mat4 refprobe1_local_matrix;
+uniform highp mat4 refprobe1_local_matrix;
#endif //use vertex lighting
@@ -673,9 +730,9 @@ varying mediump vec3 refprobe2_ambient_normal;
#else
uniform bool refprobe2_use_box_project;
-uniform vec3 refprobe2_box_extents;
+uniform highp vec3 refprobe2_box_extents;
uniform vec3 refprobe2_box_offset;
-uniform mat4 refprobe2_local_matrix;
+uniform highp mat4 refprobe2_local_matrix;
#endif //use vertex lighting
@@ -816,27 +873,29 @@ uniform float ambient_energy;
varying highp vec3 diffuse_interp;
varying highp vec3 specular_interp;
+uniform highp vec3 light_direction; //may be used by fog, so leave here
+
#else
//done in fragment
// general for all lights
-uniform vec4 light_color;
-uniform float light_specular;
+uniform highp vec4 light_color;
+uniform highp float light_specular;
// directional
-uniform vec3 light_direction;
+uniform highp vec3 light_direction;
// omni
-uniform vec3 light_position;
+uniform highp vec3 light_position;
-uniform float light_attenuation;
+uniform highp float light_attenuation;
// spot
-uniform float light_spot_attenuation;
-uniform float light_spot_range;
-uniform float light_spot_angle;
+uniform highp float light_spot_attenuation;
+uniform highp float light_spot_range;
+uniform highp float light_spot_angle;
#endif
//this is needed outside above if because dual paraboloid wants it
-uniform float light_range;
+uniform highp float light_range;
#ifdef USE_SHADOW
@@ -1239,8 +1298,7 @@ LIGHT_SHADER_CODE
#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)
-float sample_shadow(
- highp sampler2D shadow, highp vec4 spos) {
+float sample_shadow(highp sampler2D shadow, highp vec4 spos) {
#ifdef SHADOW_MODE_PCF_13
@@ -1287,6 +1345,36 @@ float sample_shadow(
#endif
+#if defined(FOG_DEPTH_ENABLED) || defined(FOG_HEIGHT_ENABLED)
+
+#if defined(USE_VERTEX_LIGHTING)
+
+varying vec4 fog_interp;
+
+#else
+uniform mediump vec4 fog_color_base;
+#ifdef LIGHT_MODE_DIRECTIONAL
+uniform mediump vec4 fog_sun_color_amount;
+#endif
+
+uniform bool fog_transmit_enabled;
+uniform mediump float fog_transmit_curve;
+
+#ifdef FOG_DEPTH_ENABLED
+uniform highp float fog_depth_begin;
+uniform mediump float fog_depth_curve;
+uniform mediump float fog_max_distance;
+#endif
+
+#ifdef FOG_HEIGHT_ENABLED
+uniform highp float fog_height_min;
+uniform highp float fog_height_max;
+uniform mediump float fog_height_curve;
+#endif
+
+#endif //vertex lit
+#endif //fog
+
void main() {
#ifdef RENDER_DEPTH_DUAL_PARABOLOID
@@ -1531,7 +1619,7 @@ FRAGMENT_SHADER_CODE
highp vec4 splane = shadow_coord;
float shadow_len = length(splane.xyz);
- splane = normalize(splane.xyz);
+ splane.xyz = normalize(splane.xyz);
vec4 clamp_rect = light_clamp;
@@ -1825,12 +1913,12 @@ FRAGMENT_SHADER_CODE
highp vec4 splane = shadow_coord;
splane.xyz /= splane.w;
- float shadow = sample_shadow(light_shadow_atlas, splane.xy, splane.z);
+ float shadow = sample_shadow(light_shadow_atlas, splane);
light_att *= shadow;
}
#endif
-#endif
+#endif // LIGHT_MODE_SPOT
#ifdef USE_VERTEX_LIGHTING
//vertex lighting
@@ -1917,5 +2005,50 @@ FRAGMENT_SHADER_CODE
#endif //unshaded
+//apply fog
+#if defined(FOG_DEPTH_ENABLED) || defined(FOG_HEIGHT_ENABLED)
+
+#if defined(USE_VERTEX_LIGHTING)
+
+ gl_FragColor.rgb = mix(gl_FragColor.rgb, fog_interp.rgb, fog_interp.a);
+#else //pixel based fog
+ float fog_amount = 0.0;
+
+#ifdef LIGHT_MODE_DIRECTIONAL
+
+ vec3 fog_color = mix(fog_color_base.rgb, fog_sun_color_amount.rgb, fog_sun_color_amount.a * pow(max(dot(eye_position, light_direction), 0.0), 8.0));
+#else
+ vec3 fog_color = fog_color_base.rgb;
+#endif
+
+#ifdef FOG_DEPTH_ENABLED
+
+ {
+
+ float fog_z = smoothstep(fog_depth_begin, fog_max_distance, length(vertex));
+
+ fog_amount = pow(fog_z, fog_depth_curve);
+
+ if (fog_transmit_enabled) {
+ vec3 total_light = gl_FragColor.rgb;
+ float transmit = pow(fog_z, fog_transmit_curve);
+ fog_color = mix(max(total_light, fog_color), fog_color, transmit);
+ }
+ }
+#endif
+
+#ifdef FOG_HEIGHT_ENABLED
+ {
+ float y = (camera_matrix * vec4(vertex, 1.0)).y;
+ fog_amount = max(fog_amount, pow(smoothstep(fog_height_min, fog_height_max, y), fog_height_curve));
+ }
+#endif
+
+ gl_FragColor.rgb = mix(gl_FragColor.rgb, fog_color, fog_amount);
+
+#endif //use vertex lit
+
+#endif // defined(FOG_DEPTH_ENABLED) || defined(FOG_HEIGHT_ENABLED)
+
#endif // not RENDER_DEPTH
}