summaryrefslogtreecommitdiff
path: root/drivers/gles3
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gles3')
-rw-r--r--drivers/gles3/rasterizer_gles3.cpp49
-rw-r--r--drivers/gles3/rasterizer_gles3.h3
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp112
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.h3
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp333
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.h25
-rw-r--r--drivers/gles3/shader_compiler_gles3.cpp17
-rw-r--r--drivers/gles3/shader_compiler_gles3.h1
-rw-r--r--drivers/gles3/shader_gles3.cpp2
-rw-r--r--drivers/gles3/shaders/scene.glsl31
10 files changed, 383 insertions, 193 deletions
diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp
index 1abdaa5f80..cb17695c5f 100644
--- a/drivers/gles3/rasterizer_gles3.cpp
+++ b/drivers/gles3/rasterizer_gles3.cpp
@@ -192,22 +192,15 @@ void RasterizerGLES3::initialize() {
scene->initialize();
}
-void RasterizerGLES3::begin_frame() {
+void RasterizerGLES3::begin_frame(double frame_step) {
- uint64_t tick = OS::get_singleton()->get_ticks_usec();
+ time_total += frame_step;
- double delta = double(tick - prev_ticks) / 1000000.0;
- delta *= Engine::get_singleton()->get_time_scale();
-
- time_total += delta;
-
- if (delta == 0) {
+ if (frame_step == 0) {
//to avoid hiccups
- delta = 0.001;
+ frame_step = 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
@@ -217,9 +210,7 @@ void RasterizerGLES3::begin_frame() {
storage->frame.time[2] = Math::fmod(time_total, 900);
storage->frame.time[3] = Math::fmod(time_total, 60);
storage->frame.count++;
- storage->frame.delta = delta;
-
- storage->frame.prev_tick = tick;
+ storage->frame.delta = frame_step;
storage->update_dirty_resources();
@@ -234,7 +225,7 @@ void RasterizerGLES3::set_current_render_target(RID p_render_target) {
if (!p_render_target.is_valid() && storage->frame.current_rt && storage->frame.clear_request) {
//handle pending clear request, if the framebuffer was not cleared
glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->fbo);
- print_line("unbind clear of: " + storage->frame.clear_request_color);
+
glClearColor(
storage->frame.clear_request_color.r,
storage->frame.clear_request_color.g,
@@ -281,7 +272,7 @@ void RasterizerGLES3::set_boot_image(const Ref<Image> &p_image, const Color &p_c
if (p_image.is_null() || p_image->empty())
return;
- begin_frame();
+ begin_frame(0.0);
int window_w = OS::get_singleton()->get_video_mode(0).width;
int window_h = OS::get_singleton()->get_video_mode(0).height;
@@ -299,7 +290,7 @@ void RasterizerGLES3::set_boot_image(const Ref<Image> &p_image, const Color &p_c
canvas->canvas_begin();
RID texture = storage->texture_create();
- storage->texture_allocate(texture, p_image->get_width(), p_image->get_height(), p_image->get_format(), VS::TEXTURE_FLAG_FILTER);
+ storage->texture_allocate(texture, p_image->get_width(), p_image->get_height(), 0, p_image->get_format(), VS::TEXTURE_TYPE_2D, VS::TEXTURE_FLAG_FILTER);
storage->texture_set_data(texture, p_image);
Rect2 imgrect(0, 0, p_image->get_width(), p_image->get_height());
@@ -333,28 +324,7 @@ void RasterizerGLES3::set_boot_image(const Ref<Image> &p_image, const Color &p_c
storage->free(texture); // free since it's only one frame that stays there
- if (OS::get_singleton()->is_layered_allowed()) {
- if (OS::get_singleton()->get_window_per_pixel_transparency_enabled()) {
-#if (defined WINDOWS_ENABLED) && !(defined UWP_ENABLED)
- Size2 wndsize = OS::get_singleton()->get_layered_buffer_size();
- uint8_t *data = OS::get_singleton()->get_layered_buffer_data();
- if (data) {
- glReadPixels(0, 0, wndsize.x, wndsize.y, GL_BGRA, GL_UNSIGNED_BYTE, data);
- OS::get_singleton()->swap_layered_buffer();
-
- return;
- }
-#endif
- } else {
- //clear alpha
- glColorMask(false, false, false, true);
- glClearColor(0, 0, 0, 1);
- glClear(GL_COLOR_BUFFER_BIT);
- glColorMask(true, true, true, true);
- }
- }
-
- OS::get_singleton()->swap_buffers();
+ end_frame(true);
}
void RasterizerGLES3::blit_render_target_to_screen(RID p_render_target, const Rect2 &p_screen_rect, int p_screen) {
@@ -451,7 +421,6 @@ RasterizerGLES3::RasterizerGLES3() {
scene->storage = storage;
storage->scene = scene;
- prev_ticks = 0;
time_total = 0;
}
diff --git a/drivers/gles3/rasterizer_gles3.h b/drivers/gles3/rasterizer_gles3.h
index 5213101778..f4449ac0f9 100644
--- a/drivers/gles3/rasterizer_gles3.h
+++ b/drivers/gles3/rasterizer_gles3.h
@@ -44,7 +44,6 @@ class RasterizerGLES3 : public Rasterizer {
RasterizerCanvasGLES3 *canvas;
RasterizerSceneGLES3 *scene;
- uint64_t prev_ticks;
double time_total;
public:
@@ -55,7 +54,7 @@ public:
virtual void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale);
virtual void initialize();
- virtual void begin_frame();
+ virtual void begin_frame(double frame_step);
virtual void set_current_render_target(RID p_render_target);
virtual void restore_render_target();
virtual void clear_render_target(const Color &p_color);
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index 85b63a6481..eebdbe9493 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -355,7 +355,7 @@ bool RasterizerSceneGLES3::shadow_atlas_update_light(RID p_atlas, RID p_light_in
bool should_redraw = shadow_atlas->quadrants[q].shadows[s].version != p_light_version;
if (!should_realloc) {
- shadow_atlas->quadrants[q].shadows[s].version = p_light_version;
+ shadow_atlas->quadrants[q].shadows.write[s].version = p_light_version;
//already existing, see if it should redraw or it's just OK
return should_redraw;
}
@@ -365,7 +365,7 @@ bool RasterizerSceneGLES3::shadow_atlas_update_light(RID p_atlas, RID p_light_in
//find a better place
if (_shadow_atlas_find_shadow(shadow_atlas, valid_quadrants, valid_quadrant_count, shadow_atlas->quadrants[q].subdivision, tick, new_quadrant, new_shadow)) {
//found a better place!
- ShadowAtlas::Quadrant::Shadow *sh = &shadow_atlas->quadrants[new_quadrant].shadows[new_shadow];
+ ShadowAtlas::Quadrant::Shadow *sh = &shadow_atlas->quadrants[new_quadrant].shadows.write[new_shadow];
if (sh->owner.is_valid()) {
//is taken, but is invalid, erasing it
shadow_atlas->shadow_owners.erase(sh->owner);
@@ -374,8 +374,8 @@ bool RasterizerSceneGLES3::shadow_atlas_update_light(RID p_atlas, RID p_light_in
}
//erase previous
- shadow_atlas->quadrants[q].shadows[s].version = 0;
- shadow_atlas->quadrants[q].shadows[s].owner = RID();
+ shadow_atlas->quadrants[q].shadows.write[s].version = 0;
+ shadow_atlas->quadrants[q].shadows.write[s].owner = RID();
sh->owner = p_light_intance;
sh->alloc_tick = tick;
@@ -395,7 +395,7 @@ bool RasterizerSceneGLES3::shadow_atlas_update_light(RID p_atlas, RID p_light_in
//already existing, see if it should redraw or it's just OK
- shadow_atlas->quadrants[q].shadows[s].version = p_light_version;
+ shadow_atlas->quadrants[q].shadows.write[s].version = p_light_version;
return should_redraw;
}
@@ -405,7 +405,7 @@ bool RasterizerSceneGLES3::shadow_atlas_update_light(RID p_atlas, RID p_light_in
//find a better place
if (_shadow_atlas_find_shadow(shadow_atlas, valid_quadrants, valid_quadrant_count, -1, tick, new_quadrant, new_shadow)) {
//found a better place!
- ShadowAtlas::Quadrant::Shadow *sh = &shadow_atlas->quadrants[new_quadrant].shadows[new_shadow];
+ ShadowAtlas::Quadrant::Shadow *sh = &shadow_atlas->quadrants[new_quadrant].shadows.write[new_shadow];
if (sh->owner.is_valid()) {
//is taken, but is invalid, erasing it
shadow_atlas->shadow_owners.erase(sh->owner);
@@ -502,7 +502,7 @@ void RasterizerSceneGLES3::reflection_atlas_set_size(RID p_ref_atlas, int p_size
//erase probes reference to this
if (reflection_atlas->reflections[i].owner.is_valid()) {
ReflectionProbeInstance *reflection_probe_instance = reflection_probe_instance_owner.getornull(reflection_atlas->reflections[i].owner);
- reflection_atlas->reflections[i].owner = RID();
+ reflection_atlas->reflections.write[i].owner = RID();
ERR_CONTINUE(!reflection_probe_instance);
reflection_probe_instance->reflection_atlas_index = -1;
@@ -574,7 +574,7 @@ void RasterizerSceneGLES3::reflection_atlas_set_subdivision(RID p_ref_atlas, int
//erase probes reference to this
if (reflection_atlas->reflections[i].owner.is_valid()) {
ReflectionProbeInstance *reflection_probe_instance = reflection_probe_instance_owner.getornull(reflection_atlas->reflections[i].owner);
- reflection_atlas->reflections[i].owner = RID();
+ reflection_atlas->reflections.write[i].owner = RID();
ERR_CONTINUE(!reflection_probe_instance);
reflection_probe_instance->reflection_atlas_index = -1;
@@ -629,7 +629,7 @@ void RasterizerSceneGLES3::reflection_probe_release_atlas_index(RID p_instance)
ERR_FAIL_COND(reflection_atlas->reflections[rpi->reflection_atlas_index].owner != rpi->self);
- reflection_atlas->reflections[rpi->reflection_atlas_index].owner = RID();
+ reflection_atlas->reflections.write[rpi->reflection_atlas_index].owner = RID();
rpi->reflection_atlas_index = -1;
rpi->atlas = RID();
@@ -701,8 +701,8 @@ bool RasterizerSceneGLES3::reflection_probe_instance_begin_render(RID p_instance
victim_rpi->reflection_atlas_index = -1;
}
- reflection_atlas->reflections[best_free].owner = p_instance;
- reflection_atlas->reflections[best_free].last_frame = storage->frame.count;
+ reflection_atlas->reflections.write[best_free].owner = p_instance;
+ reflection_atlas->reflections.write[best_free].last_frame = storage->frame.count;
rpi->reflection_atlas_index = best_free;
rpi->atlas = p_reflection_atlas;
@@ -1190,6 +1190,7 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material *p_m
int tc = p_material->textures.size();
RID *textures = p_material->textures.ptrw();
ShaderLanguage::ShaderNode::Uniform::Hint *texture_hints = p_material->shader->texture_hints.ptrw();
+ const ShaderLanguage::DataType *texture_types = p_material->shader->texture_types.ptr();
state.current_main_tex = 0;
@@ -1198,39 +1199,17 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material *p_m
glActiveTexture(GL_TEXTURE0 + i);
GLenum target;
- GLuint tex;
+ GLuint tex = 0;
- RasterizerStorageGLES3::Texture *t = storage->texture_owner.getornull(textures[i]);
+ RasterizerStorageGLES3::Texture *t = storage->texture_owner.getptr(textures[i]);
- if (!t) {
- //check hints
- target = GL_TEXTURE_2D;
-
- switch (texture_hints[i]) {
- case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK_ALBEDO:
- case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK: {
- tex = storage->resources.black_tex;
- } break;
- case ShaderLanguage::ShaderNode::Uniform::HINT_ANISO: {
- tex = storage->resources.aniso_tex;
- } break;
- case ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL: {
- tex = storage->resources.normal_tex;
-
- } break;
- default: {
- tex = storage->resources.white_tex;
- } break;
- }
-
- } else {
+ if (t) {
if (t->redraw_if_visible) { //must check before proxy because this is often used with proxies
VisualServerRaster::redraw_request();
}
t = t->get_ptr(); //resolve for proxies
-
#ifdef TOOLS_ENABLED
if (t->detect_3d) {
t->detect_3d(t->detect_3d_ud);
@@ -1247,6 +1226,59 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material *p_m
target = t->target;
tex = t->tex_id;
+ } else {
+
+ switch (texture_types[i]) {
+ case ShaderLanguage::TYPE_ISAMPLER2D:
+ case ShaderLanguage::TYPE_USAMPLER2D:
+ case ShaderLanguage::TYPE_SAMPLER2D: {
+ target = GL_TEXTURE_2D;
+
+ switch (texture_hints[i]) {
+ case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK_ALBEDO:
+ case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK: {
+ tex = storage->resources.black_tex;
+ } break;
+ case ShaderLanguage::ShaderNode::Uniform::HINT_ANISO: {
+ tex = storage->resources.aniso_tex;
+ } break;
+ case ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL: {
+ tex = storage->resources.normal_tex;
+
+ } break;
+ default: {
+ tex = storage->resources.white_tex;
+ } break;
+ }
+
+ } break;
+
+ case ShaderLanguage::TYPE_SAMPLERCUBE: {
+ // TODO
+ } break;
+
+ case ShaderLanguage::TYPE_ISAMPLER3D:
+ case ShaderLanguage::TYPE_USAMPLER3D:
+ case ShaderLanguage::TYPE_SAMPLER3D: {
+
+ target = GL_TEXTURE_3D;
+
+ switch (texture_hints[i]) {
+
+ // TODO
+ default: {
+ tex = storage->resources.white_tex_3d;
+ } break;
+ }
+
+ } break;
+
+ case ShaderLanguage::TYPE_ISAMPLER2DARRAY:
+ case ShaderLanguage::TYPE_USAMPLER2DARRAY:
+ case ShaderLanguage::TYPE_SAMPLER2DARRAY: {
+ // TODO
+ } break;
+ }
}
glBindTexture(target, tex);
@@ -3848,8 +3880,8 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p
state.exposure_shader.set_conditional(ExposureShaderGLES3::EXPOSURE_END, false);
//last step, swap with the framebuffer exposure, so the right exposure is kept int he framebuffer
- SWAP(exposure_shrink[exposure_shrink.size() - 1].fbo, storage->frame.current_rt->exposure.fbo);
- SWAP(exposure_shrink[exposure_shrink.size() - 1].color, storage->frame.current_rt->exposure.color);
+ SWAP(exposure_shrink.write[exposure_shrink.size() - 1].fbo, storage->frame.current_rt->exposure.fbo);
+ SWAP(exposure_shrink.write[exposure_shrink.size() - 1].color, storage->frame.current_rt->exposure.color);
glViewport(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height);
@@ -4086,6 +4118,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
state.ubo_data.z_slope_scale = 0;
state.ubo_data.shadow_dual_paraboloid_render_side = 0;
state.ubo_data.shadow_dual_paraboloid_render_zfar = 0;
+ state.ubo_data.opaque_prepass_threshold = 0.99;
p_cam_projection.get_viewport_size(state.ubo_data.viewport_size[0], state.ubo_data.viewport_size[1]);
@@ -4698,6 +4731,7 @@ void RasterizerSceneGLES3::render_shadow(RID p_light, RID p_shadow_atlas, int p_
state.ubo_data.z_slope_scale = normal_bias;
state.ubo_data.shadow_dual_paraboloid_render_side = dp_direction;
state.ubo_data.shadow_dual_paraboloid_render_zfar = zfar;
+ state.ubo_data.opaque_prepass_threshold = 0.1;
_setup_environment(NULL, light_projection, light_transform);
@@ -4776,7 +4810,7 @@ bool RasterizerSceneGLES3::free(RID p_rid) {
uint32_t q = (key >> ShadowAtlas::QUADRANT_SHIFT) & 0x3;
uint32_t s = key & ShadowAtlas::SHADOW_INDEX_MASK;
- shadow_atlas->quadrants[q].shadows[s].owner = RID();
+ shadow_atlas->quadrants[q].shadows.write[s].owner = RID();
shadow_atlas->shadow_owners.erase(p_rid);
}
diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h
index 524212b9c1..cf387a69bc 100644
--- a/drivers/gles3/rasterizer_scene_gles3.h
+++ b/drivers/gles3/rasterizer_scene_gles3.h
@@ -141,6 +141,7 @@ public:
float subsurface_scatter_width;
float ambient_occlusion_affect_light;
float ambient_occlusion_affect_ssao;
+ float opaque_prepass_threshold;
uint32_t fog_depth_enabled;
float fog_depth_begin;
@@ -152,7 +153,7 @@ public:
float fog_height_max;
float fog_height_curve;
// make sure this struct is padded to be a multiple of 16 bytes for webgl
- float pad[3];
+ float pad[2];
} ubo_data;
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index e67b0bea21..a5c81d6c4d 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -595,7 +595,7 @@ RID RasterizerStorageGLES3::texture_create() {
return texture_owner.make_rid(texture);
}
-void RasterizerStorageGLES3::texture_allocate(RID p_texture, int p_width, int p_height, Image::Format p_format, uint32_t p_flags) {
+void RasterizerStorageGLES3::texture_allocate(RID p_texture, int p_width, int p_height, int p_depth_3d, Image::Format p_format, VisualServer::TextureType p_type, uint32_t p_flags) {
GLenum format;
GLenum internal_format;
@@ -612,15 +612,37 @@ void RasterizerStorageGLES3::texture_allocate(RID p_texture, int p_width, int p_
ERR_FAIL_COND(!texture);
texture->width = p_width;
texture->height = p_height;
+ texture->depth = p_depth_3d;
texture->format = p_format;
texture->flags = p_flags;
texture->stored_cube_sides = 0;
- texture->target = (p_flags & VS::TEXTURE_FLAG_CUBEMAP) ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
+
+ texture->type = p_type;
+
+ switch (p_type) {
+ case VS::TEXTURE_TYPE_2D: {
+ texture->target = GL_TEXTURE_2D;
+ texture->images.resize(1);
+ } break;
+ case VS::TEXTURE_TYPE_CUBEMAP: {
+ texture->target = GL_TEXTURE_CUBE_MAP;
+ texture->images.resize(6);
+ } break;
+ case VS::TEXTURE_TYPE_2D_ARRAY: {
+ texture->target = GL_TEXTURE_2D_ARRAY;
+ texture->images.resize(p_depth_3d);
+ } break;
+ case VS::TEXTURE_TYPE_3D: {
+ texture->target = GL_TEXTURE_3D;
+ texture->images.resize(p_depth_3d);
+ } break;
+ }
_get_gl_image_and_format(Ref<Image>(), texture->format, texture->flags, format, internal_format, type, compressed, srgb);
texture->alloc_width = texture->width;
texture->alloc_height = texture->height;
+ texture->alloc_depth = texture->depth;
texture->gl_format_cache = format;
texture->gl_type_cache = type;
@@ -633,7 +655,34 @@ void RasterizerStorageGLES3::texture_allocate(RID p_texture, int p_width, int p_
glActiveTexture(GL_TEXTURE0);
glBindTexture(texture->target, texture->tex_id);
- if (p_flags & VS::TEXTURE_FLAG_USED_FOR_STREAMING) {
+ if (p_type == VS::TEXTURE_TYPE_3D || p_type == VS::TEXTURE_TYPE_2D_ARRAY) {
+
+ int width = p_width;
+ int height = p_height;
+ int depth = p_depth_3d;
+
+ int mipmaps = 0;
+
+ while (width != 1 && height != 1) {
+ glTexImage3D(texture->target, 0, internal_format, width, height, depth, 0, format, type, NULL);
+
+ width = MAX(1, width / 2);
+ height = MAX(1, height / 2);
+
+ if (p_type == VS::TEXTURE_TYPE_3D) {
+ depth = MAX(1, depth / 2);
+ }
+
+ mipmaps++;
+
+ if (!(p_flags & VS::TEXTURE_FLAG_MIPMAPS))
+ break;
+ }
+
+ glTexParameteri(texture->target, GL_TEXTURE_BASE_LEVEL, 0);
+ glTexParameteri(texture->target, GL_TEXTURE_MAX_LEVEL, mipmaps - 1);
+
+ } else 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);
}
@@ -641,7 +690,7 @@ void RasterizerStorageGLES3::texture_allocate(RID p_texture, int p_width, int p_
texture->active = true;
}
-void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Ref<Image> &p_image, VS::CubeMapSide p_cube_side) {
+void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Ref<Image> &p_image, int p_layer) {
Texture *texture = texture_owner.get(p_texture);
@@ -658,7 +707,7 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Ref<Image> &p
bool srgb;
if (config.keep_original_textures && !(texture->flags & VS::TEXTURE_FLAG_USED_FOR_STREAMING)) {
- texture->images[p_cube_side] = p_image;
+ texture->images.write[p_layer] = p_image;
}
Ref<Image> img = _get_gl_image_and_format(p_image, p_image->get_format(), texture->flags, format, internal_format, type, compressed, srgb);
@@ -677,7 +726,23 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Ref<Image> &p
}
};
- GLenum blit_target = (texture->target == GL_TEXTURE_CUBE_MAP) ? _cube_side_enum[p_cube_side] : GL_TEXTURE_2D;
+ GLenum blit_target;
+
+ switch (texture->type) {
+ case VS::TEXTURE_TYPE_2D: {
+ blit_target = GL_TEXTURE_2D;
+ } break;
+ case VS::TEXTURE_TYPE_CUBEMAP: {
+ ERR_FAIL_INDEX(p_layer, 6);
+ blit_target = _cube_side_enum[p_layer];
+ } break;
+ case VS::TEXTURE_TYPE_2D_ARRAY: {
+ blit_target = GL_TEXTURE_2D_ARRAY;
+ } break;
+ case VS::TEXTURE_TYPE_3D: {
+ blit_target = GL_TEXTURE_3D;
+ } break;
+ }
texture->data_size = img->get_data().size();
PoolVector<uint8_t>::Read read = img->get_data().read();
@@ -785,20 +850,36 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Ref<Image> &p
//print_line("mipmap: "+itos(i)+" size: "+itos(size)+" w: "+itos(mm_w)+", h: "+itos(mm_h));
- if (texture->compressed) {
- glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+ if (texture->type == VS::TEXTURE_TYPE_2D || texture->type == VS::TEXTURE_TYPE_CUBEMAP) {
- int bw = w;
- int bh = h;
+ if (texture->compressed) {
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
- glCompressedTexImage2D(blit_target, i, internal_format, bw, bh, 0, size, &read[ofs]);
+ int bw = w;
+ int bh = h;
+ glCompressedTexImage2D(blit_target, i, internal_format, bw, bh, 0, size, &read[ofs]);
+
+ } else {
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ if (texture->flags & VS::TEXTURE_FLAG_USED_FOR_STREAMING) {
+ glTexSubImage2D(blit_target, i, 0, 0, w, h, format, type, &read[ofs]);
+ } else {
+ glTexImage2D(blit_target, i, internal_format, w, h, 0, format, type, &read[ofs]);
+ }
+ }
} else {
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- if (texture->flags & VS::TEXTURE_FLAG_USED_FOR_STREAMING) {
- glTexSubImage2D(blit_target, i, 0, 0, w, h, format, type, &read[ofs]);
+ if (texture->compressed) {
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+
+ int bw = w;
+ int bh = h;
+
+ glCompressedTexSubImage3D(blit_target, i, 0, 0, p_layer, bw, bh, 1, internal_format, size, &read[ofs]);
} else {
- glTexImage2D(blit_target, i, internal_format, w, h, 0, format, type, &read[ofs]);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+ glTexSubImage3D(blit_target, i, 0, 0, p_layer, w, h, 1, format, type, &read[ofs]);
}
}
tsize += size;
@@ -813,14 +894,17 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Ref<Image> &p
//printf("texture: %i x %i - size: %i - total: %i\n",texture->width,texture->height,tsize,_rinfo.texture_mem);
- texture->stored_cube_sides |= (1 << p_cube_side);
+ texture->stored_cube_sides |= (1 << p_layer);
- if ((texture->flags & VS::TEXTURE_FLAG_MIPMAPS) && mipmaps == 1 && !texture->ignore_mipmaps && (!(texture->flags & VS::TEXTURE_FLAG_CUBEMAP) || texture->stored_cube_sides == (1 << 6) - 1)) {
+ if ((texture->type == VS::TEXTURE_TYPE_2D || texture->type == VS::TEXTURE_TYPE_CUBEMAP) && (texture->flags & VS::TEXTURE_FLAG_MIPMAPS) && mipmaps == 1 && !texture->ignore_mipmaps && (texture->type != VS::TEXTURE_TYPE_CUBEMAP || texture->stored_cube_sides == (1 << 6) - 1)) {
//generate mipmaps if they were requested and the image does not contain them
glGenerateMipmap(texture->target);
} else if (mipmaps > 1) {
glTexParameteri(texture->target, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(texture->target, GL_TEXTURE_MAX_LEVEL, mipmaps - 1);
+ } else {
+ glTexParameteri(texture->target, GL_TEXTURE_BASE_LEVEL, 0);
+ glTexParameteri(texture->target, GL_TEXTURE_MAX_LEVEL, 0);
}
texture->mipmaps = mipmaps;
@@ -831,7 +915,7 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Ref<Image> &p
// Uploads pixel data to a sub-region of a texture, for the specified mipmap.
// The texture pixels must have been allocated before, because most features seen in texture_set_data() make no sense in a partial update.
// TODO If we want this to be usable without pre-filling pixels with a full image, we have to call glTexImage2D() with null data.
-void RasterizerStorageGLES3::texture_set_data_partial(RID p_texture, const Ref<Image> &p_image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int p_dst_mip, VS::CubeMapSide p_cube_side) {
+void RasterizerStorageGLES3::texture_set_data_partial(RID p_texture, const Ref<Image> &p_image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int p_dst_mip, int p_layer) {
Texture *texture = texture_owner.get(p_texture);
@@ -859,7 +943,23 @@ void RasterizerStorageGLES3::texture_set_data_partial(RID p_texture, const Ref<I
Ref<Image> img = _get_gl_image_and_format(p_sub_img, p_sub_img->get_format(), texture->flags, format, internal_format, type, compressed, srgb);
- GLenum blit_target = (texture->target == GL_TEXTURE_CUBE_MAP) ? _cube_side_enum[p_cube_side] : GL_TEXTURE_2D;
+ GLenum blit_target;
+
+ switch (texture->type) {
+ case VS::TEXTURE_TYPE_2D: {
+ blit_target = GL_TEXTURE_2D;
+ } break;
+ case VS::TEXTURE_TYPE_CUBEMAP: {
+ ERR_FAIL_INDEX(p_layer, 6);
+ blit_target = _cube_side_enum[p_layer];
+ } break;
+ case VS::TEXTURE_TYPE_2D_ARRAY: {
+ blit_target = GL_TEXTURE_2D_ARRAY;
+ } break;
+ case VS::TEXTURE_TYPE_3D: {
+ blit_target = GL_TEXTURE_3D;
+ } break;
+ }
PoolVector<uint8_t>::Read read = img->get_data().read();
@@ -869,18 +969,38 @@ void RasterizerStorageGLES3::texture_set_data_partial(RID p_texture, const Ref<I
int src_data_size = img->get_data().size();
int src_ofs = 0;
- if (texture->compressed) {
- glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
- glCompressedTexSubImage2D(blit_target, p_dst_mip, dst_x, dst_y, src_w, src_h, internal_format, src_data_size, &read[src_ofs]);
+ if (texture->type == VS::TEXTURE_TYPE_2D || texture->type == VS::TEXTURE_TYPE_CUBEMAP) {
+ if (texture->compressed) {
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+ glCompressedTexSubImage2D(blit_target, p_dst_mip, dst_x, dst_y, src_w, src_h, internal_format, src_data_size, &read[src_ofs]);
+
+ } else {
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ // `format` has to match the internal_format used when the texture was created
+ glTexSubImage2D(blit_target, p_dst_mip, dst_x, dst_y, src_w, src_h, format, type, &read[src_ofs]);
+ }
+ } else {
+ if (texture->compressed) {
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+ glCompressedTexSubImage3D(blit_target, p_dst_mip, dst_x, dst_y, p_layer, src_w, src_h, 1, format, src_data_size, &read[src_ofs]);
+ } else {
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ // `format` has to match the internal_format used when the texture was created
+ glTexSubImage3D(blit_target, p_dst_mip, dst_x, dst_y, p_layer, src_w, src_h, 1, format, type, &read[src_ofs]);
+ }
+ }
+
+ if (texture->flags & VS::TEXTURE_FLAG_FILTER) {
+
+ glTexParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear Filtering
} else {
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- // `format` has to match the internal_format used when the texture was created
- glTexSubImage2D(blit_target, p_dst_mip, dst_x, dst_y, src_w, src_h, format, type, &read[src_ofs]);
+
+ glTexParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // raw Filtering
}
}
-Ref<Image> RasterizerStorageGLES3::texture_get_data(RID p_texture, VS::CubeMapSide p_cube_side) const {
+Ref<Image> RasterizerStorageGLES3::texture_get_data(RID p_texture, int p_layer) const {
Texture *texture = texture_owner.get(p_texture);
@@ -888,8 +1008,8 @@ Ref<Image> RasterizerStorageGLES3::texture_get_data(RID p_texture, VS::CubeMapSi
ERR_FAIL_COND_V(!texture->active, Ref<Image>());
ERR_FAIL_COND_V(texture->data_size == 0 && !texture->render_target, Ref<Image>());
- if (!texture->images[p_cube_side].is_null()) {
- return texture->images[p_cube_side];
+ if (texture->type == VS::TEXTURE_TYPE_CUBEMAP && p_layer < 6 && !texture->images[p_layer].is_null()) {
+ return texture->images[p_layer];
}
#ifdef GLES_OVER_GL
@@ -977,10 +1097,10 @@ void RasterizerStorageGLES3::texture_set_flags(RID p_texture, uint32_t p_flags)
bool had_mipmaps = texture->flags & VS::TEXTURE_FLAG_MIPMAPS;
+ texture->flags = p_flags;
+
glActiveTexture(GL_TEXTURE0);
glBindTexture(texture->target, texture->tex_id);
- uint32_t cube = texture->flags & VS::TEXTURE_FLAG_CUBEMAP;
- texture->flags = p_flags | cube; // can't remove a cube from being a cube
if (((texture->flags & VS::TEXTURE_FLAG_REPEAT) || (texture->flags & VS::TEXTURE_FLAG_MIRRORED_REPEAT)) && texture->target != GL_TEXTURE_CUBE_MAP) {
@@ -1058,6 +1178,14 @@ Image::Format RasterizerStorageGLES3::texture_get_format(RID p_texture) const {
return texture->format;
}
+
+VisualServer::TextureType RasterizerStorageGLES3::texture_get_type(RID p_texture) const {
+ Texture *texture = texture_owner.get(p_texture);
+
+ ERR_FAIL_COND_V(!texture, VS::TEXTURE_TYPE_2D);
+
+ return texture->type;
+}
uint32_t RasterizerStorageGLES3::texture_get_texid(RID p_texture) const {
Texture *texture = texture_owner.get(p_texture);
@@ -1083,7 +1211,16 @@ uint32_t RasterizerStorageGLES3::texture_get_height(RID p_texture) const {
return texture->height;
}
-void RasterizerStorageGLES3::texture_set_size_override(RID p_texture, int p_width, int p_height) {
+uint32_t RasterizerStorageGLES3::texture_get_depth(RID p_texture) const {
+
+ Texture *texture = texture_owner.get(p_texture);
+
+ ERR_FAIL_COND_V(!texture, 0);
+
+ return texture->depth;
+}
+
+void RasterizerStorageGLES3::texture_set_size_override(RID p_texture, int p_width, int p_height, int p_depth) {
Texture *texture = texture_owner.get(p_texture);
@@ -1123,8 +1260,9 @@ void RasterizerStorageGLES3::texture_debug_usage(List<VS::TextureInfo> *r_info)
VS::TextureInfo tinfo;
tinfo.path = t->path;
tinfo.format = t->format;
- tinfo.size.x = t->alloc_width;
- tinfo.size.y = t->alloc_height;
+ tinfo.width = t->alloc_width;
+ tinfo.height = t->alloc_height;
+ tinfo.depth = 0;
tinfo.bytes = t->total_data_size;
r_info->push_back(tinfo);
}
@@ -1169,7 +1307,7 @@ RID RasterizerStorageGLES3::texture_create_radiance_cubemap(RID p_source, int p_
Texture *texture = texture_owner.get(p_source);
ERR_FAIL_COND_V(!texture, RID());
- ERR_FAIL_COND_V(!(texture->flags & VS::TEXTURE_FLAG_CUBEMAP), RID());
+ ERR_FAIL_COND_V(texture->type != VS::TEXTURE_TYPE_CUBEMAP, RID());
bool use_float = config.hdr_supported;
@@ -1285,7 +1423,8 @@ RID RasterizerStorageGLES3::texture_create_radiance_cubemap(RID p_source, int p_
Texture *ctex = memnew(Texture);
- ctex->flags = VS::TEXTURE_FLAG_CUBEMAP | VS::TEXTURE_FLAG_MIPMAPS | VS::TEXTURE_FLAG_FILTER;
+ ctex->type = VS::TEXTURE_TYPE_CUBEMAP;
+ ctex->flags = VS::TEXTURE_FLAG_MIPMAPS | VS::TEXTURE_FLAG_FILTER;
ctex->width = p_resolution;
ctex->height = p_resolution;
ctex->alloc_width = p_resolution;
@@ -1765,6 +1904,7 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
p_shader->ubo_offsets = gen_code.uniform_offsets;
p_shader->texture_count = gen_code.texture_uniforms.size();
p_shader->texture_hints = gen_code.texture_hints;
+ p_shader->texture_types = gen_code.texture_types;
p_shader->uses_vertex_time = gen_code.uses_vertex_time;
p_shader->uses_fragment_time = gen_code.uses_fragment_time;
@@ -1875,6 +2015,13 @@ void RasterizerStorageGLES3::shader_get_param_list(RID p_shader, List<PropertyIn
pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
pi.hint_string = "Texture";
} break;
+ case ShaderLanguage::TYPE_SAMPLER3D:
+ case ShaderLanguage::TYPE_ISAMPLER3D:
+ case ShaderLanguage::TYPE_USAMPLER3D: {
+ pi.type = Variant::OBJECT;
+ pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
+ pi.hint_string = "Texture3D";
+ } break;
case ShaderLanguage::TYPE_SAMPLERCUBE: {
pi.type = Variant::OBJECT;
@@ -2649,6 +2796,7 @@ void RasterizerStorageGLES3::_update_material(Material *material) {
//set up the texture array, for easy access when it needs to be drawn
if (material->shader && material->shader->texture_count) {
+ material->texture_is_3d.resize(material->shader->texture_count);
material->textures.resize(material->shader->texture_count);
for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = material->shader->uniforms.front(); E; E = E->next()) {
@@ -2658,6 +2806,16 @@ void RasterizerStorageGLES3::_update_material(Material *material) {
RID texture;
+ switch (E->get().type) {
+ case ShaderLanguage::TYPE_SAMPLER3D:
+ case ShaderLanguage::TYPE_SAMPLER2DARRAY: {
+ material->texture_is_3d.write[E->get().texture_order] = true;
+ } break;
+ default: {
+ material->texture_is_3d.write[E->get().texture_order] = false;
+ } break;
+ }
+
Map<StringName, Variant>::Element *V = material->params.find(E->key());
if (V) {
texture = V->get();
@@ -2670,11 +2828,12 @@ void RasterizerStorageGLES3::_update_material(Material *material) {
}
}
- material->textures[E->get().texture_order] = texture;
+ material->textures.write[E->get().texture_order] = texture;
}
} else {
material->textures.clear();
+ material->texture_is_3d.clear();
}
}
@@ -2975,9 +3134,9 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh, uint32_t p_format, VS:
for (int i = 0; i < surface->skeleton_bone_used.size(); i++) {
if (surface->skeleton_bone_aabb[i].size.x < 0 || surface->skeleton_bone_aabb[i].size.y < 0 || surface->skeleton_bone_aabb[i].size.z < 0) {
- surface->skeleton_bone_used[i] = false;
+ surface->skeleton_bone_used.write[i] = false;
} else {
- surface->skeleton_bone_used[i] = true;
+ surface->skeleton_bone_used.write[i] = true;
}
}
@@ -3240,7 +3399,7 @@ void RasterizerStorageGLES3::mesh_surface_update_region(RID p_mesh, int p_surfac
PoolVector<uint8_t>::Read r = p_data.read();
- glBindBuffer(GL_ARRAY_BUFFER, mesh->surfaces[p_surface]->array_id);
+ glBindBuffer(GL_ARRAY_BUFFER, mesh->surfaces[p_surface]->vertex_id);
glBufferSubData(GL_ARRAY_BUFFER, p_offset, total_size, r.ptr());
glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
}
@@ -3404,6 +3563,7 @@ Vector<PoolVector<uint8_t> > RasterizerStorageGLES3::mesh_surface_get_blend_shap
return bsarr;
}
+
Vector<AABB> RasterizerStorageGLES3::mesh_surface_get_skeleton_aabb(RID p_mesh, int p_surface) const {
const Mesh *mesh = mesh_owner.getornull(p_mesh);
@@ -3455,6 +3615,7 @@ void RasterizerStorageGLES3::mesh_remove_surface(RID p_mesh, int p_surface) {
mesh->instance_change_notify();
}
+
int RasterizerStorageGLES3::mesh_get_surface_count(RID p_mesh) const {
const Mesh *mesh = mesh_owner.getornull(p_mesh);
@@ -3468,6 +3629,7 @@ void RasterizerStorageGLES3::mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb
ERR_FAIL_COND(!mesh);
mesh->custom_aabb = p_aabb;
+ mesh->instance_change_notify();
}
AABB RasterizerStorageGLES3::mesh_get_custom_aabb(RID p_mesh) const {
@@ -3875,29 +4037,29 @@ void RasterizerStorageGLES3::multimesh_allocate(RID p_multimesh, int p_instances
int custom_data_from = 0;
if (multimesh->transform_format == VS::MULTIMESH_TRANSFORM_2D) {
- multimesh->data[i + 0] = 1.0;
- multimesh->data[i + 1] = 0.0;
- multimesh->data[i + 2] = 0.0;
- multimesh->data[i + 3] = 0.0;
- multimesh->data[i + 4] = 0.0;
- multimesh->data[i + 5] = 1.0;
- multimesh->data[i + 6] = 0.0;
- multimesh->data[i + 7] = 0.0;
+ multimesh->data.write[i + 0] = 1.0;
+ multimesh->data.write[i + 1] = 0.0;
+ multimesh->data.write[i + 2] = 0.0;
+ multimesh->data.write[i + 3] = 0.0;
+ multimesh->data.write[i + 4] = 0.0;
+ multimesh->data.write[i + 5] = 1.0;
+ multimesh->data.write[i + 6] = 0.0;
+ multimesh->data.write[i + 7] = 0.0;
color_from = 8;
custom_data_from = 8;
} else {
- multimesh->data[i + 0] = 1.0;
- multimesh->data[i + 1] = 0.0;
- multimesh->data[i + 2] = 0.0;
- multimesh->data[i + 3] = 0.0;
- multimesh->data[i + 4] = 0.0;
- multimesh->data[i + 5] = 1.0;
- multimesh->data[i + 6] = 0.0;
- multimesh->data[i + 7] = 0.0;
- multimesh->data[i + 8] = 0.0;
- multimesh->data[i + 9] = 0.0;
- multimesh->data[i + 10] = 1.0;
- multimesh->data[i + 11] = 0.0;
+ multimesh->data.write[i + 0] = 1.0;
+ multimesh->data.write[i + 1] = 0.0;
+ multimesh->data.write[i + 2] = 0.0;
+ multimesh->data.write[i + 3] = 0.0;
+ multimesh->data.write[i + 4] = 0.0;
+ multimesh->data.write[i + 5] = 1.0;
+ multimesh->data.write[i + 6] = 0.0;
+ multimesh->data.write[i + 7] = 0.0;
+ multimesh->data.write[i + 8] = 0.0;
+ multimesh->data.write[i + 9] = 0.0;
+ multimesh->data.write[i + 10] = 1.0;
+ multimesh->data.write[i + 11] = 0.0;
color_from = 12;
custom_data_from = 12;
}
@@ -3912,14 +4074,14 @@ void RasterizerStorageGLES3::multimesh_allocate(RID p_multimesh, int p_instances
} cu;
cu.colu = 0xFFFFFFFF;
- multimesh->data[i + color_from + 0] = cu.colf;
+ multimesh->data.write[i + color_from + 0] = cu.colf;
custom_data_from = color_from + 1;
} else if (multimesh->color_format == VS::MULTIMESH_COLOR_FLOAT) {
- multimesh->data[i + color_from + 0] = 1.0;
- multimesh->data[i + color_from + 1] = 1.0;
- multimesh->data[i + color_from + 2] = 1.0;
- multimesh->data[i + color_from + 3] = 1.0;
+ multimesh->data.write[i + color_from + 0] = 1.0;
+ multimesh->data.write[i + color_from + 1] = 1.0;
+ multimesh->data.write[i + color_from + 2] = 1.0;
+ multimesh->data.write[i + color_from + 3] = 1.0;
custom_data_from = color_from + 4;
}
@@ -3933,13 +4095,13 @@ void RasterizerStorageGLES3::multimesh_allocate(RID p_multimesh, int p_instances
} cu;
cu.colu = 0;
- multimesh->data[i + custom_data_from + 0] = cu.colf;
+ multimesh->data.write[i + custom_data_from + 0] = cu.colf;
} else if (multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_FLOAT) {
- multimesh->data[i + custom_data_from + 0] = 0.0;
- multimesh->data[i + custom_data_from + 1] = 0.0;
- multimesh->data[i + custom_data_from + 2] = 0.0;
- multimesh->data[i + custom_data_from + 3] = 0.0;
+ multimesh->data.write[i + custom_data_from + 0] = 0.0;
+ multimesh->data.write[i + custom_data_from + 1] = 0.0;
+ multimesh->data.write[i + custom_data_from + 2] = 0.0;
+ multimesh->data.write[i + custom_data_from + 3] = 0.0;
}
}
@@ -4001,7 +4163,7 @@ void RasterizerStorageGLES3::multimesh_instance_set_transform(RID p_multimesh, i
ERR_FAIL_COND(multimesh->transform_format == VS::MULTIMESH_TRANSFORM_2D);
int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats;
- float *dataptr = &multimesh->data[stride * p_index];
+ float *dataptr = &multimesh->data.write[stride * p_index];
dataptr[0] = p_transform.basis.elements[0][0];
dataptr[1] = p_transform.basis.elements[0][1];
@@ -4032,7 +4194,7 @@ void RasterizerStorageGLES3::multimesh_instance_set_transform_2d(RID p_multimesh
ERR_FAIL_COND(multimesh->transform_format == VS::MULTIMESH_TRANSFORM_3D);
int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats;
- float *dataptr = &multimesh->data[stride * p_index];
+ float *dataptr = &multimesh->data.write[stride * p_index];
dataptr[0] = p_transform.elements[0][0];
dataptr[1] = p_transform.elements[1][0];
@@ -4058,7 +4220,7 @@ void RasterizerStorageGLES3::multimesh_instance_set_color(RID p_multimesh, int p
ERR_FAIL_COND(multimesh->color_format == VS::MULTIMESH_COLOR_NONE);
int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats;
- float *dataptr = &multimesh->data[stride * p_index + multimesh->xform_floats];
+ float *dataptr = &multimesh->data.write[stride * p_index + multimesh->xform_floats];
if (multimesh->color_format == VS::MULTIMESH_COLOR_8BIT) {
@@ -4091,7 +4253,7 @@ void RasterizerStorageGLES3::multimesh_instance_set_custom_data(RID p_multimesh,
ERR_FAIL_COND(multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_NONE);
int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats;
- float *dataptr = &multimesh->data[stride * p_index + multimesh->xform_floats + multimesh->color_floats];
+ float *dataptr = &multimesh->data.write[stride * p_index + multimesh->xform_floats + multimesh->color_floats];
if (multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_8BIT) {
@@ -4131,7 +4293,7 @@ Transform RasterizerStorageGLES3::multimesh_instance_get_transform(RID p_multime
ERR_FAIL_COND_V(multimesh->transform_format == VS::MULTIMESH_TRANSFORM_2D, Transform());
int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats;
- float *dataptr = &multimesh->data[stride * p_index];
+ float *dataptr = &multimesh->data.write[stride * p_index];
Transform xform;
@@ -4158,7 +4320,7 @@ Transform2D RasterizerStorageGLES3::multimesh_instance_get_transform_2d(RID p_mu
ERR_FAIL_COND_V(multimesh->transform_format == VS::MULTIMESH_TRANSFORM_3D, Transform2D());
int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats;
- float *dataptr = &multimesh->data[stride * p_index];
+ float *dataptr = &multimesh->data.write[stride * p_index];
Transform2D xform;
@@ -4180,7 +4342,7 @@ Color RasterizerStorageGLES3::multimesh_instance_get_color(RID p_multimesh, int
ERR_FAIL_COND_V(multimesh->color_format == VS::MULTIMESH_COLOR_NONE, Color());
int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats;
- float *dataptr = &multimesh->data[stride * p_index + multimesh->xform_floats];
+ float *dataptr = &multimesh->data.write[stride * p_index + multimesh->xform_floats];
if (multimesh->color_format == VS::MULTIMESH_COLOR_8BIT) {
union {
@@ -4213,7 +4375,7 @@ Color RasterizerStorageGLES3::multimesh_instance_get_custom_data(RID p_multimesh
ERR_FAIL_COND_V(multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_NONE, Color());
int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats;
- float *dataptr = &multimesh->data[stride * p_index + multimesh->xform_floats + multimesh->color_floats];
+ float *dataptr = &multimesh->data.write[stride * p_index + multimesh->xform_floats + multimesh->color_floats];
if (multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_8BIT) {
union {
@@ -5769,7 +5931,7 @@ void RasterizerStorageGLES3::particles_set_draw_pass_mesh(RID p_particles, int p
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
ERR_FAIL_INDEX(p_pass, particles->draw_passes.size());
- particles->draw_passes[p_pass] = p_mesh;
+ particles->draw_passes.write[p_pass] = p_mesh;
}
void RasterizerStorageGLES3::particles_restart(RID p_particles) {
@@ -6643,7 +6805,7 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) {
for (int j = 0; j < rt->effects.mip_maps[i].sizes.size(); j++) {
- RenderTarget::Effects::MipMaps::Size &mm = rt->effects.mip_maps[i].sizes[j];
+ RenderTarget::Effects::MipMaps::Size &mm = rt->effects.mip_maps[i].sizes.write[j];
glGenFramebuffers(1, &mm.fbo);
glBindFramebuffer(GL_FRAMEBUFFER, mm.fbo);
@@ -6996,6 +7158,7 @@ bool RasterizerStorageGLES3::free(RID p_rid) {
info.texture_mem -= texture->total_data_size;
texture_owner.free(p_rid);
memdelete(texture);
+
} else if (sky_owner.owns(p_rid)) {
// delete the sky
Sky *sky = sky_owner.get(p_rid);
@@ -7055,7 +7218,7 @@ bool RasterizerStorageGLES3::free(RID p_rid) {
for (int i = 0; i < ins->materials.size(); i++) {
if (ins->materials[i] == p_rid) {
- ins->materials[i] = RID();
+ ins->materials.write[i] = RID();
}
}
}
@@ -7405,6 +7568,15 @@ void RasterizerStorageGLES3::initialize() {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 8, 8, 0, GL_RGB, GL_UNSIGNED_BYTE, anisotexdata);
glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
+
+ glGenTextures(1, &resources.white_tex_3d);
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_3D, resources.white_tex_3d);
+ glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB, 2, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, whitetexdata);
+
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 0);
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0);
}
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &config.max_texture_image_units);
@@ -7486,7 +7658,6 @@ void RasterizerStorageGLES3::initialize() {
#endif
frame.count = 0;
- frame.prev_tick = 0;
frame.delta = 0;
frame.current_rt = NULL;
config.keep_original_textures = false;
diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h
index 80df21941b..f55c8026ea 100644
--- a/drivers/gles3/rasterizer_storage_gles3.h
+++ b/drivers/gles3/rasterizer_storage_gles3.h
@@ -123,6 +123,8 @@ public:
GLuint normal_tex;
GLuint aniso_tex;
+ GLuint white_tex_3d;
+
GLuint quadie;
GLuint quadie_array;
@@ -248,9 +250,10 @@ public:
String path;
uint32_t flags;
- int width, height;
- int alloc_width, alloc_height;
+ int width, height, depth;
+ int alloc_width, alloc_height, alloc_depth;
Image::Format format;
+ VS::TextureType type;
GLenum target;
GLenum gl_format_cache;
@@ -274,7 +277,7 @@ public:
RenderTarget *render_target;
- Ref<Image> images[6];
+ Vector<Ref<Image> > images;
VisualServer::TextureDetectCallback detect_3d;
void *detect_3d_ud;
@@ -340,17 +343,19 @@ public:
Ref<Image> _get_gl_image_and_format(const Ref<Image> &p_image, Image::Format p_format, uint32_t p_flags, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type, bool &r_compressed, bool &srgb);
virtual RID texture_create();
- virtual void texture_allocate(RID p_texture, int p_width, int p_height, Image::Format p_format, uint32_t p_flags = VS::TEXTURE_FLAGS_DEFAULT);
- virtual void texture_set_data(RID p_texture, const Ref<Image> &p_image, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT);
- virtual void texture_set_data_partial(RID p_texture, const Ref<Image> &p_image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int p_dst_mip, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT);
- virtual Ref<Image> texture_get_data(RID p_texture, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT) const;
+ 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);
+ virtual void texture_set_data(RID p_texture, const Ref<Image> &p_image, int p_layer = 0);
+ virtual void texture_set_data_partial(RID p_texture, const Ref<Image> &p_image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int p_dst_mip, int p_layer = 0);
+ virtual Ref<Image> texture_get_data(RID p_texture, int p_layer = 0) const;
virtual void texture_set_flags(RID p_texture, uint32_t p_flags);
virtual uint32_t texture_get_flags(RID p_texture) const;
virtual Image::Format texture_get_format(RID p_texture) const;
+ virtual VS::TextureType texture_get_type(RID p_texture) const;
virtual uint32_t texture_get_texid(RID p_texture) const;
virtual uint32_t texture_get_width(RID p_texture) const;
virtual uint32_t texture_get_height(RID p_texture) const;
- virtual void texture_set_size_override(RID p_texture, int p_width, int p_height);
+ virtual uint32_t texture_get_depth(RID p_texture) const;
+ virtual void texture_set_size_override(RID p_texture, int p_width, int p_height, int p_depth);
virtual void texture_set_path(RID p_texture, const String &p_path);
virtual String texture_get_path(RID p_texture) const;
@@ -410,6 +415,7 @@ public:
Map<StringName, RID> default_textures;
+ Vector<ShaderLanguage::DataType> texture_types;
Vector<ShaderLanguage::ShaderNode::Uniform::Hint> texture_hints;
bool valid;
@@ -532,6 +538,7 @@ public:
Map<StringName, Variant> params;
SelfList<Material> list;
SelfList<Material> dirty_list;
+ Vector<bool> texture_is_3d;
Vector<RID> textures;
float line_width;
int render_priority;
@@ -693,7 +700,6 @@ public:
AABB custom_aabb;
mutable uint64_t last_pass;
SelfList<MultiMesh>::List multimeshes;
-
_FORCE_INLINE_ void update_multimeshes() {
SelfList<MultiMesh> *mm = multimeshes.first();
@@ -1428,7 +1434,6 @@ public:
int canvas_draw_commands;
float time[4];
float delta;
- uint64_t prev_tick;
uint64_t count;
} frame;
diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp
index f3ba7aa408..0c353d42bb 100644
--- a/drivers/gles3/shader_compiler_gles3.cpp
+++ b/drivers/gles3/shader_compiler_gles3.cpp
@@ -341,6 +341,7 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
r_gen_code.texture_uniforms.resize(max_texture_uniforms);
r_gen_code.texture_hints.resize(max_texture_uniforms);
+ r_gen_code.texture_types.resize(max_texture_uniforms);
Vector<int> uniform_sizes;
Vector<int> uniform_alignments;
@@ -365,17 +366,18 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
if (SL::is_sampler_type(E->get().type)) {
r_gen_code.vertex_global += ucode;
r_gen_code.fragment_global += ucode;
- r_gen_code.texture_uniforms[E->get().texture_order] = _mkid(E->key());
- r_gen_code.texture_hints[E->get().texture_order] = E->get().hint;
+ r_gen_code.texture_uniforms.write[E->get().texture_order] = _mkid(E->key());
+ r_gen_code.texture_hints.write[E->get().texture_order] = E->get().hint;
+ r_gen_code.texture_types.write[E->get().texture_order] = E->get().type;
} else {
if (!uses_uniforms) {
r_gen_code.defines.push_back(String("#define USE_MATERIAL\n").ascii());
uses_uniforms = true;
}
- uniform_defines[E->get().order] = ucode;
- uniform_sizes[E->get().order] = _get_datatype_size(E->get().type);
- uniform_alignments[E->get().order] = _get_datatype_alignment(E->get().type);
+ uniform_defines.write[E->get().order] = ucode;
+ uniform_sizes.write[E->get().order] = _get_datatype_size(E->get().type);
+ uniform_alignments.write[E->get().order] = _get_datatype_alignment(E->get().type);
}
p_actions.uniforms->insert(E->key(), E->get());
@@ -700,6 +702,11 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
}
} else if (cfnode->flow_op == SL::FLOW_OP_DISCARD) {
+ if (p_actions.usage_flag_pointers.has("DISCARD") && !used_flag_pointers.has("DISCARD")) {
+ *p_actions.usage_flag_pointers["DISCARD"] = true;
+ used_flag_pointers.insert("DISCARD");
+ }
+
code = "discard;";
} else if (cfnode->flow_op == SL::FLOW_OP_CONTINUE) {
diff --git a/drivers/gles3/shader_compiler_gles3.h b/drivers/gles3/shader_compiler_gles3.h
index bf776ee062..7a32057741 100644
--- a/drivers/gles3/shader_compiler_gles3.h
+++ b/drivers/gles3/shader_compiler_gles3.h
@@ -52,6 +52,7 @@ public:
Vector<CharString> defines;
Vector<StringName> texture_uniforms;
+ Vector<ShaderLanguage::DataType> texture_types;
Vector<ShaderLanguage::ShaderNode::Uniform::Hint> texture_hints;
Vector<uint32_t> uniform_offsets;
diff --git a/drivers/gles3/shader_gles3.cpp b/drivers/gles3/shader_gles3.cpp
index 08b8a1cc26..ca0ce5cd3e 100644
--- a/drivers/gles3/shader_gles3.cpp
+++ b/drivers/gles3/shader_gles3.cpp
@@ -554,7 +554,7 @@ ShaderGLES3::Version *ShaderGLES3::get_current_version() {
v.texture_uniform_locations.resize(cc->texture_uniforms.size());
for (int i = 0; i < cc->texture_uniforms.size(); i++) {
- v.texture_uniform_locations[i] = glGetUniformLocation(v.id, String(cc->texture_uniforms[i]).ascii().get_data());
+ v.texture_uniform_locations.write[i] = glGetUniformLocation(v.id, String(cc->texture_uniforms[i]).ascii().get_data());
glUniform1i(v.texture_uniform_locations[i], i + base_material_tex_index);
}
}
diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index abb236138f..dee8bcbc58 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -91,6 +91,7 @@ layout(std140) uniform SceneData { //ubo:0
mediump float subsurface_scatter_width;
mediump float ambient_occlusion_affect_light;
mediump float ambient_occlusion_affect_ao_channel;
+ mediump float opaque_prepass_threshold;
bool fog_depth_enabled;
highp float fog_depth_begin;
@@ -338,7 +339,7 @@ void main() {
#endif
#endif
- float roughness=0.0;
+ float roughness = 1.0;
//defines that make writing custom shaders easier
#define projection_matrix local_projection
@@ -679,6 +680,7 @@ layout(std140) uniform SceneData {
mediump float subsurface_scatter_width;
mediump float ambient_occlusion_affect_light;
mediump float ambient_occlusion_affect_ao_channel;
+ mediump float opaque_prepass_threshold;
bool fog_depth_enabled;
highp float fog_depth_begin;
@@ -1026,12 +1028,11 @@ LIGHT_SHADER_CODE
diffuse_brdf_NL = cNdotL * (1.0 / M_PI);
#endif
-#if defined(TRANSMISSION_USED)
- diffuse_light += light_color * diffuse_color * mix(vec3(diffuse_brdf_NL), vec3(M_PI), transmission) * attenuation;
-#else
diffuse_light += light_color * diffuse_color * diffuse_brdf_NL * attenuation;
-#endif
+#if defined(TRANSMISSION_USED)
+ diffuse_light += light_color * diffuse_color * (vec3(1.0 / M_PI) - diffuse_brdf_NL) * transmission * attenuation;
+#endif
#if defined(LIGHT_USE_RIM)
@@ -1607,18 +1608,18 @@ void main() {
//lay out everything, whathever is unused is optimized away anyway
highp vec3 vertex = vertex_interp;
- vec3 albedo = vec3(0.8,0.8,0.8);
+ vec3 albedo = vec3(1.0);
vec3 transmission = vec3(0.0);
float metallic = 0.0;
float specular = 0.5;
- vec3 emission = vec3(0.0,0.0,0.0);
+ vec3 emission = vec3(0.0);
float roughness = 1.0;
float rim = 0.0;
float rim_tint = 0.0;
- float clearcoat=0.0;
- float clearcoat_gloss=0.0;
- float anisotropy = 1.0;
- vec2 anisotropy_flow = vec2(1.0,0.0);
+ float clearcoat = 0.0;
+ float clearcoat_gloss = 0.0;
+ float anisotropy = 0.0;
+ vec2 anisotropy_flow = vec2(1.0, 0.0);
#if defined(ENABLE_AO)
float ao=1.0;
@@ -1628,7 +1629,7 @@ void main() {
float alpha = 1.0;
#if defined(DO_SIDE_CHECK)
- float side=float(gl_FrontFacing)*2.0-1.0;
+ float side=gl_FrontFacing ? 1.0 : -1.0;
#else
float side=1.0;
#endif
@@ -1690,9 +1691,10 @@ FRAGMENT_SHADER_CODE
#ifdef USE_OPAQUE_PREPASS
- if (alpha<0.99) {
+ if (alpha<opaque_prepass_threshold) {
discard;
}
+
#endif
#if defined(ENABLE_NORMALMAP)
@@ -2138,6 +2140,8 @@ FRAGMENT_SHADER_CODE
#else
+
+
//approximate ambient scale for SSAO, since we will lack full ambient
float max_emission=max(emission.r,max(emission.g,emission.b));
float max_ambient=max(ambient_light.r,max(ambient_light.g,ambient_light.b));
@@ -2169,7 +2173,6 @@ FRAGMENT_SHADER_CODE
frag_color=vec4(emission+ambient_light+diffuse_light+specular_light,alpha);
#endif //SHADELESS
-
#endif //USE_MULTIPLE_RENDER_TARGETS