diff options
Diffstat (limited to 'drivers')
27 files changed, 874 insertions, 354 deletions
diff --git a/drivers/coreaudio/audio_driver_coreaudio.cpp b/drivers/coreaudio/audio_driver_coreaudio.cpp index 6e451eabcd..ef7858b4ca 100644 --- a/drivers/coreaudio/audio_driver_coreaudio.cpp +++ b/drivers/coreaudio/audio_driver_coreaudio.cpp @@ -52,7 +52,9 @@ OSStatus AudioDriverCoreAudio::output_device_address_cb(AudioObjectID inObjectID } #endif -Error AudioDriverCoreAudio::init_device() { +Error AudioDriverCoreAudio::init() { + mutex = Mutex::create(); + AudioComponentDescription desc; zeromem(&desc, sizeof(desc)); desc.componentType = kAudioUnitType_Output; @@ -69,6 +71,16 @@ Error AudioDriverCoreAudio::init_device() { OSStatus result = AudioComponentInstanceNew(comp, &audio_unit); ERR_FAIL_COND_V(result != noErr, FAILED); +#ifdef OSX_ENABLED + AudioObjectPropertyAddress prop; + prop.mSelector = kAudioHardwarePropertyDefaultOutputDevice; + prop.mScope = kAudioObjectPropertyScopeGlobal; + prop.mElement = kAudioObjectPropertyElementMaster; + + result = AudioObjectAddPropertyListener(kAudioObjectSystemObject, &prop, &output_device_address_cb, this); + ERR_FAIL_COND_V(result != noErr, FAILED); +#endif + AudioStreamBasicDescription strdesc; zeromem(&strdesc, sizeof(strdesc)); @@ -135,42 +147,6 @@ Error AudioDriverCoreAudio::init_device() { return OK; } -Error AudioDriverCoreAudio::finish_device() { - OSStatus result; - - if (active) { - result = AudioOutputUnitStop(audio_unit); - ERR_FAIL_COND_V(result != noErr, FAILED); - - active = false; - } - - result = AudioUnitUninitialize(audio_unit); - ERR_FAIL_COND_V(result != noErr, FAILED); - - return OK; -} - -Error AudioDriverCoreAudio::init() { - OSStatus result; - - mutex = Mutex::create(); - active = false; - channels = 2; - -#ifdef OSX_ENABLED - AudioObjectPropertyAddress prop; - prop.mSelector = kAudioHardwarePropertyDefaultOutputDevice; - prop.mScope = kAudioObjectPropertyScopeGlobal; - prop.mElement = kAudioObjectPropertyElementMaster; - - result = AudioObjectAddPropertyListener(kAudioObjectSystemObject, &prop, &output_device_address_cb, this); - ERR_FAIL_COND_V(result != noErr, FAILED); -#endif - - return init_device(); -}; - OSStatus AudioDriverCoreAudio::output_callback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, @@ -370,6 +346,7 @@ void AudioDriverCoreAudio::set_device(String device) { } if (!found) { + // If we haven't found the desired device get the system default one UInt32 size = sizeof(AudioDeviceID); AudioObjectPropertyAddress property = { kAudioHardwarePropertyDefaultOutputDevice, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; @@ -406,7 +383,28 @@ bool AudioDriverCoreAudio::try_lock() { void AudioDriverCoreAudio::finish() { OSStatus result; - finish_device(); + lock(); + + AURenderCallbackStruct callback; + zeromem(&callback, sizeof(AURenderCallbackStruct)); + result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, kOutputBus, &callback, sizeof(callback)); + if (result != noErr) { + ERR_PRINT("AudioUnitSetProperty failed"); + } + + if (active) { + result = AudioOutputUnitStop(audio_unit); + if (result != noErr) { + ERR_PRINT("AudioOutputUnitStop failed"); + } + + active = false; + } + + result = AudioUnitUninitialize(audio_unit); + if (result != noErr) { + ERR_PRINT("AudioUnitUninitialize failed"); + } #ifdef OSX_ENABLED AudioObjectPropertyAddress prop; @@ -420,13 +418,13 @@ void AudioDriverCoreAudio::finish() { } #endif - AURenderCallbackStruct callback; - zeromem(&callback, sizeof(AURenderCallbackStruct)); - result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, kOutputBus, &callback, sizeof(callback)); + result = AudioComponentInstanceDispose(audio_unit); if (result != noErr) { - ERR_PRINT("AudioUnitSetProperty failed"); + ERR_PRINT("AudioComponentInstanceDispose failed"); } + unlock(); + if (mutex) { memdelete(mutex); mutex = NULL; diff --git a/drivers/coreaudio/audio_driver_coreaudio.h b/drivers/coreaudio/audio_driver_coreaudio.h index c44e225521..99c910498e 100644 --- a/drivers/coreaudio/audio_driver_coreaudio.h +++ b/drivers/coreaudio/audio_driver_coreaudio.h @@ -68,9 +68,6 @@ class AudioDriverCoreAudio : public AudioDriver { UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData); - Error init_device(); - Error finish_device(); - public: const char *get_name() const { return "CoreAudio"; diff --git a/drivers/dummy/rasterizer_dummy.h b/drivers/dummy/rasterizer_dummy.h index ea0d3ec706..bab89f649a 100644 --- a/drivers/dummy/rasterizer_dummy.h +++ b/drivers/dummy/rasterizer_dummy.h @@ -67,7 +67,7 @@ public: void environment_set_fog(RID p_env, bool p_enable, float p_begin, float p_end, RID p_gradient_texture) {} void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance, bool p_roughness) {} - void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, const Color &p_color, VS::EnvironmentSSAOQuality p_quality, VS::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) {} + void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, float p_ao_channel_affect, const Color &p_color, VS::EnvironmentSSAOQuality p_quality, VS::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) {} void environment_set_tonemap(RID p_env, VS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) {} @@ -127,7 +127,26 @@ public: String path; }; + struct DummySurface { + uint32_t format; + VS::PrimitiveType primitive; + PoolVector<uint8_t> array; + int vertex_count; + PoolVector<uint8_t> index_array; + int index_count; + AABB aabb; + Vector<PoolVector<uint8_t> > blend_shapes; + Vector<AABB> bone_aabbs; + }; + + struct DummyMesh : public RID_Data { + Vector<DummySurface> surfaces; + int blend_shape_count; + VS::BlendShapeMode blend_shape_mode; + }; + mutable RID_Owner<DummyTexture> texture_owner; + mutable RID_Owner<DummyMesh> mesh_owner; RID texture_create() { @@ -154,6 +173,19 @@ public: t->image->create(t->width, t->height, false, t->format, p_image->get_data()); } + 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) { + DummyTexture *t = texture_owner.get(p_texture); + + ERR_FAIL_COND(!t); + ERR_FAIL_COND(t->format != p_image->get_format()); + ERR_FAIL_COND(p_image.is_null()); + ERR_FAIL_COND(src_w <= 0 || src_h <= 0); + ERR_FAIL_COND(src_x < 0 || src_y < 0 || src_x + src_w > p_image->get_width() || src_y + src_h > p_image->get_height()); + ERR_FAIL_COND(dst_x < 0 || dst_y < 0 || dst_x + src_w > t->width || dst_y + src_h > t->height); + + t->image->blit_rect(p_image, Rect2(src_x, src_y, src_w, src_h), Vector2(dst_x, dst_y)); + } + Ref<Image> texture_get_data(RID p_texture, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT) const { DummyTexture *t = texture_owner.getornull(p_texture); ERR_FAIL_COND_V(!t, Ref<Image>()); @@ -203,6 +235,7 @@ public: void textures_keep_original(bool p_enable) {} void texture_set_proxy(RID p_proxy, RID p_base) {} + void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) {} /* SKY API */ @@ -243,46 +276,128 @@ public: /* MESH API */ - RID mesh_create() { return RID(); } - - void mesh_add_surface_from_arrays(RID p_mesh, VS::PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes = Array(), uint32_t p_compress_format = Mesh::ARRAY_COMPRESS_DEFAULT) {} - void mesh_add_surface(RID p_mesh, uint32_t p_format, VS::PrimitiveType p_primitive, const PoolVector<uint8_t> &p_array, int p_vertex_count, const PoolVector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<PoolVector<uint8_t> > &p_blend_shapes = Vector<PoolVector<uint8_t> >(), const Vector<AABB> &p_bone_aabbs = Vector<AABB>()) {} + RID mesh_create() { + DummyMesh *mesh = memnew(DummyMesh); + ERR_FAIL_COND_V(!mesh, RID()); + mesh->blend_shape_count = 0; + mesh->blend_shape_mode = VS::BLEND_SHAPE_MODE_NORMALIZED; + return mesh_owner.make_rid(mesh); + } - void mesh_add_surface_from_mesh_data(RID p_mesh, const Geometry::MeshData &p_mesh_data) {} - void mesh_add_surface_from_planes(RID p_mesh, const PoolVector<Plane> &p_planes) {} + void mesh_add_surface(RID p_mesh, uint32_t p_format, VS::PrimitiveType p_primitive, const PoolVector<uint8_t> &p_array, int p_vertex_count, const PoolVector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<PoolVector<uint8_t> > &p_blend_shapes = Vector<PoolVector<uint8_t> >(), const Vector<AABB> &p_bone_aabbs = Vector<AABB>()) { + DummyMesh *m = mesh_owner.getornull(p_mesh); + ERR_FAIL_COND(!m); + + m->surfaces.push_back(DummySurface()); + DummySurface *s = &m->surfaces[m->surfaces.size() - 1]; + s->format = p_format; + s->primitive = p_primitive; + s->array = p_array; + s->vertex_count = p_vertex_count; + s->index_array = p_index_array; + s->index_count = p_index_count; + s->aabb = p_aabb; + s->blend_shapes = p_blend_shapes; + s->bone_aabbs = p_bone_aabbs; + } - void mesh_set_blend_shape_count(RID p_mesh, int p_amount) {} - int mesh_get_blend_shape_count(RID p_mesh) const { return 0; } + void mesh_set_blend_shape_count(RID p_mesh, int p_amount) { + DummyMesh *m = mesh_owner.getornull(p_mesh); + ERR_FAIL_COND(!m); + m->blend_shape_count = p_amount; + } + int mesh_get_blend_shape_count(RID p_mesh) const { + DummyMesh *m = mesh_owner.getornull(p_mesh); + ERR_FAIL_COND_V(!m, 0); + return m->blend_shape_count; + } - void mesh_set_blend_shape_mode(RID p_mesh, VS::BlendShapeMode p_mode) {} - VS::BlendShapeMode mesh_get_blend_shape_mode(RID p_mesh) const { return VS::BLEND_SHAPE_MODE_NORMALIZED; } + void mesh_set_blend_shape_mode(RID p_mesh, VS::BlendShapeMode p_mode) { + DummyMesh *m = mesh_owner.getornull(p_mesh); + ERR_FAIL_COND(!m); + m->blend_shape_mode = p_mode; + } + VS::BlendShapeMode mesh_get_blend_shape_mode(RID p_mesh) const { + DummyMesh *m = mesh_owner.getornull(p_mesh); + ERR_FAIL_COND_V(!m, VS::BLEND_SHAPE_MODE_NORMALIZED); + return m->blend_shape_mode; + } void mesh_surface_update_region(RID p_mesh, int p_surface, int p_offset, const PoolVector<uint8_t> &p_data) {} void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) {} RID mesh_surface_get_material(RID p_mesh, int p_surface) const { return RID(); } - int mesh_surface_get_array_len(RID p_mesh, int p_surface) const { return 0; } - int mesh_surface_get_array_index_len(RID p_mesh, int p_surface) const { return 0; } + int mesh_surface_get_array_len(RID p_mesh, int p_surface) const { + DummyMesh *m = mesh_owner.getornull(p_mesh); + ERR_FAIL_COND_V(!m, 0); + + return m->surfaces[p_surface].vertex_count; + } + int mesh_surface_get_array_index_len(RID p_mesh, int p_surface) const { + DummyMesh *m = mesh_owner.getornull(p_mesh); + ERR_FAIL_COND_V(!m, 0); + + return m->surfaces[p_surface].index_count; + } PoolVector<uint8_t> mesh_surface_get_array(RID p_mesh, int p_surface) const { - PoolVector<uint8_t> p; - return p; + DummyMesh *m = mesh_owner.getornull(p_mesh); + ERR_FAIL_COND_V(!m, PoolVector<uint8_t>()); + + return m->surfaces[p_surface].array; } PoolVector<uint8_t> mesh_surface_get_index_array(RID p_mesh, int p_surface) const { - PoolVector<uint8_t> p; - return p; + DummyMesh *m = mesh_owner.getornull(p_mesh); + ERR_FAIL_COND_V(!m, PoolVector<uint8_t>()); + + return m->surfaces[p_surface].index_array; } - uint32_t mesh_surface_get_format(RID p_mesh, int p_surface) const { return 0; } - VS::PrimitiveType mesh_surface_get_primitive_type(RID p_mesh, int p_surface) const { return VS::PRIMITIVE_POINTS; } + uint32_t mesh_surface_get_format(RID p_mesh, int p_surface) const { + DummyMesh *m = mesh_owner.getornull(p_mesh); + ERR_FAIL_COND_V(!m, 0); - AABB mesh_surface_get_aabb(RID p_mesh, int p_surface) const { return AABB(); } - Vector<PoolVector<uint8_t> > mesh_surface_get_blend_shapes(RID p_mesh, int p_surface) const { return Vector<PoolVector<uint8_t> >(); } - Vector<AABB> mesh_surface_get_skeleton_aabb(RID p_mesh, int p_surface) const { return Vector<AABB>(); } + return m->surfaces[p_surface].format; + } + VS::PrimitiveType mesh_surface_get_primitive_type(RID p_mesh, int p_surface) const { + DummyMesh *m = mesh_owner.getornull(p_mesh); + ERR_FAIL_COND_V(!m, VS::PRIMITIVE_POINTS); + + return m->surfaces[p_surface].primitive; + } - void mesh_remove_surface(RID p_mesh, int p_index) {} - int mesh_get_surface_count(RID p_mesh) const { return 0; } + AABB mesh_surface_get_aabb(RID p_mesh, int p_surface) const { + DummyMesh *m = mesh_owner.getornull(p_mesh); + ERR_FAIL_COND_V(!m, AABB()); + + return m->surfaces[p_surface].aabb; + } + Vector<PoolVector<uint8_t> > mesh_surface_get_blend_shapes(RID p_mesh, int p_surface) const { + DummyMesh *m = mesh_owner.getornull(p_mesh); + ERR_FAIL_COND_V(!m, Vector<PoolVector<uint8_t> >()); + + return m->surfaces[p_surface].blend_shapes; + } + Vector<AABB> mesh_surface_get_skeleton_aabb(RID p_mesh, int p_surface) const { + DummyMesh *m = mesh_owner.getornull(p_mesh); + ERR_FAIL_COND_V(!m, Vector<AABB>()); + + return m->surfaces[p_surface].bone_aabbs; + } + + void mesh_remove_surface(RID p_mesh, int p_index) { + DummyMesh *m = mesh_owner.getornull(p_mesh); + ERR_FAIL_COND(!m); + ERR_FAIL_COND(p_index >= m->surfaces.size()); + + m->surfaces.remove(p_index); + } + int mesh_get_surface_count(RID p_mesh) const { + DummyMesh *m = mesh_owner.getornull(p_mesh); + ERR_FAIL_COND_V(!m, 0); + return m->surfaces.size(); + } void mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) {} AABB mesh_get_custom_aabb(RID p_mesh) const { return AABB(); } @@ -294,19 +409,23 @@ public: virtual RID multimesh_create() { return RID(); } - void multimesh_allocate(RID p_multimesh, int p_instances, VS::MultimeshTransformFormat p_transform_format, VS::MultimeshColorFormat p_color_format) {} + void multimesh_allocate(RID p_multimesh, int p_instances, VS::MultimeshTransformFormat p_transform_format, VS::MultimeshColorFormat p_color_format, VS::MultimeshCustomDataFormat p_data = VS::MULTIMESH_CUSTOM_DATA_NONE) {} int multimesh_get_instance_count(RID p_multimesh) const { return 0; } void multimesh_set_mesh(RID p_multimesh, RID p_mesh) {} void multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform &p_transform) {} void multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform) {} void multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) {} + void multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_color) {} RID multimesh_get_mesh(RID p_multimesh) const { return RID(); } Transform multimesh_instance_get_transform(RID p_multimesh, int p_index) const { return Transform(); } Transform2D multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const { return Transform2D(); } Color multimesh_instance_get_color(RID p_multimesh, int p_index) const { return Color(); } + Color multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const { return Color(); } + + void multimesh_set_as_bulk_array(RID p_multimesh, const PoolVector<float> &p_array) {} void multimesh_set_visible_instances(RID p_multimesh, int p_visible) {} int multimesh_get_visible_instances(RID p_multimesh) const { return 0; } @@ -333,6 +452,7 @@ public: RID skeleton_create() { return RID(); } void skeleton_allocate(RID p_skeleton, int p_bones, bool p_2d_skeleton = false) {} + void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) {} int skeleton_get_bone_count(RID p_skeleton) const { return 0; } void skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform &p_transform) {} Transform skeleton_bone_get_transform(RID p_skeleton, int p_bone) const { return Transform(); } @@ -584,7 +704,14 @@ public: RID canvas_light_occluder_create() { return RID(); } void canvas_light_occluder_set_polylines(RID p_occluder, const PoolVector<Vector2> &p_lines) {} - VS::InstanceType get_base_type(RID p_rid) const { return VS::INSTANCE_NONE; } + VS::InstanceType get_base_type(RID p_rid) const { + if (mesh_owner.owns(p_rid)) { + return VS::INSTANCE_MESH; + } + + return VS::INSTANCE_NONE; + } + bool free(RID p_rid) { if (texture_owner.owns(p_rid)) { diff --git a/drivers/dummy/texture_loader_dummy.cpp b/drivers/dummy/texture_loader_dummy.cpp new file mode 100644 index 0000000000..6d3e176bbb --- /dev/null +++ b/drivers/dummy/texture_loader_dummy.cpp @@ -0,0 +1,87 @@ +/*************************************************************************/ +/* texture_loader_dummy.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "texture_loader_dummy.h" +#include "core/os/file_access.h" +#include "print_string.h" +#include <string.h> + +RES ResourceFormatDummyTexture::load(const String &p_path, const String &p_original_path, Error *r_error) { + unsigned int width = 8; + unsigned int height = 8; + + //We just use some format + Image::Format fmt = Image::FORMAT_RGB8; + int rowsize = 3 * width; + + PoolVector<uint8_t> dstbuff; + + dstbuff.resize(rowsize * height); + + PoolVector<uint8_t>::Write dstbuff_write = dstbuff.write(); + + uint8_t *data = dstbuff_write.ptr(); + + uint8_t **row_p = memnew_arr(uint8_t *, height); + + for (unsigned int i = 0; i < height; i++) { + row_p[i] = 0; //No colors any more, I want them to turn black + } + + memdelete_arr(row_p); + + Ref<Image> img = memnew(Image(width, height, 0, fmt, dstbuff)); + + Ref<ImageTexture> texture = memnew(ImageTexture); + texture->create_from_image(img); + + if (r_error) + *r_error = OK; + + return texture; +} + +void ResourceFormatDummyTexture::get_recognized_extensions(List<String> *p_extensions) const { + p_extensions->push_back("png"); + p_extensions->push_back("hdr"); + p_extensions->push_back("jpg"); + p_extensions->push_back("tga"); +} + +bool ResourceFormatDummyTexture::handles_type(const String &p_type) const { + return ClassDB::is_parent_class(p_type, "Texture"); +} + +String ResourceFormatDummyTexture::get_resource_type(const String &p_path) const { + String extension = p_path.get_extension().to_lower(); + if (extension == "png" || extension == "hdr" || extension == "jpg" || extension == "tga") + return "ImageTexture"; + return ""; +} diff --git a/drivers/dummy/texture_loader_dummy.h b/drivers/dummy/texture_loader_dummy.h new file mode 100644 index 0000000000..f0a355ec12 --- /dev/null +++ b/drivers/dummy/texture_loader_dummy.h @@ -0,0 +1,47 @@ +/*************************************************************************/ +/* texture_loader_dummy.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef TEXTURE_LOADER_DUMMY_H +#define TEXTURE_LOADER_DUMMY_H + +#include "core/io/resource_loader.h" +#include "scene/resources/texture.h" + +class ResourceFormatDummyTexture : public ResourceFormatLoader { +public: + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL); + virtual void get_recognized_extensions(List<String> *p_extensions) const; + virtual bool handles_type(const String &p_type) const; + virtual String get_resource_type(const String &p_path) const; + + virtual ~ResourceFormatDummyTexture() {} +}; + +#endif // TEXTURE_LOADER_DUMMY_H diff --git a/drivers/gles2/rasterizer_canvas_gles2.cpp b/drivers/gles2/rasterizer_canvas_gles2.cpp index cc8e3277b9..daa421d45c 100644 --- a/drivers/gles2/rasterizer_canvas_gles2.cpp +++ b/drivers/gles2/rasterizer_canvas_gles2.cpp @@ -140,6 +140,10 @@ RasterizerStorageGLES2::Texture *RasterizerCanvasGLES2::_bind_canvas_texture(con texture = texture->get_ptr(); + if (texture->redraw_if_visible) { + VisualServerRaster::redraw_request(); + } + if (texture->render_target) { texture->render_target->used_in_frame = true; } @@ -733,6 +737,9 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur int w = current_clip->final_clip_rect.size.x; int h = current_clip->final_clip_rect.size.y; + if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP]) + y = current_clip->final_clip_rect.position.y; + glScissor(x, y, w, h); reclip = false; @@ -821,7 +828,10 @@ void RasterizerCanvasGLES2::canvas_render_items(Item *p_item_list, int p_z, cons if (current_clip) { glEnable(GL_SCISSOR_TEST); - glScissor(current_clip->final_clip_rect.position.x, (rt_size.height - (current_clip->final_clip_rect.position.y + current_clip->final_clip_rect.size.height)), current_clip->final_clip_rect.size.width, current_clip->final_clip_rect.size.height); + int y = storage->frame.current_rt->height - (current_clip->final_clip_rect.position.y + current_clip->final_clip_rect.size.y); + if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP]) + y = current_clip->final_clip_rect.position.y; + glScissor(current_clip->final_clip_rect.position.x, y, current_clip->final_clip_rect.size.width, current_clip->final_clip_rect.size.height); } else { glDisable(GL_SCISSOR_TEST); } @@ -903,6 +913,10 @@ void RasterizerCanvasGLES2::canvas_render_items(Item *p_item_list, int p_z, cons t = t->get_ptr(); + if (t->redraw_if_visible) { + VisualServerRaster::redraw_request(); + } + glBindTexture(t->target, t->tex_id); } } else { @@ -969,7 +983,10 @@ void RasterizerCanvasGLES2::canvas_render_items(Item *p_item_list, int p_z, cons if (reclip) { glEnable(GL_SCISSOR_TEST); - glScissor(current_clip->final_clip_rect.position.x, (rt_size.height - (current_clip->final_clip_rect.position.y + current_clip->final_clip_rect.size.height)), current_clip->final_clip_rect.size.width, current_clip->final_clip_rect.size.height); + int y = storage->frame.current_rt->height - (current_clip->final_clip_rect.position.y + current_clip->final_clip_rect.size.y); + if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP]) + y = current_clip->final_clip_rect.position.y; + glScissor(current_clip->final_clip_rect.position.x, y, current_clip->final_clip_rect.size.width, current_clip->final_clip_rect.size.height); } p_item_list = p_item_list->next; diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index 4626a5ed3c..ab48e682d6 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.cpp @@ -346,7 +346,7 @@ void RasterizerGLES2::set_boot_image(const Ref<Image> &p_image, const Color &p_c if (OS::get_singleton()->is_layered_allowed()) { if (OS::get_singleton()->get_window_per_pixel_transparency_enabled()) { -#ifdef WINDOWS_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) { @@ -401,7 +401,7 @@ void RasterizerGLES2::end_frame(bool p_swap_buffers) { if (OS::get_singleton()->is_layered_allowed()) { if (OS::get_singleton()->get_window_per_pixel_transparency_enabled()) { -#ifdef WINDOWS_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) { diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp index bb39cbcbd5..f7712be5d0 100644 --- a/drivers/gles2/rasterizer_scene_gles2.cpp +++ b/drivers/gles2/rasterizer_scene_gles2.cpp @@ -144,7 +144,7 @@ void RasterizerSceneGLES2::environment_set_fog(RID p_env, bool p_enable, float p void RasterizerSceneGLES2::environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_in, float p_fade_out, float p_depth_tolerance, bool p_roughness) { } -void RasterizerSceneGLES2::environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, const Color &p_color, VS::EnvironmentSSAOQuality p_quality, VisualServer::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) { +void RasterizerSceneGLES2::environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, float p_ao_channel_affect, const Color &p_color, VS::EnvironmentSSAOQuality p_quality, VisualServer::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) { } void RasterizerSceneGLES2::environment_set_tonemap(RID p_env, VS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) { diff --git a/drivers/gles2/rasterizer_scene_gles2.h b/drivers/gles2/rasterizer_scene_gles2.h index 99f034afed..110222f709 100644 --- a/drivers/gles2/rasterizer_scene_gles2.h +++ b/drivers/gles2/rasterizer_scene_gles2.h @@ -212,7 +212,7 @@ public: virtual void environment_set_fog(RID p_env, bool p_enable, float p_begin, float p_end, RID p_gradient_texture); virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_in, float p_fade_out, float p_depth_tolerance, bool p_roughness); - virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, const Color &p_color, VS::EnvironmentSSAOQuality p_quality, VS::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness); + virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, float p_ao_channel_affect, const Color &p_color, VS::EnvironmentSSAOQuality p_quality, VS::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness); virtual void environment_set_tonemap(RID p_env, VS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale); diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp index 6e7e1793e1..b268d4c723 100644 --- a/drivers/gles2/rasterizer_storage_gles2.cpp +++ b/drivers/gles2/rasterizer_storage_gles2.cpp @@ -674,6 +674,15 @@ void RasterizerStorageGLES2::texture_set_proxy(RID p_texture, RID p_proxy) { } } +void RasterizerStorageGLES2::texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) { + + Texture *texture = texture_owner.getornull(p_texture); + ERR_FAIL_COND(!texture); + + texture->redraw_if_visible = p_enable; + +} + void RasterizerStorageGLES2::texture_set_detect_3d_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata) { // TODO } @@ -1182,7 +1191,7 @@ RID RasterizerStorageGLES2::multimesh_create() { return RID(); } -void RasterizerStorageGLES2::multimesh_allocate(RID p_multimesh, int p_instances, VS::MultimeshTransformFormat p_transform_format, VS::MultimeshColorFormat p_color_format) { +void RasterizerStorageGLES2::multimesh_allocate(RID p_multimesh, int p_instances, VS::MultimeshTransformFormat p_transform_format, VS::MultimeshColorFormat p_color_format,VS::MultimeshCustomDataFormat p_data) { } int RasterizerStorageGLES2::multimesh_get_instance_count(RID p_multimesh) const { @@ -1201,6 +1210,9 @@ void RasterizerStorageGLES2::multimesh_instance_set_transform_2d(RID p_multimesh void RasterizerStorageGLES2::multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) { } +void RasterizerStorageGLES2::multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_color) { +} + RID RasterizerStorageGLES2::multimesh_get_mesh(RID p_multimesh) const { return RID(); } @@ -1217,6 +1229,15 @@ Color RasterizerStorageGLES2::multimesh_instance_get_color(RID p_multimesh, int return Color(); } +Color RasterizerStorageGLES2::multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const { + return Color(); +} + +void RasterizerStorageGLES2::multimesh_set_as_bulk_array(RID p_multimesh, const PoolVector<float> &p_array) { + + +} + void RasterizerStorageGLES2::multimesh_set_visible_instances(RID p_multimesh, int p_visible) { } @@ -1303,7 +1324,6 @@ Transform2D RasterizerStorageGLES2::skeleton_bone_get_transform_2d(RID p_skeleto } void RasterizerStorageGLES2::skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) { - } void RasterizerStorageGLES2::update_dirty_skeletons() { diff --git a/drivers/gles2/rasterizer_storage_gles2.h b/drivers/gles2/rasterizer_storage_gles2.h index b735f2e148..b2c8b620a6 100644 --- a/drivers/gles2/rasterizer_storage_gles2.h +++ b/drivers/gles2/rasterizer_storage_gles2.h @@ -176,12 +176,15 @@ public: bool active; GLenum tex_id; + uint16_t stored_cube_sides; RenderTarget *render_target; Ref<Image> images[6]; + bool redraw_if_visible; + Texture() { flags = 0; width = 0; @@ -205,6 +208,8 @@ public: proxy = NULL; render_target = NULL; + + redraw_if_visible = false; } _ALWAYS_INLINE_ Texture *get_ptr() { @@ -264,6 +269,8 @@ public: virtual void texture_set_detect_srgb_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata); virtual void texture_set_detect_normal_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata); + virtual void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable); + /* SKY API */ virtual RID sky_create(); @@ -508,19 +515,23 @@ public: virtual RID multimesh_create(); - virtual void multimesh_allocate(RID p_multimesh, int p_instances, VS::MultimeshTransformFormat p_transform_format, VS::MultimeshColorFormat p_color_format); + virtual void multimesh_allocate(RID p_multimesh, int p_instances, VS::MultimeshTransformFormat p_transform_format, VS::MultimeshColorFormat p_color_format,VS::MultimeshCustomDataFormat p_data=VS::MULTIMESH_CUSTOM_DATA_NONE); virtual int multimesh_get_instance_count(RID p_multimesh) const; virtual void multimesh_set_mesh(RID p_multimesh, RID p_mesh); virtual void multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform &p_transform); virtual void multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform); virtual void multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color); + virtual void multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_color); virtual RID multimesh_get_mesh(RID p_multimesh) const; virtual Transform multimesh_instance_get_transform(RID p_multimesh, int p_index) const; virtual Transform2D multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const; virtual Color multimesh_instance_get_color(RID p_multimesh, int p_index) const; + virtual Color multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const; + + virtual void multimesh_set_as_bulk_array(RID p_multimesh, const PoolVector<float> &p_array); virtual void multimesh_set_visible_instances(RID p_multimesh, int p_visible); virtual int multimesh_get_visible_instances(RID p_multimesh) const; diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp index ad6c2f850a..aa55e72083 100644 --- a/drivers/gles2/shader_compiler_gles2.cpp +++ b/drivers/gles2/shader_compiler_gles2.cpp @@ -712,7 +712,7 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() { actions[VS::SHADER_CANVAS_ITEM].renames["WORLD_MATRIX"] = "modelview_matrix"; actions[VS::SHADER_CANVAS_ITEM].renames["PROJECTION_MATRIX"] = "projection_matrix"; - actions[VS::SHADER_CANVAS_ITEM].renames["EXTRA_MATRIX"] == "extra_matrix"; + actions[VS::SHADER_CANVAS_ITEM].renames["EXTRA_MATRIX"] = "extra_matrix"; actions[VS::SHADER_CANVAS_ITEM].renames["TIME"] = "time"; actions[VS::SHADER_CANVAS_ITEM].renames["AT_LIGHT_PASS"] = "at_light_pass"; actions[VS::SHADER_CANVAS_ITEM].renames["INSTANCE_CUSTOM"] = "instance_custom"; diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index ff423bf0d0..f859e49b5b 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -193,11 +193,11 @@ void RasterizerCanvasGLES3::canvas_end() { state.using_ninepatch = false; } -RasterizerStorageGLES3::Texture *RasterizerCanvasGLES3::_bind_canvas_texture(const RID &p_texture, const RID &p_normal_map) { +RasterizerStorageGLES3::Texture *RasterizerCanvasGLES3::_bind_canvas_texture(const RID &p_texture, const RID &p_normal_map, bool p_force) { RasterizerStorageGLES3::Texture *tex_return = NULL; - if (p_texture == state.current_tex) { + if (p_texture == state.current_tex && !p_force) { tex_return = state.current_tex_ptr; } else if (p_texture.is_valid()) { @@ -211,6 +211,10 @@ RasterizerStorageGLES3::Texture *RasterizerCanvasGLES3::_bind_canvas_texture(con } else { + if (texture->redraw_if_visible) { //check before proxy, because this is usually used with proxies + VisualServerRaster::redraw_request(); + } + texture = texture->get_ptr(); if (texture->render_target) @@ -232,7 +236,7 @@ RasterizerStorageGLES3::Texture *RasterizerCanvasGLES3::_bind_canvas_texture(con state.current_tex_ptr = NULL; } - if (p_normal_map == state.current_normal) { + if (p_normal_map == state.current_normal && !p_force) { //do none state.canvas_shader.set_uniform(CanvasShaderGLES3::USE_DEFAULT_NORMAL, state.current_normal.is_valid()); @@ -248,6 +252,10 @@ RasterizerStorageGLES3::Texture *RasterizerCanvasGLES3::_bind_canvas_texture(con } else { + if (normal_map->redraw_if_visible) { //check before proxy, because this is usually used with proxies + VisualServerRaster::redraw_request(); + } + normal_map = normal_map->get_ptr(); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, normal_map->tex_id); @@ -832,6 +840,9 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur if (!particles) break; + if (particles->inactive && !particles->emitting) + break; + glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1); //not used, so keep white VisualServerRaster::redraw_request(); @@ -997,13 +1008,11 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur glEnable(GL_SCISSOR_TEST); //glScissor(viewport.x+current_clip->final_clip_rect.pos.x,viewport.y+ (viewport.height-(current_clip->final_clip_rect.pos.y+current_clip->final_clip_rect.size.height)), //current_clip->final_clip_rect.size.width,current_clip->final_clip_rect.size.height); - - int x = current_clip->final_clip_rect.position.x; int y = storage->frame.current_rt->height - (current_clip->final_clip_rect.position.y + current_clip->final_clip_rect.size.y); - int w = current_clip->final_clip_rect.size.x; - int h = current_clip->final_clip_rect.size.y; + if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP]) + y = current_clip->final_clip_rect.position.y; - glScissor(x, y, w, h); + glScissor(current_clip->final_clip_rect.position.x, y, current_clip->final_clip_rect.size.x, current_clip->final_clip_rect.size.y); reclip = false; } @@ -1086,7 +1095,7 @@ void RasterizerCanvasGLES3::_copy_texscreen(const Rect2 &p_rect) { state.using_texture_rect = true; _set_texture_rect_mode(false); - _bind_canvas_texture(state.current_tex, state.current_normal); + _bind_canvas_texture(state.current_tex, state.current_normal, true); glEnable(GL_BLEND); } @@ -1138,7 +1147,11 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons if (current_clip) { glEnable(GL_SCISSOR_TEST); - glScissor(current_clip->final_clip_rect.position.x, (rt_size.height - (current_clip->final_clip_rect.position.y + current_clip->final_clip_rect.size.height)), current_clip->final_clip_rect.size.width, current_clip->final_clip_rect.size.height); + int y = storage->frame.current_rt->height - (current_clip->final_clip_rect.position.y + current_clip->final_clip_rect.size.y); + if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP]) + y = current_clip->final_clip_rect.position.y; + + glScissor(current_clip->final_clip_rect.position.x, y, current_clip->final_clip_rect.size.x, current_clip->final_clip_rect.size.y); } else { @@ -1261,6 +1274,10 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons continue; } + if (t->redraw_if_visible) { //check before proxy, because this is usually used with proxies + VisualServerRaster::redraw_request(); + } + t = t->get_ptr(); if (storage->config.srgb_decode_supported && t->using_srgb) { @@ -1515,7 +1532,10 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons if (reclip) { glEnable(GL_SCISSOR_TEST); - glScissor(current_clip->final_clip_rect.position.x, (rt_size.height - (current_clip->final_clip_rect.position.y + current_clip->final_clip_rect.size.height)), current_clip->final_clip_rect.size.width, current_clip->final_clip_rect.size.height); + int y = storage->frame.current_rt->height - (current_clip->final_clip_rect.position.y + current_clip->final_clip_rect.size.y); + if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP]) + y = current_clip->final_clip_rect.position.y; + glScissor(current_clip->final_clip_rect.position.x, y, current_clip->final_clip_rect.size.width, current_clip->final_clip_rect.size.height); } p_item_list = p_item_list->next; diff --git a/drivers/gles3/rasterizer_canvas_gles3.h b/drivers/gles3/rasterizer_canvas_gles3.h index bfaf1fdb4b..c7f2e54efb 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.h +++ b/drivers/gles3/rasterizer_canvas_gles3.h @@ -123,7 +123,7 @@ public: virtual void canvas_end(); _FORCE_INLINE_ void _set_texture_rect_mode(bool p_enable, bool p_ninepatch = false); - _FORCE_INLINE_ RasterizerStorageGLES3::Texture *_bind_canvas_texture(const RID &p_texture, const RID &p_normal_map); + _FORCE_INLINE_ RasterizerStorageGLES3::Texture *_bind_canvas_texture(const RID &p_texture, const RID &p_normal_map, bool p_force = false); _FORCE_INLINE_ void _draw_gui_primitive(int p_points, const Vector2 *p_vertices, const Color *p_colors, const Vector2 *p_uvs); _FORCE_INLINE_ void _draw_polygon(const int *p_indices, int p_index_count, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor, const int *p_bones, const float *p_weights); diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp index 12e29827b0..1abdaa5f80 100644 --- a/drivers/gles3/rasterizer_gles3.cpp +++ b/drivers/gles3/rasterizer_gles3.cpp @@ -335,7 +335,7 @@ void RasterizerGLES3::set_boot_image(const Ref<Image> &p_image, const Color &p_c if (OS::get_singleton()->is_layered_allowed()) { if (OS::get_singleton()->get_window_per_pixel_transparency_enabled()) { -#ifdef WINDOWS_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) { @@ -392,7 +392,7 @@ void RasterizerGLES3::end_frame(bool p_swap_buffers) { if (OS::get_singleton()->is_layered_allowed()) { if (OS::get_singleton()->get_window_per_pixel_transparency_enabled()) { -#ifdef WINDOWS_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) { diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 8da2c2f9c2..9d0fb462f4 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -896,7 +896,7 @@ void RasterizerSceneGLES3::environment_set_ssr(RID p_env, bool p_enable, int p_m env->ssr_roughness = p_roughness; } -void RasterizerSceneGLES3::environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, const Color &p_color, VS::EnvironmentSSAOQuality p_quality, VisualServer::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) { +void RasterizerSceneGLES3::environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, float p_ao_channel_affect, const Color &p_color, VS::EnvironmentSSAOQuality p_quality, VisualServer::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); @@ -908,6 +908,7 @@ void RasterizerSceneGLES3::environment_set_ssao(RID p_env, bool p_enable, float env->ssao_intensity2 = p_intensity2; env->ssao_bias = p_bias; env->ssao_light_affect = p_light_affect; + env->ssao_ao_channel_affect = p_ao_channel_affect; env->ssao_color = p_color; env->ssao_filter = p_blur; env->ssao_quality = p_quality; @@ -1224,7 +1225,12 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material *p_m } else { + 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); @@ -1335,7 +1341,7 @@ void RasterizerSceneGLES3::_setup_geometry(RenderList::Element *e, const Transfo glBindBuffer(GL_ARRAY_BUFFER, multi_mesh->buffer); //modify the buffer - int stride = (multi_mesh->xform_floats + multi_mesh->color_floats) * 4; + int stride = (multi_mesh->xform_floats + multi_mesh->color_floats + multi_mesh->custom_data_floats) * 4; glEnableVertexAttribArray(8); glVertexAttribPointer(8, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + 0); glVertexAttribDivisor(8, 1); @@ -1356,6 +1362,8 @@ void RasterizerSceneGLES3::_setup_geometry(RenderList::Element *e, const Transfo color_ofs = 8 * 4; } + int custom_data_ofs = color_ofs; + switch (multi_mesh->color_format) { case VS::MULTIMESH_COLOR_NONE: { @@ -1366,12 +1374,33 @@ void RasterizerSceneGLES3::_setup_geometry(RenderList::Element *e, const Transfo glEnableVertexAttribArray(11); glVertexAttribPointer(11, 4, GL_UNSIGNED_BYTE, GL_TRUE, stride, ((uint8_t *)NULL) + color_ofs); glVertexAttribDivisor(11, 1); + custom_data_ofs += 4; } break; case VS::MULTIMESH_COLOR_FLOAT: { glEnableVertexAttribArray(11); glVertexAttribPointer(11, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + color_ofs); glVertexAttribDivisor(11, 1); + custom_data_ofs += 4 * 4; + } break; + } + + switch (multi_mesh->custom_data_format) { + + case VS::MULTIMESH_CUSTOM_DATA_NONE: { + glDisableVertexAttribArray(12); + glVertexAttrib4f(12, 1, 1, 1, 1); + } break; + case VS::MULTIMESH_CUSTOM_DATA_8BIT: { + glEnableVertexAttribArray(12); + glVertexAttribPointer(12, 4, GL_UNSIGNED_BYTE, GL_TRUE, stride, ((uint8_t *)NULL) + custom_data_ofs); + glVertexAttribDivisor(12, 1); + + } break; + case VS::MULTIMESH_CUSTOM_DATA_FLOAT: { + glEnableVertexAttribArray(12); + glVertexAttribPointer(12, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + custom_data_ofs); + glVertexAttribDivisor(12, 1); } break; } @@ -1545,6 +1574,11 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) { RasterizerStorageGLES3::Texture *t = storage->texture_owner.get(c.texture); t = t->get_ptr(); //resolve for proxies + + if (t->redraw_if_visible) { + VisualServerRaster::redraw_request(); + } + #ifdef TOOLS_ENABLED if (t->detect_3d) { t->detect_3d(t->detect_3d_ud); @@ -2363,10 +2397,9 @@ void RasterizerSceneGLES3::_draw_sky(RasterizerStorageGLES3::Sky *p_sky, const C ERR_FAIL_COND(!tex); glActiveTexture(GL_TEXTURE0); - if (tex->proxy && tex->proxy->tex_id) - glBindTexture(tex->target, tex->proxy->tex_id); - else - glBindTexture(tex->target, tex->tex_id); + tex = tex->get_ptr(); //resolve for proxies + + glBindTexture(tex->target, tex->tex_id); if (storage->config.srgb_decode_supported && tex->srgb && !tex->using_srgb) { @@ -2508,6 +2541,7 @@ void RasterizerSceneGLES3::_setup_environment(Environment *env, const CameraMatr state.env_radiance_data.ambient_contribution = env->ambient_sky_contribution; state.ubo_data.ambient_occlusion_affect_light = env->ssao_light_affect; + state.ubo_data.ambient_occlusion_affect_ssao = env->ssao_ao_channel_affect; //fog diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h index a6faeef473..524212b9c1 100644 --- a/drivers/gles3/rasterizer_scene_gles3.h +++ b/drivers/gles3/rasterizer_scene_gles3.h @@ -140,6 +140,7 @@ public: float reflection_multiplier; float subsurface_scatter_width; float ambient_occlusion_affect_light; + float ambient_occlusion_affect_ssao; uint32_t fog_depth_enabled; float fog_depth_begin; @@ -151,6 +152,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]; } ubo_data; @@ -385,6 +387,7 @@ public: float ssao_radius2; float ssao_bias; float ssao_light_affect; + float ssao_ao_channel_affect; Color ssao_color; VS::EnvironmentSSAOQuality ssao_quality; float ssao_bilateral_sharpness; @@ -465,6 +468,7 @@ public: ssao_radius2 = 0.0; ssao_bias = 0.01; ssao_light_affect = 0; + ssao_ao_channel_affect = 0; ssao_filter = VS::ENV_SSAO_BLUR_3x3; ssao_quality = VS::ENV_SSAO_QUALITY_LOW; ssao_bilateral_sharpness = 4; @@ -543,7 +547,7 @@ public: virtual void environment_set_fog(RID p_env, bool p_enable, float p_begin, float p_end, RID p_gradient_texture); virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_in, float p_fade_out, float p_depth_tolerance, bool p_roughness); - virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, const Color &p_color, VS::EnvironmentSSAOQuality p_quality, VS::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness); + virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, float p_ao_channel_affect, const Color &p_color, VS::EnvironmentSSAOQuality p_quality, VS::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness); virtual void environment_set_tonemap(RID p_env, VS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale); diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index 945df35456..eb25d6c7a1 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -1328,6 +1328,13 @@ void RasterizerStorageGLES3::texture_set_proxy(RID p_texture, RID p_proxy) { } } +void RasterizerStorageGLES3::texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) { + + Texture *texture = texture_owner.get(p_texture); + ERR_FAIL_COND(!texture); + texture->redraw_if_visible = p_enable; +} + RID RasterizerStorageGLES3::sky_create() { Sky *sky = memnew(Sky); @@ -1356,6 +1363,8 @@ void RasterizerStorageGLES3::sky_set_texture(RID p_sky, RID p_panorama, int p_ra ERR_FAIL_COND(!texture); } + texture = texture->get_ptr(); //resolve for proxies + glBindVertexArray(0); glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); @@ -3814,12 +3823,12 @@ RID RasterizerStorageGLES3::multimesh_create() { return multimesh_owner.make_rid(multimesh); } -void RasterizerStorageGLES3::multimesh_allocate(RID p_multimesh, int p_instances, VS::MultimeshTransformFormat p_transform_format, VS::MultimeshColorFormat p_color_format) { +void RasterizerStorageGLES3::multimesh_allocate(RID p_multimesh, int p_instances, VS::MultimeshTransformFormat p_transform_format, VS::MultimeshColorFormat p_color_format, VS::MultimeshCustomDataFormat p_data_format) { MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND(!multimesh); - if (multimesh->size == p_instances && multimesh->transform_format == p_transform_format && multimesh->color_format == p_color_format) + if (multimesh->size == p_instances && multimesh->transform_format == p_transform_format && multimesh->color_format == p_color_format && multimesh->custom_data_format == p_data_format) return; if (multimesh->buffer) { @@ -3830,6 +3839,7 @@ void RasterizerStorageGLES3::multimesh_allocate(RID p_multimesh, int p_instances multimesh->size = p_instances; multimesh->transform_format = p_transform_format; multimesh->color_format = p_color_format; + multimesh->custom_data_format = p_data_format; if (multimesh->size) { @@ -3847,11 +3857,22 @@ void RasterizerStorageGLES3::multimesh_allocate(RID p_multimesh, int p_instances multimesh->color_floats = 4; } - int format_floats = multimesh->color_floats + multimesh->xform_floats; + if (multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_NONE) { + multimesh->custom_data_floats = 0; + } else if (multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_8BIT) { + multimesh->custom_data_floats = 1; + } else if (multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_FLOAT) { + multimesh->custom_data_floats = 4; + } + + int format_floats = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats; + multimesh->data.resize(format_floats * p_instances); - for (int i = 0; i < p_instances; i += format_floats) { + + for (int i = 0; i < p_instances * format_floats; i += format_floats) { int color_from = 0; + int custom_data_from = 0; if (multimesh->transform_format == VS::MULTIMESH_TRANSFORM_2D) { multimesh->data[i + 0] = 1.0; @@ -3863,6 +3884,7 @@ void RasterizerStorageGLES3::multimesh_allocate(RID p_multimesh, int p_instances multimesh->data[i + 6] = 0.0; multimesh->data[i + 7] = 0.0; color_from = 8; + custom_data_from = 8; } else { multimesh->data[i + 0] = 1.0; multimesh->data[i + 1] = 0.0; @@ -3877,6 +3899,7 @@ void RasterizerStorageGLES3::multimesh_allocate(RID p_multimesh, int p_instances multimesh->data[i + 10] = 1.0; multimesh->data[i + 11] = 0.0; color_from = 12; + custom_data_from = 12; } if (multimesh->color_format == VS::MULTIMESH_COLOR_NONE) { @@ -3890,12 +3913,33 @@ void RasterizerStorageGLES3::multimesh_allocate(RID p_multimesh, int p_instances cu.colu = 0xFFFFFFFF; multimesh->data[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; + custom_data_from = color_from + 4; + } + + if (multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_NONE) { + //none + } else if (multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_8BIT) { + + union { + uint32_t colu; + float colf; + } cu; + + cu.colu = 0; + multimesh->data[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; } } @@ -3956,7 +4000,7 @@ void RasterizerStorageGLES3::multimesh_instance_set_transform(RID p_multimesh, i ERR_FAIL_INDEX(p_index, multimesh->size); ERR_FAIL_COND(multimesh->transform_format == VS::MULTIMESH_TRANSFORM_2D); - int stride = multimesh->color_floats + multimesh->xform_floats; + int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats; float *dataptr = &multimesh->data[stride * p_index]; dataptr[0] = p_transform.basis.elements[0][0]; @@ -3987,7 +4031,7 @@ void RasterizerStorageGLES3::multimesh_instance_set_transform_2d(RID p_multimesh ERR_FAIL_INDEX(p_index, multimesh->size); ERR_FAIL_COND(multimesh->transform_format == VS::MULTIMESH_TRANSFORM_3D); - int stride = multimesh->color_floats + multimesh->xform_floats; + int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats; float *dataptr = &multimesh->data[stride * p_index]; dataptr[0] = p_transform.elements[0][0]; @@ -4013,7 +4057,7 @@ void RasterizerStorageGLES3::multimesh_instance_set_color(RID p_multimesh, int p ERR_FAIL_INDEX(p_index, multimesh->size); ERR_FAIL_COND(multimesh->color_format == VS::MULTIMESH_COLOR_NONE); - int stride = multimesh->color_floats + multimesh->xform_floats; + int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats; float *dataptr = &multimesh->data[stride * p_index + multimesh->xform_floats]; if (multimesh->color_format == VS::MULTIMESH_COLOR_8BIT) { @@ -4039,6 +4083,38 @@ void RasterizerStorageGLES3::multimesh_instance_set_color(RID p_multimesh, int p } } +void RasterizerStorageGLES3::multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_custom_data) { + + MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); + ERR_FAIL_COND(!multimesh); + ERR_FAIL_INDEX(p_index, multimesh->size); + 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]; + + if (multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_8BIT) { + + uint8_t *data8 = (uint8_t *)dataptr; + data8[0] = CLAMP(p_custom_data.r * 255.0, 0, 255); + data8[1] = CLAMP(p_custom_data.g * 255.0, 0, 255); + data8[2] = CLAMP(p_custom_data.b * 255.0, 0, 255); + data8[3] = CLAMP(p_custom_data.a * 255.0, 0, 255); + + } else if (multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_FLOAT) { + dataptr[0] = p_custom_data.r; + dataptr[1] = p_custom_data.g; + dataptr[2] = p_custom_data.b; + dataptr[3] = p_custom_data.a; + } + + multimesh->dirty_data = true; + multimesh->dirty_aabb = true; + + if (!multimesh->update_list.in_list()) { + multimesh_update_list.add(&multimesh->update_list); + } +} RID RasterizerStorageGLES3::multimesh_get_mesh(RID p_multimesh) const { MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); @@ -4054,7 +4130,7 @@ Transform RasterizerStorageGLES3::multimesh_instance_get_transform(RID p_multime ERR_FAIL_INDEX_V(p_index, multimesh->size, Transform()); ERR_FAIL_COND_V(multimesh->transform_format == VS::MULTIMESH_TRANSFORM_2D, Transform()); - int stride = multimesh->color_floats + multimesh->xform_floats; + int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats; float *dataptr = &multimesh->data[stride * p_index]; Transform xform; @@ -4081,7 +4157,7 @@ Transform2D RasterizerStorageGLES3::multimesh_instance_get_transform_2d(RID p_mu ERR_FAIL_INDEX_V(p_index, multimesh->size, Transform2D()); ERR_FAIL_COND_V(multimesh->transform_format == VS::MULTIMESH_TRANSFORM_3D, Transform2D()); - int stride = multimesh->color_floats + multimesh->xform_floats; + int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats; float *dataptr = &multimesh->data[stride * p_index]; Transform2D xform; @@ -4103,7 +4179,7 @@ Color RasterizerStorageGLES3::multimesh_instance_get_color(RID p_multimesh, int ERR_FAIL_INDEX_V(p_index, multimesh->size, Color()); ERR_FAIL_COND_V(multimesh->color_format == VS::MULTIMESH_COLOR_NONE, Color()); - int stride = multimesh->color_floats + multimesh->xform_floats; + int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats; float *dataptr = &multimesh->data[stride * p_index + multimesh->xform_floats]; if (multimesh->color_format == VS::MULTIMESH_COLOR_8BIT) { @@ -4129,6 +4205,59 @@ Color RasterizerStorageGLES3::multimesh_instance_get_color(RID p_multimesh, int return Color(); } +Color RasterizerStorageGLES3::multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const { + + MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); + ERR_FAIL_COND_V(!multimesh, Color()); + ERR_FAIL_INDEX_V(p_index, multimesh->size, Color()); + 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]; + + if (multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_8BIT) { + union { + uint32_t colu; + float colf; + } cu; + + cu.colf = dataptr[0]; + + return Color::hex(BSWAP32(cu.colu)); + + } else if (multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_FLOAT) { + Color c; + c.r = dataptr[0]; + c.g = dataptr[1]; + c.b = dataptr[2]; + c.a = dataptr[3]; + + return c; + } + + return Color(); +} + +void RasterizerStorageGLES3::multimesh_set_as_bulk_array(RID p_multimesh, const PoolVector<float> &p_array) { + + MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); + ERR_FAIL_COND(!multimesh); + + int dsize = multimesh->data.size(); + + ERR_FAIL_COND(dsize != p_array.size()); + + PoolVector<float>::Read r = p_array.read(); + copymem(multimesh->data.ptrw(), r.ptr(), dsize * sizeof(float)); + + multimesh->dirty_data = true; + multimesh->dirty_aabb = true; + + if (!multimesh->update_list.in_list()) { + multimesh_update_list.add(&multimesh->update_list); + } +} + void RasterizerStorageGLES3::multimesh_set_visible_instances(RID p_multimesh, int p_visible) { MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); @@ -4177,7 +4306,7 @@ void RasterizerStorageGLES3::update_dirty_multimeshes() { mesh_aabb.size += Vector3(0.001, 0.001, 0.001); } - int stride = multimesh->color_floats + multimesh->xform_floats; + int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats; int count = multimesh->data.size(); float *data = multimesh->data.ptrw(); @@ -5895,9 +6024,9 @@ void RasterizerStorageGLES3::update_particles() { tex = resources.white_tex; } break; } - } else { + t = t->get_ptr(); //resolve for proxies target = t->target; tex = t->tex_id; } diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h index 6b626cbd00..80df21941b 100644 --- a/drivers/gles3/rasterizer_storage_gles3.h +++ b/drivers/gles3/rasterizer_storage_gles3.h @@ -268,6 +268,7 @@ public: GLuint tex_id; bool using_srgb; + bool redraw_if_visible; uint16_t stored_cube_sides; @@ -306,6 +307,7 @@ public: detect_normal = NULL; detect_normal_ud = NULL; proxy = NULL; + redraw_if_visible = false; } _ALWAYS_INLINE_ Texture *get_ptr() { @@ -366,6 +368,7 @@ public: virtual void texture_set_detect_normal_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata); virtual void texture_set_proxy(RID p_texture, RID p_proxy); + virtual void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable); /* SKY API */ @@ -756,6 +759,7 @@ public: int size; VS::MultimeshTransformFormat transform_format; VS::MultimeshColorFormat color_format; + VS::MultimeshCustomDataFormat custom_data_format; Vector<float> data; AABB aabb; SelfList<MultiMesh> update_list; @@ -765,6 +769,7 @@ public: int xform_floats; int color_floats; + int custom_data_floats; bool dirty_aabb; bool dirty_data; @@ -776,11 +781,13 @@ public: dirty_data = true; xform_floats = 0; color_floats = 0; + custom_data_floats = 0; visible_instances = -1; size = 0; buffer = 0; transform_format = VS::MULTIMESH_TRANSFORM_2D; color_format = VS::MULTIMESH_COLOR_NONE; + custom_data_format = VS::MULTIMESH_CUSTOM_DATA_NONE; } }; @@ -792,19 +799,23 @@ public: virtual RID multimesh_create(); - virtual void multimesh_allocate(RID p_multimesh, int p_instances, VS::MultimeshTransformFormat p_transform_format, VS::MultimeshColorFormat p_color_format); + virtual void multimesh_allocate(RID p_multimesh, int p_instances, VS::MultimeshTransformFormat p_transform_format, VS::MultimeshColorFormat p_color_format, VS::MultimeshCustomDataFormat p_data_format = VS::MULTIMESH_CUSTOM_DATA_NONE); virtual int multimesh_get_instance_count(RID p_multimesh) const; virtual void multimesh_set_mesh(RID p_multimesh, RID p_mesh); virtual void multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform &p_transform); virtual void multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform); virtual void multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color); + virtual void multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_color); virtual RID multimesh_get_mesh(RID p_multimesh) const; virtual Transform multimesh_instance_get_transform(RID p_multimesh, int p_index) const; virtual Transform2D multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const; virtual Color multimesh_instance_get_color(RID p_multimesh, int p_index) const; + virtual Color multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const; + + virtual void multimesh_set_as_bulk_array(RID p_multimesh, const PoolVector<float> &p_array); virtual void multimesh_set_visible_instances(RID p_multimesh, int p_visible); virtual int multimesh_get_visible_instances(RID p_multimesh) const; diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp index eb8d6c485b..9ad16ac2a2 100644 --- a/drivers/gles3/shader_compiler_gles3.cpp +++ b/drivers/gles3/shader_compiler_gles3.cpp @@ -898,6 +898,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() { actions[VS::SHADER_SPATIAL].render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["world_vertex_coords"] = "#define VERTEX_WORLD_COORDS_USED\n"; + actions[VS::SHADER_SPATIAL].render_mode_defines["ensure_correct_normals"] = "#define ENSURE_CORRECT_NORMALS\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["cull_front"] = "#define DO_SIDE_CHECK\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["cull_disabled"] = "#define DO_SIDE_CHECK\n"; diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl index 326aab4c7c..e7828d265c 100644 --- a/drivers/gles3/shaders/canvas.glsl +++ b/drivers/gles3/shaders/canvas.glsl @@ -82,6 +82,7 @@ layout(std140) uniform LightData { //ubo:1 out vec4 light_uv_interp; +out vec2 transformed_light_uv; out vec4 local_rot; @@ -236,6 +237,13 @@ VERTEX_SHADER_CODE light_uv_interp.xy = (light_matrix * outvec).xy; light_uv_interp.zw =(light_local_matrix * outvec).xy; + + mat3 inverse_light_matrix = mat3(inverse(light_matrix)); + inverse_light_matrix[0] = normalize(inverse_light_matrix[0]); + inverse_light_matrix[1] = normalize(inverse_light_matrix[1]); + inverse_light_matrix[2] = normalize(inverse_light_matrix[2]); + transformed_light_uv = (inverse_light_matrix * vec3(light_uv_interp.zw,0.0)).xy; //for normal mapping + #ifdef USE_SHADOWS pos=outvec.xy; #endif @@ -304,6 +312,7 @@ layout(std140) uniform LightData { uniform lowp sampler2D light_texture; // texunit:-1 in vec4 light_uv_interp; +in vec2 transformed_light_uv; in vec4 local_rot; @@ -518,10 +527,9 @@ FRAGMENT_SHADER_CODE - #ifdef USE_LIGHTING - vec2 light_vec = light_uv_interp.zw;; //for shadow and normal mapping + vec2 light_vec = transformed_light_uv; if (normal_used) { normal.xy = mat2(local_rot.xy,local_rot.zw) * normal.xy; @@ -567,7 +575,7 @@ FRAGMENT_SHADER_CODE color*=light; #ifdef USE_SHADOWS - + light_vec = light_uv_interp.zw; //for shadows float angle_to_light = -atan(light_vec.x,light_vec.y); float PI = 3.14159265358979323846264; /*int i = int(mod(floor((angle_to_light+7.0*PI/6.0)/(4.0*PI/6.0))+1.0, 3.0)); // +1 pq os indices estao em ordem 2,0,1 nos arrays diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index f5481c597c..ed8df04377 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -90,6 +90,7 @@ layout(std140) uniform SceneData { //ubo:0 mediump float reflection_multiplier; mediump float subsurface_scatter_width; mediump float ambient_occlusion_affect_light; + mediump float ambient_occlusion_affect_ao_channel; bool fog_depth_enabled; highp float fog_depth_begin; @@ -322,7 +323,13 @@ void main() { #if !defined(SKIP_TRANSFORM_USED) && defined(VERTEX_WORLD_COORDS_USED) vertex = world_matrix * vertex; + +#if defined(ENSURE_CORRECT_NORMALS) + mat3 normal_matrix = mat3(transpose(inverse(world_matrix))); + normal = normal_matrix * normal; +#else normal = normalize((world_matrix * vec4(normal,0.0)).xyz); +#endif #if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY) @@ -394,7 +401,13 @@ VERTEX_SHADER_CODE #if !defined(SKIP_TRANSFORM_USED) && !defined(VERTEX_WORLD_COORDS_USED) vertex = modelview * vertex; + +#if defined(ENSURE_CORRECT_NORMALS) + mat3 normal_matrix = mat3(transpose(inverse(modelview))); + normal = normal_matrix * normal; +#else normal = normalize((modelview * vec4(normal,0.0)).xyz); +#endif #if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY) @@ -670,6 +683,7 @@ layout(std140) uniform SceneData { mediump float reflection_multiplier; mediump float subsurface_scatter_width; mediump float ambient_occlusion_affect_light; + mediump float ambient_occlusion_affect_ao_channel; bool fog_depth_enabled; highp float fog_depth_begin; @@ -2128,18 +2142,16 @@ FRAGMENT_SHADER_CODE #else -#if defined(ENABLE_AO) - - float ambient_scale=0.0; // AO is supplied by material -#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)); float max_diffuse=max(diffuse_light.r,max(diffuse_light.g,diffuse_light.b)); float total_ambient = max_ambient+max_diffuse+max_emission; float ambient_scale = (total_ambient>0.0) ? (max_ambient+ambient_occlusion_affect_light*max_diffuse)/total_ambient : 0.0; -#endif //ENABLE_AO +#if defined(ENABLE_AO) + ambient_scale=mix(0.0,ambient_scale,ambient_occlusion_affect_ao_channel); +#endif diffuse_buffer=vec4(emission+diffuse_light+ambient_light,ambient_scale); specular_buffer=vec4(specular_light,metallic); diff --git a/drivers/gles3/shaders/tonemap.glsl b/drivers/gles3/shaders/tonemap.glsl index a75871f08e..63475c9039 100644 --- a/drivers/gles3/shaders/tonemap.glsl +++ b/drivers/gles3/shaders/tonemap.glsl @@ -1,28 +1,27 @@ [vertex] - -layout(location=0) in highp vec4 vertex_attrib; -layout(location=4) in vec2 uv_in; +layout (location = 0) in highp vec4 vertex_attrib; +layout (location = 4) in vec2 uv_in; out vec2 uv_interp; -void main() { - +void main() +{ gl_Position = vertex_attrib; + uv_interp = uv_in; -#ifdef V_FLIP - uv_interp.y = 1.0-uv_interp.y; -#endif + #ifdef V_FLIP + uv_interp.y = 1.0f - uv_interp.y; + #endif } [fragment] #if !defined(GLES_OVER_GL) -precision mediump float; + precision mediump float; #endif - in vec2 uv_interp; uniform highp sampler2D source; //texunit:0 @@ -31,297 +30,286 @@ uniform float exposure; uniform float white; #ifdef USE_AUTO_EXPOSURE - -uniform highp sampler2D source_auto_exposure; //texunit:1 -uniform highp float auto_exposure_grey; - + uniform highp sampler2D source_auto_exposure; //texunit:1 + uniform highp float auto_exposure_grey; #endif #if defined(USE_GLOW_LEVEL1) || defined(USE_GLOW_LEVEL2) || defined(USE_GLOW_LEVEL3) || defined(USE_GLOW_LEVEL4) || defined(USE_GLOW_LEVEL5) || defined(USE_GLOW_LEVEL6) || defined(USE_GLOW_LEVEL7) + #define USING_GLOW // only use glow when at least one glow level is selected -uniform highp sampler2D source_glow; //texunit:2 -uniform highp float glow_intensity; - + uniform highp sampler2D source_glow; //texunit:2 + uniform highp float glow_intensity; #endif #ifdef USE_BCS - -uniform vec3 bcs; - + uniform vec3 bcs; #endif #ifdef USE_COLOR_CORRECTION - -uniform sampler2D color_correction; //texunit:3 - + uniform sampler2D color_correction; //texunit:3 #endif - -layout(location = 0) out vec4 frag_color; +layout (location = 0) out vec4 frag_color; #ifdef USE_GLOW_FILTER_BICUBIC + // w0, w1, w2, and w3 are the four cubic B-spline basis functions + float w0(float a) + { + return (1.0f / 6.0f) * (a * (a * (-a + 3.0f) - 3.0f) + 1.0f); + } -// w0, w1, w2, and w3 are the four cubic B-spline basis functions -float w0(float a) -{ - return (1.0/6.0)*(a*(a*(-a + 3.0) - 3.0) + 1.0); -} - -float w1(float a) -{ - return (1.0/6.0)*(a*a*(3.0*a - 6.0) + 4.0); -} - -float w2(float a) -{ - return (1.0/6.0)*(a*(a*(-3.0*a + 3.0) + 3.0) + 1.0); -} - -float w3(float a) -{ - return (1.0/6.0)*(a*a*a); -} - -// g0 and g1 are the two amplitude functions -float g0(float a) -{ - return w0(a) + w1(a); -} + float w1(float a) + { + return (1.0f / 6.0f) * (a * a * (3.0f * a - 6.0f) + 4.0f); + } -float g1(float a) -{ - return w2(a) + w3(a); -} + float w2(float a) + { + return (1.0f / 6.0f) * (a * (a * (-3.0f * a + 3.0f) + 3.0f) + 1.0f); + } -// h0 and h1 are the two offset functions -float h0(float a) -{ - return -1.0 + w1(a) / (w0(a) + w1(a)); -} + float w3(float a) + { + return (1.0f / 6.0f) * (a * a * a); + } -float h1(float a) -{ - return 1.0 + w3(a) / (w2(a) + w3(a)); -} + // g0 and g1 are the two amplitude functions + float g0(float a) + { + return w0(a) + w1(a); + } -uniform ivec2 glow_texture_size; + float g1(float a) + { + return w2(a) + w3(a); + } -vec4 texture2D_bicubic(sampler2D tex, vec2 uv,int p_lod) -{ - float lod=float(p_lod); - vec2 tex_size = vec2(glow_texture_size >> p_lod); - vec2 pixel_size =1.0/tex_size; - uv = uv*tex_size + 0.5; - vec2 iuv = floor( uv ); - vec2 fuv = fract( uv ); - - float g0x = g0(fuv.x); - float g1x = g1(fuv.x); - float h0x = h0(fuv.x); - float h1x = h1(fuv.x); - float h0y = h0(fuv.y); - float h1y = h1(fuv.y); - - vec2 p0 = (vec2(iuv.x + h0x, iuv.y + h0y) - 0.5) * pixel_size; - vec2 p1 = (vec2(iuv.x + h1x, iuv.y + h0y) - 0.5) * pixel_size; - vec2 p2 = (vec2(iuv.x + h0x, iuv.y + h1y) - 0.5) * pixel_size; - vec2 p3 = (vec2(iuv.x + h1x, iuv.y + h1y) - 0.5) * pixel_size; - - return g0(fuv.y) * (g0x * textureLod(tex, p0,lod) + - g1x * textureLod(tex, p1,lod)) + - g1(fuv.y) * (g0x * textureLod(tex, p2,lod) + - g1x * textureLod(tex, p3,lod)); -} + // h0 and h1 are the two offset functions + float h0(float a) + { + return -1.0f + w1(a) / (w0(a) + w1(a)); + } + float h1(float a) + { + return 1.0f + w3(a) / (w2(a) + w3(a)); + } + uniform ivec2 glow_texture_size; -#define GLOW_TEXTURE_SAMPLE(m_tex,m_uv,m_lod) texture2D_bicubic(m_tex,m_uv,m_lod) + vec4 texture2D_bicubic(sampler2D tex, vec2 uv, int p_lod) + { + float lod = float(p_lod); + vec2 tex_size = vec2(glow_texture_size >> p_lod); + vec2 pixel_size = vec2(1.0f) / tex_size; + + uv = uv * tex_size + vec2(0.5f); + + vec2 iuv = floor(uv); + vec2 fuv = fract(uv); + + float g0x = g0(fuv.x); + float g1x = g1(fuv.x); + float h0x = h0(fuv.x); + float h1x = h1(fuv.x); + float h0y = h0(fuv.y); + float h1y = h1(fuv.y); + + vec2 p0 = (vec2(iuv.x + h0x, iuv.y + h0y) - vec2(0.5f)) * pixel_size; + vec2 p1 = (vec2(iuv.x + h1x, iuv.y + h0y) - vec2(0.5f)) * pixel_size; + vec2 p2 = (vec2(iuv.x + h0x, iuv.y + h1y) - vec2(0.5f)) * pixel_size; + vec2 p3 = (vec2(iuv.x + h1x, iuv.y + h1y) - vec2(0.5f)) * pixel_size; + + return g0(fuv.y) * (g0x * textureLod(tex, p0,lod) + + g1x * textureLod(tex, p1,lod)) + + g1(fuv.y) * (g0x * textureLod(tex, p2,lod) + + g1x * textureLod(tex, p3,lod)); + } + #define GLOW_TEXTURE_SAMPLE(m_tex, m_uv, m_lod) texture2D_bicubic(m_tex, m_uv, m_lod) #else - -#define GLOW_TEXTURE_SAMPLE(m_tex,m_uv,m_lod) textureLod(m_tex,m_uv,float(m_lod)) - + #define GLOW_TEXTURE_SAMPLE(m_tex, m_uv, m_lod) textureLod(m_tex, m_uv, float(m_lod)) #endif +vec3 tonemap_filmic(vec3 color, float white) +{ + const float A = 0.15f; + const float B = 0.50f; + const float C = 0.10f; + const float D = 0.20f; + const float E = 0.02f; + const float F = 0.30f; + const float W = 11.2f; + + vec3 color_tonemapped = ((color * (A * color + C * B) + D * E) / (color * (A * color + B) + D * F)) - E / F; + float white_tonemapped = ((white * (A * white + C * B) + D * E) / (white * (A * white + B) + D * F)) - E / F; + + return clamp(color_tonemapped / white_tonemapped, vec3(0.0f), vec3(1.0f)); +} -vec3 tonemap_filmic(vec3 color,float white) { - - float A = 0.15; - float B = 0.50; - float C = 0.10; - float D = 0.20; - float E = 0.02; - float F = 0.30; - float W = 11.2; - - vec3 coltn = ((color*(A*color+C*B)+D*E)/(color*(A*color+B)+D*F))-E/F; - float whitetn = ((white*(A*white+C*B)+D*E)/(white*(A*white+B)+D*F))-E/F; +vec3 tonemap_aces(vec3 color, float white) +{ + const float A = 2.51f; + const float B = 0.03f; + const float C = 2.43f; + const float D = 0.59f; + const float E = 0.14f; - return coltn/whitetn; + vec3 color_tonemapped = (color * (A * color + B)) / (color * (C * color + D) + E); + float white_tonemapped = (white * (A * white + B)) / (white * (C * white + D) + E); + return clamp(color_tonemapped / white_tonemapped, vec3(0.0f), vec3(1.0f)); } -vec3 tonemap_aces(vec3 color) { - float a = 2.51f; - float b = 0.03f; - float c = 2.43f; - float d = 0.59f; - float e = 0.14f; - return color = clamp((color*(a*color+b))/(color*(c*color+d)+e),vec3(0.0),vec3(1.0)); +vec3 tonemap_reindhart(vec3 color, float white) +{ + return clamp((color) / (1.0f + color) * (1.0f + (color / (white))), vec3(0.0f), vec3(1.0f)); // whitepoint is probably not in linear space here! } -vec3 tonemap_reindhart(vec3 color,float white) { - - return ( color * ( 1.0 + ( color / ( white) ) ) ) / ( 1.0 + color ); +vec3 linear_to_srgb(vec3 color) // convert linear rgb to srgb, assumes clamped input in range [0;1] +{ + const vec3 a = vec3(0.055f); + return mix((vec3(1.0f) + a) * pow(color.rgb, vec3(1.0f / 2.4f)) - a, 12.92f * color.rgb, lessThan(color.rgb, vec3(0.0031308f))); } -void main() { - - vec4 color = textureLod(source, uv_interp, 0.0); - -#ifdef USE_AUTO_EXPOSURE - - color/=texelFetch(source_auto_exposure,ivec2(0,0),0).r/auto_exposure_grey; -#endif - - color*=exposure; - -#if defined(USE_GLOW_LEVEL1) || defined(USE_GLOW_LEVEL2) || defined(USE_GLOW_LEVEL3) || defined(USE_GLOW_LEVEL4) || defined(USE_GLOW_LEVEL5) || defined(USE_GLOW_LEVEL6) || defined(USE_GLOW_LEVEL7) -#define USING_GLOW -#endif - -#if defined(USING_GLOW) - vec3 glow = vec3(0.0); - -#ifdef USE_GLOW_LEVEL1 - - glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,1).rgb; -#endif - -#ifdef USE_GLOW_LEVEL2 - glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,2).rgb; -#endif - -#ifdef USE_GLOW_LEVEL3 - glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,3).rgb; -#endif - -#ifdef USE_GLOW_LEVEL4 - glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,4).rgb; -#endif - -#ifdef USE_GLOW_LEVEL5 - glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,5).rgb; -#endif - -#ifdef USE_GLOW_LEVEL6 - glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,6).rgb; -#endif - -#ifdef USE_GLOW_LEVEL7 - glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,7).rgb; -#endif - - - glow *= glow_intensity; +vec3 apply_tonemapping(vec3 color, float white) // inputs are LINEAR, always outputs clamped [0;1] color +{ + #ifdef USE_REINDHART_TONEMAPPER + return tonemap_reindhart(color, white); + #endif -#endif + #ifdef USE_FILMIC_TONEMAPPER + return tonemap_filmic(color, white); + #endif + #ifdef USE_ACES_TONEMAPPER + return tonemap_aces(color, white); + #endif -#ifdef USE_REINDHART_TONEMAPPER + return clamp(color, vec3(0.0f), vec3(1.0f)); // no other seleced -> linear +} - color.rgb = tonemap_reindhart(color.rgb,white); +vec3 gather_glow(sampler2D tex, vec2 uv) // sample all selected glow levels +{ + vec3 glow = vec3(0.0f); -# if defined(USING_GLOW) - glow = tonemap_reindhart(glow,white); -# endif + #ifdef USE_GLOW_LEVEL1 + glow += GLOW_TEXTURE_SAMPLE(tex, uv, 1).rgb; + #endif -#endif + #ifdef USE_GLOW_LEVEL2 + glow += GLOW_TEXTURE_SAMPLE(tex, uv, 2).rgb; + #endif -#ifdef USE_FILMIC_TONEMAPPER + #ifdef USE_GLOW_LEVEL3 + glow += GLOW_TEXTURE_SAMPLE(tex, uv, 3).rgb; + #endif - color.rgb = tonemap_filmic(color.rgb,white); + #ifdef USE_GLOW_LEVEL4 + glow += GLOW_TEXTURE_SAMPLE(tex, uv, 4).rgb; + #endif -# if defined(USING_GLOW) - glow = tonemap_filmic(glow,white); -# endif + #ifdef USE_GLOW_LEVEL5 + glow += GLOW_TEXTURE_SAMPLE(tex, uv, 5).rgb; + #endif -#endif + #ifdef USE_GLOW_LEVEL6 + glow += GLOW_TEXTURE_SAMPLE(tex, uv, 6).rgb; + #endif -#ifdef USE_ACES_TONEMAPPER + #ifdef USE_GLOW_LEVEL7 + glow += GLOW_TEXTURE_SAMPLE(tex, uv, 7).rgb; + #endif - color.rgb = tonemap_aces(color.rgb); + return glow; +} -# if defined(USING_GLOW) - glow = tonemap_aces(glow); -# endif +vec3 apply_glow(vec3 color, vec3 glow) // apply glow using the selected blending mode +{ + #ifdef USE_GLOW_REPLACE + color = glow; + #endif -#endif + #ifdef USE_GLOW_SCREEN + color = max((color + glow) - (color * glow), vec3(0.0)); + #endif -#ifdef KEEP_3D_LINEAR - // leave color as is... -#else - //regular Linear -> SRGB conversion - vec3 a = vec3(0.055); - color.rgb = mix( (vec3(1.0)+a)*pow(color.rgb,vec3(1.0/2.4))-a , 12.92*color.rgb , lessThan(color.rgb,vec3(0.0031308))); -#endif + #ifdef USE_GLOW_SOFTLIGHT + glow = glow * vec3(0.5f) + vec3(0.5f); -#if defined(USING_GLOW) - glow = mix( (vec3(1.0)+a)*pow(glow,vec3(1.0/2.4))-a , 12.92*glow , lessThan(glow,vec3(0.0031308))); -#endif + color.r = (glow.r <= 0.5f) ? (color.r - (1.0f - 2.0f * glow.r) * color.r * (1.0f - color.r)) : (((glow.r > 0.5f) && (color.r <= 0.25f)) ? (color.r + (2.0f * glow.r - 1.0f) * (4.0f * color.r * (4.0f * color.r + 1.0f) * (color.r - 1.0f) + 7.0f * color.r)) : (color.r + (2.0f * glow.r - 1.0f) * (sqrt(color.r) - color.r))); + color.g = (glow.g <= 0.5f) ? (color.g - (1.0f - 2.0f * glow.g) * color.g * (1.0f - color.g)) : (((glow.g > 0.5f) && (color.g <= 0.25f)) ? (color.g + (2.0f * glow.g - 1.0f) * (4.0f * color.g * (4.0f * color.g + 1.0f) * (color.g - 1.0f) + 7.0f * color.g)) : (color.g + (2.0f * glow.g - 1.0f) * (sqrt(color.g) - color.g))); + color.b = (glow.b <= 0.5f) ? (color.b - (1.0f - 2.0f * glow.b) * color.b * (1.0f - color.b)) : (((glow.b > 0.5f) && (color.b <= 0.25f)) ? (color.b + (2.0f * glow.b - 1.0f) * (4.0f * color.b * (4.0f * color.b + 1.0f) * (color.b - 1.0f) + 7.0f * color.b)) : (color.b + (2.0f * glow.b - 1.0f) * (sqrt(color.b) - color.b))); + #endif -//glow needs to be added in SRGB space (together with image space effects) + #if !defined(USE_GLOW_SCREEN) && !defined(USE_GLOW_SOFTLIGHT) && !defined(USE_GLOW_REPLACE) // no other selected -> additive + color += glow; + #endif - color.rgb = clamp(color.rgb,0.0,1.0); + return color; +} -#if defined(USING_GLOW) - glow = clamp(glow,0.0,1.0); -#endif +vec3 apply_bcs(vec3 color, vec3 bcs) +{ + color = mix(vec3(0.0f), color, bcs.x); + color = mix(vec3(0.5f), color, bcs.y); + color = mix(vec3(dot(vec3(1.0f), color) * 0.33333f), color, bcs.z); -#ifdef USE_GLOW_REPLACE + return color; +} - color.rgb = glow; +vec3 apply_color_correction(vec3 color, sampler2D correction_tex) +{ + color.r = texture(correction_tex, vec2(color.r, 0.0f)).r; + color.g = texture(correction_tex, vec2(color.g, 0.0f)).g; + color.b = texture(correction_tex, vec2(color.b, 0.0f)).b; -#endif + return color; +} -#ifdef USE_GLOW_SCREEN +void main() +{ + vec3 color = textureLod(source, uv_interp, 0.0f).rgb; - color.rgb = max((color.rgb + glow) - (color.rgb * glow), vec3(0.0)); + // Exposure -#endif + #ifdef USE_AUTO_EXPOSURE + color /= texelFetch(source_auto_exposure, ivec2(0, 0), 0).r / auto_exposure_grey; + #endif -#ifdef USE_GLOW_SOFTLIGHT + color *= exposure; - { + // Early Tonemap & SRGB Conversion - glow = (glow * 0.5) + 0.5; - color.r = (glow.r <= 0.5) ? (color.r - (1.0 - 2.0 * glow.r) * color.r * (1.0 - color.r)) : (((glow.r > 0.5) && (color.r <= 0.25)) ? (color.r + (2.0 * glow.r - 1.0) * (4.0 * color.r * (4.0 * color.r + 1.0) * (color.r - 1.0) + 7.0 * color.r)) : (color.r + (2.0 * glow.r - 1.0) * (sqrt(color.r) - color.r))); - color.g = (glow.g <= 0.5) ? (color.g - (1.0 - 2.0 * glow.g) * color.g * (1.0 - color.g)) : (((glow.g > 0.5) && (color.g <= 0.25)) ? (color.g + (2.0 * glow.g - 1.0) * (4.0 * color.g * (4.0 * color.g + 1.0) * (color.g - 1.0) + 7.0 * color.g)) : (color.g + (2.0 * glow.g - 1.0) * (sqrt(color.g) - color.g))); - color.b = (glow.b <= 0.5) ? (color.b - (1.0 - 2.0 * glow.b) * color.b * (1.0 - color.b)) : (((glow.b > 0.5) && (color.b <= 0.25)) ? (color.b + (2.0 * glow.b - 1.0) * (4.0 * color.b * (4.0 * color.b + 1.0) * (color.b - 1.0) + 7.0 * color.b)) : (color.b + (2.0 * glow.b - 1.0) * (sqrt(color.b) - color.b))); - } + color = apply_tonemapping(color, white); -#endif + #ifdef KEEP_3D_LINEAR + // leave color as is (-> don't convert to SRGB) + #else + color = linear_to_srgb(color); // regular linear -> SRGB conversion + #endif -#if defined(USING_GLOW) && !defined(USE_GLOW_SCREEN) && !defined(USE_GLOW_SOFTLIGHT) && !defined(USE_GLOW_REPLACE) - //additive - color.rgb+=glow; -#endif + // Glow -#ifdef USE_BCS + #ifdef USING_GLOW + vec3 glow = gather_glow(source_glow, uv_interp) * glow_intensity; - color.rgb = mix(vec3(0.0),color.rgb,bcs.x); - color.rgb = mix(vec3(0.5),color.rgb,bcs.y); - color.rgb = mix(vec3(dot(vec3(1.0),color.rgb)*0.33333),color.rgb,bcs.z); + // high dynamic range -> SRGB + glow = apply_tonemapping(glow, white); + glow = linear_to_srgb(glow); -#endif + color = apply_glow(color, glow); + #endif -#ifdef USE_COLOR_CORRECTION + // Additional effects - color.r = texture(color_correction,vec2(color.r,0.0)).r; - color.g = texture(color_correction,vec2(color.g,0.0)).g; - color.b = texture(color_correction,vec2(color.b,0.0)).b; -#endif + #ifdef USE_BCS + color = apply_bcs(color, bcs); + #endif + #ifdef USE_COLOR_CORRECTION + color = apply_color_correction(color, color_correction); + #endif - frag_color=vec4(color.rgb,1.0); + frag_color = vec4(color, 1.0f); } diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp index 1e34d63b13..05dfd69f58 100644 --- a/drivers/unix/os_unix.cpp +++ b/drivers/unix/os_unix.cpp @@ -244,7 +244,7 @@ OS::TimeZoneInfo OS_Unix::get_time_zone_info() const { void OS_Unix::delay_usec(uint32_t p_usec) const { - struct timespec rem = { p_usec / 1000000, (p_usec % 1000000) * 1000 }; + struct timespec rem = { static_cast<time_t>(p_usec / 1000000), static_cast<long>((p_usec % 1000000) * 1000) }; while (nanosleep(&rem, &rem) == EINTR) { } } diff --git a/drivers/unix/socket_helpers.h b/drivers/unix/socket_helpers.h index 5ef9ad3088..5b42c13eae 100644 --- a/drivers/unix/socket_helpers.h +++ b/drivers/unix/socket_helpers.h @@ -124,6 +124,13 @@ static int _socket_create(IP::Type &p_type, int type, int protocol) { WARN_PRINT("Unable to set/unset IPv4 address mapping over IPv6"); } } + if (protocol == IPPROTO_UDP && p_type != IP::TYPE_IPV6) { + // Enable broadcasting for UDP sockets if it's not IPv6 only (IPv6 has no broadcast option). + int broadcast = 1; + if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, (char *)&broadcast, sizeof(broadcast)) != 0) { + WARN_PRINT("Error when enabling broadcasting"); + } + } return sockfd; } diff --git a/drivers/unix/stream_peer_tcp_posix.cpp b/drivers/unix/stream_peer_tcp_posix.cpp index 6d798f32f9..44b9ef1d7c 100644 --- a/drivers/unix/stream_peer_tcp_posix.cpp +++ b/drivers/unix/stream_peer_tcp_posix.cpp @@ -297,6 +297,7 @@ Error StreamPeerTCPPosix::read(uint8_t *p_buffer, int p_bytes, int &r_received, status = STATUS_NONE; peer_port = 0; peer_host = IP_Address(); + r_received = total_read; return ERR_FILE_EOF; } else { diff --git a/drivers/windows/stream_peer_tcp_winsock.cpp b/drivers/windows/stream_peer_tcp_winsock.cpp index cb501ce35d..19c937170b 100644 --- a/drivers/windows/stream_peer_tcp_winsock.cpp +++ b/drivers/windows/stream_peer_tcp_winsock.cpp @@ -212,6 +212,7 @@ Error StreamPeerTCPWinsock::read(uint8_t *p_buffer, int p_bytes, int &r_received _block(sockfd, true, false); } else if (read == 0) { disconnect_from_host(); + r_received = total_read; return ERR_FILE_EOF; } else { |