summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp67
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.h2
-rw-r--r--drivers/gles3/rasterizer_gles3.cpp26
-rw-r--r--drivers/gles3/rasterizer_gles3.h3
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp21
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp2
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.h1
-rw-r--r--drivers/gles3/shader_compiler_gles3.cpp2
-rw-r--r--drivers/gles3/shaders/scene.glsl10
9 files changed, 120 insertions, 14 deletions
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index 56d9f2cc47..e6ffa39197 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -941,6 +941,8 @@ void RasterizerGLES2::_canvas_item_setup_shader_params(ShaderMaterial *material,
void RasterizerCanvasGLES3::_copy_texscreen(const Rect2 &p_rect) {
+ glDisable(GL_BLEND);
+
state.canvas_texscreen_used = true;
//blur diffuse into effect mipmaps using separatable convolution
//storage->shaders.copy.set_conditional(CopyShaderGLES3::GAUSSIAN_HORIZONTAL,true);
@@ -1003,12 +1005,16 @@ void RasterizerCanvasGLES3::_copy_texscreen(const Rect2 &p_rect) {
glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->fbo); //back to front
glViewport(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height);
+
state.canvas_shader.bind(); //back to canvas
+ _bind_canvas_texture(state.current_tex, state.current_normal);
if (state.using_texture_rect) {
state.using_texture_rect = false;
_set_texture_rect_mode(state.using_texture_rect, state.using_ninepatch);
}
+
+ glEnable(GL_BLEND);
}
void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light) {
@@ -1595,6 +1601,67 @@ void RasterizerCanvasGLES3::draw_generic_textured_rect(const Rect2 &p_rect, cons
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
+void RasterizerCanvasGLES3::draw_window_margins(int *black_margin, RID *black_image) {
+
+ Vector2 window_size = OS::get_singleton()->get_window_size();
+ int window_h = window_size.height;
+ int window_w = window_size.width;
+
+ glBindFramebuffer(GL_FRAMEBUFFER, storage->system_fbo);
+ glViewport(0, 0, window_size.width, window_size.height);
+ canvas_begin();
+
+ if (black_image[MARGIN_LEFT].is_valid()) {
+ _bind_canvas_texture(black_image[MARGIN_LEFT], RID());
+ Size2 sz(storage->texture_get_width(black_image[MARGIN_LEFT]), storage->texture_get_height(black_image[MARGIN_LEFT]));
+ draw_generic_textured_rect(Rect2(0, 0, black_margin[MARGIN_LEFT], window_h), Rect2(0, 0, sz.x, sz.y));
+ } else if (black_margin[MARGIN_LEFT]) {
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, storage->resources.black_tex);
+
+ draw_generic_textured_rect(Rect2(0, 0, black_margin[MARGIN_LEFT], window_h), Rect2(0, 0, 1, 1));
+ }
+
+ if (black_image[MARGIN_RIGHT].is_valid()) {
+ _bind_canvas_texture(black_image[MARGIN_RIGHT], RID());
+ Size2 sz(storage->texture_get_width(black_image[MARGIN_RIGHT]), storage->texture_get_height(black_image[MARGIN_RIGHT]));
+ draw_generic_textured_rect(Rect2(window_w - black_margin[MARGIN_RIGHT], 0, black_margin[MARGIN_RIGHT], window_h), Rect2(0, 0, sz.x, sz.y));
+ } else if (black_margin[MARGIN_RIGHT]) {
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, storage->resources.black_tex);
+
+ draw_generic_textured_rect(Rect2(window_w - black_margin[MARGIN_RIGHT], 0, black_margin[MARGIN_RIGHT], window_h), Rect2(0, 0, 1, 1));
+ }
+
+ if (black_image[MARGIN_TOP].is_valid()) {
+ _bind_canvas_texture(black_image[MARGIN_TOP], RID());
+
+ Size2 sz(storage->texture_get_width(black_image[MARGIN_TOP]), storage->texture_get_height(black_image[MARGIN_TOP]));
+ draw_generic_textured_rect(Rect2(0, 0, window_w, black_margin[MARGIN_TOP]), Rect2(0, 0, sz.x, sz.y));
+
+ } else if (black_margin[MARGIN_TOP]) {
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, storage->resources.black_tex);
+
+ draw_generic_textured_rect(Rect2(0, 0, window_w, black_margin[MARGIN_TOP]), Rect2(0, 0, 1, 1));
+ }
+
+ if (black_image[MARGIN_BOTTOM].is_valid()) {
+
+ _bind_canvas_texture(black_image[MARGIN_BOTTOM], RID());
+
+ Size2 sz(storage->texture_get_width(black_image[MARGIN_BOTTOM]), storage->texture_get_height(black_image[MARGIN_BOTTOM]));
+ draw_generic_textured_rect(Rect2(0, window_h - black_margin[MARGIN_BOTTOM], window_w, black_margin[MARGIN_BOTTOM]), Rect2(0, 0, sz.x, sz.y));
+
+ } else if (black_margin[MARGIN_BOTTOM]) {
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, storage->resources.black_tex);
+
+ draw_generic_textured_rect(Rect2(0, window_h - black_margin[MARGIN_BOTTOM], window_w, black_margin[MARGIN_BOTTOM]), Rect2(0, 0, 1, 1));
+ }
+}
+
void RasterizerCanvasGLES3::initialize() {
{
diff --git a/drivers/gles3/rasterizer_canvas_gles3.h b/drivers/gles3/rasterizer_canvas_gles3.h
index c0af22b5e8..26003f543f 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.h
+++ b/drivers/gles3/rasterizer_canvas_gles3.h
@@ -138,6 +138,8 @@ public:
void initialize();
void finalize();
+ virtual void draw_window_margins(int *black_margin, RID *black_image);
+
RasterizerCanvasGLES3();
};
diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp
index 3fc5bed80b..e025992c0b 100644
--- a/drivers/gles3/rasterizer_gles3.cpp
+++ b/drivers/gles3/rasterizer_gles3.cpp
@@ -197,18 +197,28 @@ void RasterizerGLES3::begin_frame() {
uint64_t tick = OS::get_singleton()->get_ticks_usec();
- double time_total = double(tick) / 1000000.0;
+ double delta = double(tick - prev_ticks) / 1000000.0;
+ delta *= Engine::get_singleton()->get_time_scale();
+
+ time_total += delta;
+
+ if (delta == 0) {
+ //to avoid hiccups
+ delta = 0.001;
+ }
+
+ prev_ticks = tick;
+
+ double time_roll_over = GLOBAL_GET("rendering/limits/time/time_rollover_secs");
+ if (time_total > time_roll_over)
+ time_total = 0; //roll over every day (should be customz
storage->frame.time[0] = time_total;
storage->frame.time[1] = Math::fmod(time_total, 3600);
storage->frame.time[2] = Math::fmod(time_total, 900);
storage->frame.time[3] = Math::fmod(time_total, 60);
storage->frame.count++;
- storage->frame.delta = double(tick - storage->frame.prev_tick) / 1000000.0;
- if (storage->frame.prev_tick == 0) {
- //to avoid hiccups
- storage->frame.delta = 0.001;
- }
+ storage->frame.delta = delta;
storage->frame.prev_tick = tick;
@@ -408,6 +418,7 @@ void RasterizerGLES3::register_config() {
GLOBAL_DEF("rendering/quality/filters/use_nearest_mipmap_filter", false);
GLOBAL_DEF("rendering/quality/filters/anisotropic_filter_level", 4.0);
+ GLOBAL_DEF("rendering/limits/time/time_rollover_secs", 3600);
}
RasterizerGLES3::RasterizerGLES3() {
@@ -420,6 +431,9 @@ RasterizerGLES3::RasterizerGLES3() {
storage->canvas = canvas;
scene->storage = storage;
storage->scene = scene;
+
+ prev_ticks = 0;
+ time_total = 0;
}
RasterizerGLES3::~RasterizerGLES3() {
diff --git a/drivers/gles3/rasterizer_gles3.h b/drivers/gles3/rasterizer_gles3.h
index ce18d6b6c1..4bc267ec7e 100644
--- a/drivers/gles3/rasterizer_gles3.h
+++ b/drivers/gles3/rasterizer_gles3.h
@@ -43,6 +43,9 @@ class RasterizerGLES3 : public Rasterizer {
RasterizerCanvasGLES3 *canvas;
RasterizerSceneGLES3 *scene;
+ uint64_t prev_ticks;
+ double time_total;
+
public:
virtual RasterizerStorage *get_storage();
virtual RasterizerCanvas *get_canvas();
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index cd74c450f5..30a77c4b39 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -1561,7 +1561,7 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) {
if (!c.normals.empty()) {
glEnableVertexAttribArray(VS::ARRAY_NORMAL);
- glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vector3) * vertices, c.normals.ptr());
+ glBufferSubData(GL_ARRAY_BUFFER, buf_ofs, sizeof(Vector3) * vertices, c.normals.ptr());
glVertexAttribPointer(VS::ARRAY_NORMAL, 3, GL_FLOAT, false, sizeof(Vector3) * vertices, ((uint8_t *)NULL) + buf_ofs);
buf_ofs += sizeof(Vector3) * vertices;
@@ -1573,7 +1573,7 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) {
if (!c.tangents.empty()) {
glEnableVertexAttribArray(VS::ARRAY_TANGENT);
- glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Plane) * vertices, c.tangents.ptr());
+ glBufferSubData(GL_ARRAY_BUFFER, buf_ofs, sizeof(Plane) * vertices, c.tangents.ptr());
glVertexAttribPointer(VS::ARRAY_TANGENT, 4, GL_FLOAT, false, sizeof(Plane) * vertices, ((uint8_t *)NULL) + buf_ofs);
buf_ofs += sizeof(Plane) * vertices;
@@ -1585,7 +1585,7 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) {
if (!c.colors.empty()) {
glEnableVertexAttribArray(VS::ARRAY_COLOR);
- glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Color) * vertices, c.colors.ptr());
+ glBufferSubData(GL_ARRAY_BUFFER, buf_ofs, sizeof(Color) * vertices, c.colors.ptr());
glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, false, sizeof(Color), ((uint8_t *)NULL) + buf_ofs);
buf_ofs += sizeof(Color) * vertices;
@@ -1598,7 +1598,7 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) {
if (!c.uvs.empty()) {
glEnableVertexAttribArray(VS::ARRAY_TEX_UV);
- glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vector2) * vertices, c.uvs.ptr());
+ glBufferSubData(GL_ARRAY_BUFFER, buf_ofs, sizeof(Vector2) * vertices, c.uvs.ptr());
glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, false, sizeof(Vector2), ((uint8_t *)NULL) + buf_ofs);
buf_ofs += sizeof(Vector2) * vertices;
@@ -1610,7 +1610,7 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) {
if (!c.uvs2.empty()) {
glEnableVertexAttribArray(VS::ARRAY_TEX_UV2);
- glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vector2) * vertices, c.uvs2.ptr());
+ glBufferSubData(GL_ARRAY_BUFFER, buf_ofs, sizeof(Vector2) * vertices, c.uvs2.ptr());
glVertexAttribPointer(VS::ARRAY_TEX_UV2, 2, GL_FLOAT, false, sizeof(Vector2), ((uint8_t *)NULL) + buf_ofs);
buf_ofs += sizeof(Vector2) * vertices;
@@ -1620,7 +1620,7 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) {
}
glEnableVertexAttribArray(VS::ARRAY_VERTEX);
- glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vector3) * vertices, c.vertices.ptr());
+ glBufferSubData(GL_ARRAY_BUFFER, buf_ofs, sizeof(Vector3) * vertices, c.vertices.ptr());
glVertexAttribPointer(VS::ARRAY_VERTEX, 3, GL_FLOAT, false, sizeof(Vector3), ((uint8_t *)NULL) + buf_ofs);
glDrawArrays(gl_primitive[c.primitive], 0, c.vertices.size());
}
@@ -2182,7 +2182,7 @@ void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geo
void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, RasterizerStorageGLES3::Material *m, bool p_shadow) {
- bool has_base_alpha = (m->shader->spatial.uses_alpha || m->shader->spatial.uses_screen_texture || m->shader->spatial.unshaded);
+ bool has_base_alpha = (m->shader->spatial.uses_alpha && !m->shader->spatial.uses_alpha_scissor) || m->shader->spatial.uses_screen_texture || m->shader->spatial.unshaded;
bool has_blend_alpha = m->shader->spatial.blend_mode != RasterizerStorageGLES3::Shader::Spatial::BLEND_MODE_MIX || m->shader->spatial.ontop;
bool has_alpha = has_base_alpha || has_blend_alpha;
bool shadow = false;
@@ -2206,7 +2206,7 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G
if (has_blend_alpha || (has_base_alpha && m->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS))
return; //bye
- if (!m->shader->spatial.writes_modelview_or_projection && !m->shader->spatial.uses_vertex && !m->shader->spatial.uses_discard && m->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) {
+ if (!m->shader->spatial.uses_alpha_scissor && !m->shader->spatial.writes_modelview_or_projection && !m->shader->spatial.uses_vertex && !m->shader->spatial.uses_discard && m->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) {
//shader does not use discard and does not write a vertex position, use generic material
if (p_instance->cast_shadows == VS::SHADOW_CASTING_SETTING_DOUBLE_SIDED)
m = storage->material_owner.getptr(default_material_twosided);
@@ -3051,6 +3051,11 @@ void RasterizerSceneGLES3::_fill_render_list(InstanceBase **p_cull_result, int p
} break;
case VS::INSTANCE_IMMEDIATE: {
+ RasterizerStorageGLES3::Immediate *immediate = storage->immediate_owner.getptr(inst->base);
+ ERR_CONTINUE(!immediate);
+
+ _add_geometry(immediate, inst, NULL, -1, p_shadow);
+
} break;
case VS::INSTANCE_PARTICLES: {
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index f7ecc3b158..a8e4bc0d4b 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -1596,6 +1596,7 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
p_shader->spatial.depth_draw_mode = Shader::Spatial::DEPTH_DRAW_OPAQUE;
p_shader->spatial.cull_mode = Shader::Spatial::CULL_MODE_BACK;
p_shader->spatial.uses_alpha = false;
+ p_shader->spatial.uses_alpha_scissor = false;
p_shader->spatial.uses_discard = false;
p_shader->spatial.unshaded = false;
p_shader->spatial.ontop = false;
@@ -1625,6 +1626,7 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
shaders.actions_scene.render_mode_flags["vertex_lighting"] = &p_shader->spatial.uses_vertex_lighting;
shaders.actions_scene.usage_flag_pointers["ALPHA"] = &p_shader->spatial.uses_alpha;
+ shaders.actions_scene.usage_flag_pointers["ALPHA_SCISSOR"] = &p_shader->spatial.uses_alpha_scissor;
shaders.actions_scene.usage_flag_pointers["VERTEX"] = &p_shader->spatial.uses_vertex;
shaders.actions_scene.usage_flag_pointers["SSS_STRENGTH"] = &p_shader->spatial.uses_sss;
diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h
index b536c9841c..5a272f43fb 100644
--- a/drivers/gles3/rasterizer_storage_gles3.h
+++ b/drivers/gles3/rasterizer_storage_gles3.h
@@ -442,6 +442,7 @@ public:
int cull_mode;
bool uses_alpha;
+ bool uses_alpha_scissor;
bool unshaded;
bool ontop;
bool uses_vertex;
diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp
index 206f270f68..c014caee8d 100644
--- a/drivers/gles3/shader_compiler_gles3.cpp
+++ b/drivers/gles3/shader_compiler_gles3.cpp
@@ -762,6 +762,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_SPATIAL].renames["SCREEN_TEXTURE"] = "screen_texture";
actions[VS::SHADER_SPATIAL].renames["DEPTH_TEXTURE"] = "depth_buffer";
actions[VS::SHADER_SPATIAL].renames["SIDE"] = "side";
+ actions[VS::SHADER_SPATIAL].renames["ALPHA_SCISSOR"] = "alpha_scissor";
actions[VS::SHADER_SPATIAL].usage_defines["TANGENT"] = "#define ENABLE_TANGENT_INTERP\n";
actions[VS::SHADER_SPATIAL].usage_defines["BINORMAL"] = "@TANGENT";
@@ -778,6 +779,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_SPATIAL].usage_defines["NORMALMAP_DEPTH"] = "@NORMALMAP";
actions[VS::SHADER_SPATIAL].usage_defines["COLOR"] = "#define ENABLE_COLOR_INTERP\n";
actions[VS::SHADER_SPATIAL].usage_defines["INSTANCE_CUSTOM"] = "#define ENABLE_INSTANCE_CUSTOM\n";
+ actions[VS::SHADER_SPATIAL].usage_defines["ALPHA_SCISSOR"] = "#define ALPHA_SCISSOR_USED\n";
actions[VS::SHADER_SPATIAL].usage_defines["SSS_STRENGTH"] = "#define ENABLE_SSS\n";
actions[VS::SHADER_SPATIAL].usage_defines["SCREEN_TEXTURE"] = "#define SCREEN_TEXTURE_USED\n";
diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index efb82441f4..3f0498746b 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -1523,6 +1523,10 @@ void main() {
#endif
+#if defined(ALPHA_SCISSOR_USED)
+ float alpha_scissor = 0.5;
+#endif
+
#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY)
vec3 binormal = normalize(binormal_interp)*side;
vec3 tangent = normalize(tangent_interp)*side;
@@ -1571,6 +1575,12 @@ FRAGMENT_SHADER_CODE
}
+#if defined(ALPHA_SCISSOR_USED)
+ if (alpha<alpha_scissor) {
+ discard;
+ }
+#endif
+
#if defined(ENABLE_NORMALMAP)