diff options
Diffstat (limited to 'drivers')
48 files changed, 4101 insertions, 3736 deletions
diff --git a/drivers/alsa/audio_driver_alsa.cpp b/drivers/alsa/audio_driver_alsa.cpp index 7884269103..f86c4d82ef 100644 --- a/drivers/alsa/audio_driver_alsa.cpp +++ b/drivers/alsa/audio_driver_alsa.cpp @@ -181,7 +181,7 @@ Error AudioDriverALSA::init() { } void AudioDriverALSA::thread_func(void *p_udata) { - AudioDriverALSA *ad = (AudioDriverALSA *)p_udata; + AudioDriverALSA *ad = static_cast<AudioDriverALSA *>(p_udata); while (!ad->exit_thread) { ad->lock(); diff --git a/drivers/alsamidi/midi_driver_alsamidi.cpp b/drivers/alsamidi/midi_driver_alsamidi.cpp index 0674c90cd6..c334146dd2 100644 --- a/drivers/alsamidi/midi_driver_alsamidi.cpp +++ b/drivers/alsamidi/midi_driver_alsamidi.cpp @@ -73,7 +73,7 @@ static int get_message_size(uint8_t message) { } void MIDIDriverALSAMidi::thread_func(void *p_udata) { - MIDIDriverALSAMidi *md = (MIDIDriverALSAMidi *)p_udata; + MIDIDriverALSAMidi *md = static_cast<MIDIDriverALSAMidi *>(p_udata); uint64_t timestamp = 0; uint8_t buffer[256]; int expected_size = 255; diff --git a/drivers/coreaudio/audio_driver_coreaudio.cpp b/drivers/coreaudio/audio_driver_coreaudio.cpp index e2b195350f..276e69e470 100644 --- a/drivers/coreaudio/audio_driver_coreaudio.cpp +++ b/drivers/coreaudio/audio_driver_coreaudio.cpp @@ -42,7 +42,7 @@ OSStatus AudioDriverCoreAudio::input_device_address_cb(AudioObjectID inObjectID, UInt32 inNumberAddresses, const AudioObjectPropertyAddress *inAddresses, void *inClientData) { - AudioDriverCoreAudio *driver = (AudioDriverCoreAudio *)inClientData; + AudioDriverCoreAudio *driver = static_cast<AudioDriverCoreAudio *>(inClientData); // If our selected device is the Default call set_device to update the // kAudioOutputUnitProperty_CurrentDevice property @@ -56,7 +56,7 @@ OSStatus AudioDriverCoreAudio::input_device_address_cb(AudioObjectID inObjectID, OSStatus AudioDriverCoreAudio::output_device_address_cb(AudioObjectID inObjectID, UInt32 inNumberAddresses, const AudioObjectPropertyAddress *inAddresses, void *inClientData) { - AudioDriverCoreAudio *driver = (AudioDriverCoreAudio *)inClientData; + AudioDriverCoreAudio *driver = static_cast<AudioDriverCoreAudio *>(inClientData); // If our selected device is the Default call set_device to update the // kAudioOutputUnitProperty_CurrentDevice property @@ -168,7 +168,7 @@ OSStatus AudioDriverCoreAudio::output_callback(void *inRefCon, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData) { - AudioDriverCoreAudio *ad = (AudioDriverCoreAudio *)inRefCon; + AudioDriverCoreAudio *ad = static_cast<AudioDriverCoreAudio *>(inRefCon); if (!ad->active || !ad->try_lock()) { for (unsigned int i = 0; i < ioData->mNumberBuffers; i++) { @@ -209,7 +209,7 @@ OSStatus AudioDriverCoreAudio::input_callback(void *inRefCon, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData) { - AudioDriverCoreAudio *ad = (AudioDriverCoreAudio *)inRefCon; + AudioDriverCoreAudio *ad = static_cast<AudioDriverCoreAudio *>(inRefCon); if (!ad->active) { return 0; } diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index b47d2e08f1..ebf538351e 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -38,8 +38,9 @@ #include "core/config/project_settings.h" #include "servers/rendering/rendering_server_default.h" -#include "storage/canvas_texture_storage.h" #include "storage/config.h" +#include "storage/material_storage.h" +#include "storage/texture_storage.h" #ifndef GLES_OVER_GL #define glClearDepth glClearDepthf @@ -115,9 +116,11 @@ void RasterizerCanvasGLES3::_update_transform_to_mat4(const Transform3D &p_trans } void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, bool &r_sdf_used) { - storage->frame.current_rt = nullptr; + GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton(); - storage->_set_current_render_target(p_to_render_target); + texture_storage->frame.current_rt = nullptr; + + texture_storage->_set_current_render_target(p_to_render_target); Transform2D canvas_transform_inverse = p_canvas_transform.affine_inverse(); @@ -129,7 +132,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_ //update canvas state uniform buffer StateBuffer state_buffer; - Size2i ssize = storage->render_target_get_size(p_to_render_target); + Size2i ssize = texture_storage->render_target_get_size(p_to_render_target); Transform3D screen_transform; screen_transform.translate(-(ssize.width / 2.0f), -(ssize.height / 2.0f), 0.0f); @@ -148,11 +151,11 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_ state_buffer.canvas_modulate[2] = p_modulate.b; state_buffer.canvas_modulate[3] = p_modulate.a; - Size2 render_target_size = storage->render_target_get_size(p_to_render_target); + Size2 render_target_size = texture_storage->render_target_get_size(p_to_render_target); state_buffer.screen_pixel_size[0] = 1.0 / render_target_size.x; state_buffer.screen_pixel_size[1] = 1.0 / render_target_size.y; - state_buffer.time = storage->frame.time; + state_buffer.time = texture_storage->frame.time; state_buffer.use_pixel_snap = p_snap_2d_vertices_to_pixel; state_buffer.directional_light_count = 0; //directional_light_count; @@ -165,7 +168,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_ state_buffer.screen_to_sdf[0] = 1.0 / state_buffer.sdf_to_screen[0]; state_buffer.screen_to_sdf[1] = 1.0 / state_buffer.sdf_to_screen[1]; - Rect2 sdf_rect = storage->render_target_get_sdf_rect(p_to_render_target); + Rect2 sdf_rect = texture_storage->render_target_get_sdf_rect(p_to_render_target); Rect2 sdf_tex_rect(sdf_rect.position / canvas_scale, sdf_rect.size / canvas_scale); state_buffer.sdf_to_tex[0] = 1.0 / sdf_tex_rect.size.width; @@ -212,6 +215,8 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_ } void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool p_to_backbuffer) { + GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton(); + GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton(); Item *current_clip = nullptr; Transform2D canvas_transform_inverse = p_canvas_transform_inverse; @@ -228,14 +233,14 @@ void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_cou Item *ci = items[i]; RID material = ci->material_owner == nullptr ? ci->material : ci->material_owner->material; - RasterizerStorageGLES3::Material *material_ptr = storage->material_owner.get_or_null(material); + GLES3::Material *material_ptr = material_storage->get_material(material); if (material.is_null() && ci->canvas_group != nullptr) { material = default_canvas_group_material; } if (material != prev_material) { - RasterizerStorageGLES3::Shader *shader_ptr = nullptr; + GLES3::Shader *shader_ptr = nullptr; if (material_ptr) { shader_ptr = material_ptr->shader; @@ -360,7 +365,6 @@ void RasterizerCanvasGLES3::_render_item(RID p_render_target, const Item *p_item state.instance_data_array[r_index].dst_rect[i] = 0.0; state.instance_data_array[r_index].lights[i] = uint32_t(0); } - state.instance_data_array[r_index].flags = base_flags; state.instance_data_array[r_index].color_texture_pixel_size[0] = 0.0; state.instance_data_array[r_index].color_texture_pixel_size[1] = 0.0; @@ -819,24 +823,24 @@ void RasterizerCanvasGLES3::_render_batch(uint32_t &r_index) { } // TODO maybe dont use -void RasterizerCanvasGLES3::_end_batch(uint32_t &r_index) { +void RasterizerCanvasGLES3::_end_batch(uint32_t p_index) { for (int i = 0; i < 4; i++) { - state.instance_data_array[r_index].modulation[i] = 0.0; - state.instance_data_array[r_index].ninepatch_margins[i] = 0.0; - state.instance_data_array[r_index].src_rect[i] = 0.0; - state.instance_data_array[r_index].dst_rect[i] = 0.0; + state.instance_data_array[p_index].modulation[i] = 0.0; + state.instance_data_array[p_index].ninepatch_margins[i] = 0.0; + state.instance_data_array[p_index].src_rect[i] = 0.0; + state.instance_data_array[p_index].dst_rect[i] = 0.0; } - state.instance_data_array[r_index].flags = uint32_t(0); - state.instance_data_array[r_index].color_texture_pixel_size[0] = 0.0; - state.instance_data_array[r_index].color_texture_pixel_size[1] = 0.0; + state.instance_data_array[p_index].flags = uint32_t(0); + state.instance_data_array[p_index].color_texture_pixel_size[0] = 0.0; + state.instance_data_array[p_index].color_texture_pixel_size[1] = 0.0; - state.instance_data_array[r_index].pad[0] = 0.0; - state.instance_data_array[r_index].pad[1] = 0.0; + state.instance_data_array[p_index].pad[0] = 0.0; + state.instance_data_array[p_index].pad[1] = 0.0; - state.instance_data_array[r_index].lights[0] = uint32_t(0); - state.instance_data_array[r_index].lights[1] = uint32_t(0); - state.instance_data_array[r_index].lights[2] = uint32_t(0); - state.instance_data_array[r_index].lights[3] = uint32_t(0); + state.instance_data_array[p_index].lights[0] = uint32_t(0); + state.instance_data_array[p_index].lights[1] = uint32_t(0); + state.instance_data_array[p_index].lights[2] = uint32_t(0); + state.instance_data_array[p_index].lights[3] = uint32_t(0); } RID RasterizerCanvasGLES3::light_create() { @@ -879,19 +883,21 @@ void RasterizerCanvasGLES3::update() { } void RasterizerCanvasGLES3::canvas_begin() { + GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton(); + state.using_transparent_rt = false; - if (storage->frame.current_rt) { - storage->bind_framebuffer(storage->frame.current_rt->fbo); - state.using_transparent_rt = storage->frame.current_rt->flags[RendererStorage::RENDER_TARGET_TRANSPARENT]; + if (texture_storage->frame.current_rt) { + glBindFramebuffer(GL_FRAMEBUFFER, texture_storage->frame.current_rt->fbo); + state.using_transparent_rt = texture_storage->frame.current_rt->flags[GLES3::TextureStorage::RENDER_TARGET_TRANSPARENT]; } - if (storage->frame.current_rt && storage->frame.current_rt->clear_requested) { - const Color &col = storage->frame.current_rt->clear_color; + if (texture_storage->frame.current_rt && texture_storage->frame.current_rt->clear_requested) { + const Color &col = texture_storage->frame.current_rt->clear_color; glClearColor(col.r, col.g, col.b, col.a); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - storage->frame.current_rt->clear_requested = false; + texture_storage->frame.current_rt->clear_requested = false; } reset_canvas(); @@ -906,6 +912,8 @@ void RasterizerCanvasGLES3::canvas_end() { } void RasterizerCanvasGLES3::_bind_canvas_texture(RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, uint32_t &r_index, RID &r_last_texture, Size2 &r_texpixel_size) { + GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton(); + if (p_texture == RID()) { p_texture = default_canvas_texture; } @@ -930,7 +938,7 @@ void RasterizerCanvasGLES3::_bind_canvas_texture(RID p_texture, RS::CanvasItemTe ct = t->canvas_texture; } else { - ct = GLES3::CanvasTextureStorage::get_singleton()->get_canvas_texture(p_texture); + ct = GLES3::TextureStorage::get_singleton()->get_canvas_texture(p_texture); } if (!ct) { @@ -1037,6 +1045,8 @@ void RasterizerCanvasGLES3::_set_uniforms() { } void RasterizerCanvasGLES3::reset_canvas() { + GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton(); + glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); glDisable(GL_SCISSOR_TEST); @@ -1045,7 +1055,7 @@ void RasterizerCanvasGLES3::reset_canvas() { // Default to Mix. glBlendEquation(GL_FUNC_ADD); - if (storage->frame.current_rt && storage->frame.current_rt->flags[RendererStorage::RENDER_TARGET_TRANSPARENT]) { + if (texture_storage->frame.current_rt && texture_storage->frame.current_rt->flags[GLES3::TextureStorage::RENDER_TARGET_TRANSPARENT]) { glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); } else { glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE); @@ -1092,8 +1102,8 @@ RendererCanvasRender::PolygonID RasterizerCanvasGLES3::request_polygon(const Vec { glBindBuffer(GL_ARRAY_BUFFER, pb.vertex_buffer); glBufferData(GL_ARRAY_BUFFER, stride * vertex_count * sizeof(float), nullptr, GL_STATIC_DRAW); // TODO may not be necessary - const uint8_t *r = polygon_buffer.ptr(); - float *fptr = (float *)r; + uint8_t *r = polygon_buffer.ptrw(); + float *fptr = reinterpret_cast<float *>(r); uint32_t *uptr = (uint32_t *)r; uint32_t base_offset = 0; { @@ -1251,9 +1261,8 @@ void RasterizerCanvasGLES3::_allocate_instance_data_buffer() { } void RasterizerCanvasGLES3::initialize() { - // !BAS! shouldn't we be obtaining storage here as well? - canvas_texture_storage = GLES3::CanvasTextureStorage::get_singleton(); - texture_storage = GLES3::TextureStorage::get_singleton(); + GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton(); + GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton(); // quad buffer { @@ -1423,10 +1432,10 @@ void RasterizerCanvasGLES3::initialize() { //state.canvas_shader.set_conditional(CanvasOldShaderGLES3::USE_PIXEL_SNAP, GLOBAL_DEF("rendering/quality/2d/use_pixel_snap", false)); { - default_canvas_group_shader = storage->shader_allocate(); - storage->shader_initialize(default_canvas_group_shader); + default_canvas_group_shader = material_storage->shader_allocate(); + material_storage->shader_initialize(default_canvas_group_shader); - storage->shader_set_code(default_canvas_group_shader, R"( + material_storage->shader_set_code(default_canvas_group_shader, R"( // Default CanvasGroup shader. shader_type canvas_item; @@ -1441,14 +1450,14 @@ void fragment() { COLOR *= c; } )"); - default_canvas_group_material = storage->material_allocate(); - storage->material_initialize(default_canvas_group_material); + default_canvas_group_material = material_storage->material_allocate(); + material_storage->material_initialize(default_canvas_group_material); - storage->material_set_shader(default_canvas_group_material, default_canvas_group_shader); + material_storage->material_set_shader(default_canvas_group_material, default_canvas_group_shader); } - default_canvas_texture = canvas_texture_storage->canvas_texture_allocate(); - canvas_texture_storage->canvas_texture_initialize(default_canvas_texture); + default_canvas_texture = texture_storage->canvas_texture_allocate(); + texture_storage->canvas_texture_initialize(default_canvas_texture); state.using_light = nullptr; state.using_transparent_rt = false; @@ -1456,13 +1465,27 @@ void fragment() { state.current_shader_version = state.canvas_shader_default_version; } -RasterizerCanvasGLES3::RasterizerCanvasGLES3() { +RasterizerCanvasGLES3 *RasterizerCanvasGLES3::singleton = nullptr; + +RasterizerCanvasGLES3 *RasterizerCanvasGLES3::get_singleton() { + return singleton; } + +RasterizerCanvasGLES3::RasterizerCanvasGLES3(RasterizerStorageGLES3 *p_storage) { + singleton = this; + storage = p_storage; + initialize(); +} + RasterizerCanvasGLES3::~RasterizerCanvasGLES3() { + GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton(); + GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton(); + state.canvas_shader.version_free(state.canvas_shader_default_version); - storage->free(default_canvas_group_material); - storage->free(default_canvas_group_shader); - canvas_texture_storage->canvas_texture_free(default_canvas_texture); + material_storage->material_free(default_canvas_group_material); + material_storage->shader_free(default_canvas_group_shader); + texture_storage->canvas_texture_free(default_canvas_texture); + singleton = nullptr; } void RasterizerCanvasGLES3::finalize() { diff --git a/drivers/gles3/rasterizer_canvas_gles3.h b/drivers/gles3/rasterizer_canvas_gles3.h index 1f57c2b5ea..99b079b8bb 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.h +++ b/drivers/gles3/rasterizer_canvas_gles3.h @@ -37,7 +37,7 @@ #include "rasterizer_storage_gles3.h" #include "servers/rendering/renderer_canvas_render.h" #include "servers/rendering/renderer_compositor.h" -#include "storage/canvas_texture_storage.h" +#include "storage/material_storage.h" #include "storage/texture_storage.h" #include "shaders/canvas.glsl.gen.h" @@ -45,6 +45,8 @@ class RasterizerSceneGLES3; class RasterizerCanvasGLES3 : public RendererCanvasRender { + static RasterizerCanvasGLES3 *singleton; + _FORCE_INLINE_ void _update_transform_2d_to_mat2x4(const Transform2D &p_transform, float *p_mat2x4); _FORCE_INLINE_ void _update_transform_2d_to_mat2x3(const Transform2D &p_transform, float *p_mat2x3); @@ -166,7 +168,7 @@ public: LocalVector<GLsync> fences; uint32_t current_buffer = 0; - InstanceData *instance_data_array; + InstanceData *instance_data_array = nullptr; bool canvas_texscreen_used; CanvasShaderGLES3 canvas_shader; RID canvas_shader_current_version; @@ -195,7 +197,7 @@ public: bool end_batch = false; Transform3D vp; - Light *using_light; + Light *using_light = nullptr; bool using_shadow; bool using_transparent_rt; @@ -217,11 +219,7 @@ public: typedef void Texture; - RasterizerSceneGLES3 *scene_render; - - GLES3::CanvasTextureStorage *canvas_texture_storage; - GLES3::TextureStorage *texture_storage; - RasterizerStorageGLES3 *storage; + RasterizerStorageGLES3 *storage = nullptr; void _set_uniforms(); @@ -272,12 +270,14 @@ public: void _render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool p_to_backbuffer = false); void _render_item(RID p_render_target, const Item *p_item, const Transform2D &p_canvas_transform_inverse, Item *¤t_clip, Light *p_lights, uint32_t &r_index); void _render_batch(uint32_t &p_max_index); - void _end_batch(uint32_t &p_max_index); + void _end_batch(uint32_t p_index); void _allocate_instance_data_buffer(); void initialize(); void finalize(); - RasterizerCanvasGLES3(); + + static RasterizerCanvasGLES3 *get_singleton(); + RasterizerCanvasGLES3(RasterizerStorageGLES3 *storage); ~RasterizerCanvasGLES3(); }; diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp index faadb2a4ed..a8133c1317 100644 --- a/drivers/gles3/rasterizer_gles3.cpp +++ b/drivers/gles3/rasterizer_gles3.cpp @@ -34,6 +34,7 @@ #include "core/config/project_settings.h" #include "core/os/os.h" +#include "storage/texture_storage.h" #define _EXT_DEBUG_OUTPUT_SYNCHRONOUS_ARB 0x8242 #define _EXT_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB 0x8243 @@ -87,6 +88,8 @@ #endif void RasterizerGLES3::begin_frame(double frame_step) { + GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton(); + frame++; delta = frame_step; @@ -95,14 +98,14 @@ void RasterizerGLES3::begin_frame(double frame_step) { double time_roll_over = GLOBAL_GET("rendering/limits/time/time_rollover_secs"); time_total = Math::fmod(time_total, time_roll_over); - storage.frame.time = time_total; - storage.frame.count++; - storage.frame.delta = frame_step; + texture_storage->frame.time = time_total; + texture_storage->frame.count++; + texture_storage->frame.delta = frame_step; - storage.update_dirty_resources(); + storage->update_dirty_resources(); - storage.info.render_final = storage.info.render; - storage.info.render.reset(); + storage->info.render_final = storage->info.render; + storage->info.render.reset(); //scene->iteration(); } @@ -193,10 +196,14 @@ typedef void (*DEBUGPROCARB)(GLenum source, typedef void (*DebugMessageCallbackARB)(DEBUGPROCARB callback, const void *userParam); void RasterizerGLES3::initialize() { - print_verbose("Using OpenGL video driver"); + print_line("OpenGL Renderer: " + RS::get_singleton()->get_video_adapter_name()); - texture_storage.set_main_thread_id(Thread::get_caller_id()); + texture_storage->set_main_thread_id(Thread::get_caller_id()); + // make sure the OS knows to only access the renderer from the main thread + OS::get_singleton()->set_render_main_thread_mode(OS::RENDER_MAIN_THREAD_ONLY); +} +RasterizerGLES3::RasterizerGLES3() { #ifdef GLAD_ENABLED if (!gladLoadGL()) { ERR_PRINT("Error initializing GLAD"); @@ -248,30 +255,38 @@ void RasterizerGLES3::initialize() { #endif // GLES_OVER_GL #endif // CAN_DEBUG - print_line("OpenGL Renderer: " + RS::get_singleton()->get_video_adapter_name()); - storage.initialize(); - canvas.initialize(); - // scene.initialize(); - - // make sure the OS knows to only access the renderer from the main thread - OS::get_singleton()->set_render_main_thread_mode(OS::RENDER_MAIN_THREAD_ONLY); + // OpenGL needs to be initialized before initializing the Rasterizers + config = memnew(GLES3::Config); + texture_storage = memnew(GLES3::TextureStorage); + material_storage = memnew(GLES3::MaterialStorage); + mesh_storage = memnew(GLES3::MeshStorage); + particles_storage = memnew(GLES3::ParticlesStorage); + light_storage = memnew(GLES3::LightStorage); + storage = memnew(RasterizerStorageGLES3); + canvas = memnew(RasterizerCanvasGLES3(storage)); + scene = memnew(RasterizerSceneGLES3); } -RasterizerGLES3::RasterizerGLES3() { - canvas.storage = &storage; - canvas.scene_render = &scene; - storage.canvas = &canvas; - //scene.storage = &storage; - storage.scene = &scene; +RasterizerGLES3::~RasterizerGLES3() { + memdelete(scene); + memdelete(canvas); + memdelete(storage); + memdelete(light_storage); + memdelete(particles_storage); + memdelete(mesh_storage); + memdelete(material_storage); + memdelete(texture_storage); + memdelete(config); } void RasterizerGLES3::prepare_for_blitting_render_targets() { } void RasterizerGLES3::_blit_render_target_to_screen(RID p_render_target, DisplayServer::WindowID p_screen, const Rect2 &p_screen_rect) { - ERR_FAIL_COND(storage.frame.current_rt); + GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton(); + ERR_FAIL_COND(texture_storage->frame.current_rt); - GLES3::RenderTarget *rt = storage.render_target_owner.get_or_null(p_render_target); + GLES3::RenderTarget *rt = texture_storage->get_render_target(p_render_target); ERR_FAIL_COND(!rt); // TODO: do we need a keep 3d linear option? @@ -282,16 +297,17 @@ void RasterizerGLES3::_blit_render_target_to_screen(RID p_render_target, Display glBindFramebuffer(GL_READ_FRAMEBUFFER, rt->fbo); } glReadBuffer(GL_COLOR_ATTACHMENT0); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, RasterizerStorageGLES3::system_fbo); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, GLES3::TextureStorage::system_fbo); glBlitFramebuffer(0, 0, rt->width, rt->height, 0, p_screen_rect.size.y, p_screen_rect.size.x, 0, GL_COLOR_BUFFER_BIT, GL_NEAREST); } // is this p_screen useless in a multi window environment? void RasterizerGLES3::blit_render_targets_to_screen(DisplayServer::WindowID p_screen, const BlitToScreen *p_render_targets, int p_amount) { // do this once off for all blits - storage.bind_framebuffer_system(); + GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton(); + glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo); - storage.frame.current_rt = nullptr; + texture_storage->frame.current_rt = nullptr; for (int i = 0; i < p_amount; i++) { const BlitToScreen &blit = p_render_targets[i]; @@ -322,12 +338,12 @@ void RasterizerGLES3::set_boot_image(const Ref<Image> &p_image, const Color &p_c } glClear(GL_COLOR_BUFFER_BIT); - canvas.canvas_begin(); + canvas->canvas_begin(); - RID texture = texture_storage.texture_create(); + RID texture = texture_storage->texture_create(); //texture_storage.texture_allocate(texture, p_image->get_width(), p_image->get_height(), 0, p_image->get_format(), VS::TEXTURE_TYPE_2D, p_use_filter ? VS::TEXTURE_FLAG_FILTER : 0); - texture_storage._texture_allocate_internal(texture, p_image->get_width(), p_image->get_height(), 0, p_image->get_format(), RenderingDevice::TEXTURE_TYPE_2D); - texture_storage.texture_set_data(texture, p_image); + texture_storage->_texture_allocate_internal(texture, p_image->get_width(), p_image->get_height(), 0, p_image->get_format(), RenderingDevice::TEXTURE_TYPE_2D); + texture_storage->texture_set_data(texture, p_image); Rect2 imgrect(0, 0, p_image->get_width(), p_image->get_height()); Rect2 screenrect; @@ -349,13 +365,13 @@ void RasterizerGLES3::set_boot_image(const Ref<Image> &p_image, const Color &p_c screenrect.position += ((Size2(win_size.width, win_size.height) - screenrect.size) / 2.0).floor(); } - GLES3::Texture *t = texture_storage.get_texture(texture); - glActiveTexture(GL_TEXTURE0 + config.max_texture_image_units - 1); + GLES3::Texture *t = texture_storage->get_texture(texture); + glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 1); glBindTexture(GL_TEXTURE_2D, t->tex_id); glBindTexture(GL_TEXTURE_2D, 0); - canvas.canvas_end(); + canvas->canvas_end(); - texture_storage.texture_free(texture); + texture_storage->texture_free(texture); end_frame(true); } diff --git a/drivers/gles3/rasterizer_gles3.h b/drivers/gles3/rasterizer_gles3.h index 4aa94e5293..139695165e 100644 --- a/drivers/gles3/rasterizer_gles3.h +++ b/drivers/gles3/rasterizer_gles3.h @@ -37,10 +37,11 @@ #include "rasterizer_scene_gles3.h" #include "rasterizer_storage_gles3.h" #include "servers/rendering/renderer_compositor.h" -#include "storage/canvas_texture_storage.h" #include "storage/config.h" -#include "storage/decal_atlas_storage.h" -#include "storage/render_target_storage.h" +#include "storage/light_storage.h" +#include "storage/material_storage.h" +#include "storage/mesh_storage.h" +#include "storage/particles_storage.h" #include "storage/texture_storage.h" class RasterizerGLES3 : public RendererCompositor { @@ -51,23 +52,27 @@ private: double time_total = 0.0; protected: - GLES3::Config config; - GLES3::CanvasTextureStorage canvas_texture_storage; - GLES3::TextureStorage texture_storage; - GLES3::DecalAtlasStorage decal_atlas_storage; - RasterizerStorageGLES3 storage; - RasterizerCanvasGLES3 canvas; - RasterizerSceneGLES3 scene; + GLES3::Config *config = nullptr; + GLES3::TextureStorage *texture_storage = nullptr; + GLES3::MaterialStorage *material_storage = nullptr; + GLES3::MeshStorage *mesh_storage = nullptr; + GLES3::ParticlesStorage *particles_storage = nullptr; + GLES3::LightStorage *light_storage = nullptr; + RasterizerStorageGLES3 *storage = nullptr; + RasterizerCanvasGLES3 *canvas = nullptr; + RasterizerSceneGLES3 *scene = nullptr; void _blit_render_target_to_screen(RID p_render_target, DisplayServer::WindowID p_screen, const Rect2 &p_screen_rect); public: - RendererCanvasTextureStorage *get_canvas_texture_storage() { return &canvas_texture_storage; } - RendererTextureStorage *get_texture_storage() { return &texture_storage; } - RendererDecalAtlasStorage *get_decal_atlas_storage() { return &decal_atlas_storage; } - RendererStorage *get_storage() { return &storage; } - RendererCanvasRender *get_canvas() { return &canvas; } - RendererSceneRender *get_scene() { return &scene; } + RendererLightStorage *get_light_storage() { return light_storage; } + RendererMaterialStorage *get_material_storage() { return material_storage; } + RendererMeshStorage *get_mesh_storage() { return mesh_storage; } + RendererParticlesStorage *get_particles_storage() { return particles_storage; } + RendererTextureStorage *get_texture_storage() { return texture_storage; } + RendererStorage *get_storage() { return storage; } + RendererCanvasRender *get_canvas() { return canvas; } + RendererSceneRender *get_scene() { return scene; } void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter = true); @@ -94,7 +99,7 @@ public: double get_frame_delta_time() const { return delta; } RasterizerGLES3(); - ~RasterizerGLES3() {} + ~RasterizerGLES3(); }; #endif // GLES3_ENABLED diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 1382573461..08d6dd25cf 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -411,7 +411,7 @@ void RasterizerSceneGLES3::voxel_gi_set_quality(RS::VoxelGIQuality) { void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData *p_camera_data, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data, RendererScene::RenderInfo *r_render_info) { } -void RasterizerSceneGLES3::render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { +void RasterizerSceneGLES3::render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { } void RasterizerSceneGLES3::render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<GeometryInstance *> &p_instances) { diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h index 12bb21a5a0..1c78c66c20 100644 --- a/drivers/gles3/rasterizer_scene_gles3.h +++ b/drivers/gles3/rasterizer_scene_gles3.h @@ -196,7 +196,7 @@ public: void voxel_gi_set_quality(RS::VoxelGIQuality) override; void render_scene(RID p_render_buffers, const CameraData *p_camera_data, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RendererScene::RenderInfo *r_render_info = nullptr) override; - void render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; + void render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<GeometryInstance *> &p_instances) override; void set_scene_pass(uint64_t p_pass) override; diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index 5efbc715ab..124c2330c2 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -34,12 +34,10 @@ #include "core/config/project_settings.h" #include "core/math/transform_3d.h" -#include "rasterizer_canvas_gles3.h" +// #include "rasterizer_canvas_gles3.h" #include "rasterizer_scene_gles3.h" #include "servers/rendering/shader_language.h" -GLuint RasterizerStorageGLES3::system_fbo = 0; - void RasterizerStorageGLES3::bind_quad_array() const { //glBindBuffer(GL_ARRAY_BUFFER, resources.quadie); //glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, 0); @@ -58,1150 +56,9 @@ RID RasterizerStorageGLES3::sky_create() { void RasterizerStorageGLES3::sky_set_texture(RID p_sky, RID p_panorama, int p_radiance_size) { } -/* SHADER API */ - -RID RasterizerStorageGLES3::shader_allocate() { - Shader *shader = memnew(Shader); - shader->mode = RS::SHADER_CANVAS_ITEM; - //shader->shader = &scene->state.scene_shader; - RID rid = shader_owner.make_rid(shader); - _shader_make_dirty(shader); - shader->self = rid; - - return rid; -} - -void RasterizerStorageGLES3::shader_initialize(RID p_rid) { - // noop -} - -//RID RasterizerStorageGLES3::shader_create() { -// Shader *shader = memnew(Shader); -// shader->mode = RS::SHADER_SPATIAL; -// shader->shader = &scene->state.scene_shader; -// RID rid = shader_owner.make_rid(shader); -// _shader_make_dirty(shader); -// shader->self = rid; - -// return rid; -//} - -void RasterizerStorageGLES3::_shader_make_dirty(Shader *p_shader) { - if (p_shader->dirty_list.in_list()) { - return; - } - - _shader_dirty_list.add(&p_shader->dirty_list); -} - -void RasterizerStorageGLES3::shader_set_code(RID p_shader, const String &p_code) { - Shader *shader = shader_owner.get_or_null(p_shader); - ERR_FAIL_COND(!shader); - - shader->code = p_code; - - String mode_string = ShaderLanguage::get_shader_type(p_code); - RS::ShaderMode mode; - - if (mode_string == "canvas_item") { - mode = RS::SHADER_CANVAS_ITEM; - } else if (mode_string == "particles") { - mode = RS::SHADER_PARTICLES; - } else if (mode_string == "sky") { - mode = RS::SHADER_SKY; - } else if (mode_string == "spatial") { - mode = RS::SHADER_SPATIAL; - } else { - mode = RS::SHADER_MAX; - ERR_PRINT("shader type " + mode_string + " not supported in OpenGL renderer"); - } - - if (shader->version.is_valid() && mode != shader->mode) { - shader->shader->version_free(shader->version); - shader->version = RID(); - } - - shader->mode = mode; - - // TODO handle all shader types - if (mode == RS::SHADER_CANVAS_ITEM) { - shader->shader = &canvas->state.canvas_shader; - - } else if (mode == RS::SHADER_SPATIAL) { - //shader->shader = &scene->state.scene_shader; - } else if (mode == RS::SHADER_PARTICLES) { - } else if (mode == RS::SHADER_SKY) { - } else { - return; - } - - if (shader->version.is_null() && shader->shader) { - shader->version = shader->shader->version_create(); - } - - _shader_make_dirty(shader); -} - -String RasterizerStorageGLES3::shader_get_code(RID p_shader) const { - const Shader *shader = shader_owner.get_or_null(p_shader); - ERR_FAIL_COND_V(!shader, ""); - - return shader->code; -} - -void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const { - _shader_dirty_list.remove(&p_shader->dirty_list); - - p_shader->valid = false; - - p_shader->uniforms.clear(); - - if (p_shader->code.is_empty()) { - return; //just invalid, but no error - } - - ShaderCompiler::GeneratedCode gen_code; - ShaderCompiler::IdentifierActions *actions = nullptr; - - switch (p_shader->mode) { - case RS::SHADER_CANVAS_ITEM: { - p_shader->canvas_item.light_mode = Shader::CanvasItem::LIGHT_MODE_NORMAL; - p_shader->canvas_item.blend_mode = Shader::CanvasItem::BLEND_MODE_MIX; - - p_shader->canvas_item.uses_screen_texture = false; - p_shader->canvas_item.uses_screen_uv = false; - p_shader->canvas_item.uses_time = false; - p_shader->canvas_item.uses_modulate = false; - p_shader->canvas_item.uses_color = false; - p_shader->canvas_item.uses_vertex = false; - - p_shader->canvas_item.uses_model_matrix = false; - p_shader->canvas_item.uses_extra_matrix = false; - p_shader->canvas_item.uses_projection_matrix = false; - p_shader->canvas_item.uses_instance_custom = false; - - shaders.actions_canvas.render_mode_values["blend_add"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_ADD); - shaders.actions_canvas.render_mode_values["blend_mix"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_MIX); - shaders.actions_canvas.render_mode_values["blend_sub"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_SUB); - shaders.actions_canvas.render_mode_values["blend_mul"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_MUL); - shaders.actions_canvas.render_mode_values["blend_premul_alpha"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_PMALPHA); - - shaders.actions_canvas.render_mode_values["unshaded"] = Pair<int *, int>(&p_shader->canvas_item.light_mode, Shader::CanvasItem::LIGHT_MODE_UNSHADED); - shaders.actions_canvas.render_mode_values["light_only"] = Pair<int *, int>(&p_shader->canvas_item.light_mode, Shader::CanvasItem::LIGHT_MODE_LIGHT_ONLY); - - shaders.actions_canvas.usage_flag_pointers["SCREEN_UV"] = &p_shader->canvas_item.uses_screen_uv; - shaders.actions_canvas.usage_flag_pointers["SCREEN_PIXEL_SIZE"] = &p_shader->canvas_item.uses_screen_uv; - shaders.actions_canvas.usage_flag_pointers["SCREEN_TEXTURE"] = &p_shader->canvas_item.uses_screen_texture; - shaders.actions_canvas.usage_flag_pointers["TIME"] = &p_shader->canvas_item.uses_time; - shaders.actions_canvas.usage_flag_pointers["MODULATE"] = &p_shader->canvas_item.uses_modulate; - shaders.actions_canvas.usage_flag_pointers["COLOR"] = &p_shader->canvas_item.uses_color; - - shaders.actions_canvas.usage_flag_pointers["VERTEX"] = &p_shader->canvas_item.uses_vertex; - - shaders.actions_canvas.usage_flag_pointers["MODEL_MATRIX"] = &p_shader->canvas_item.uses_model_matrix; - shaders.actions_canvas.usage_flag_pointers["EXTRA_MATRIX"] = &p_shader->canvas_item.uses_extra_matrix; - shaders.actions_canvas.usage_flag_pointers["PROJECTION_MATRIX"] = &p_shader->canvas_item.uses_projection_matrix; - shaders.actions_canvas.usage_flag_pointers["INSTANCE_CUSTOM"] = &p_shader->canvas_item.uses_instance_custom; - - actions = &shaders.actions_canvas; - actions->uniforms = &p_shader->uniforms; - } break; - - case RS::SHADER_SPATIAL: { - // TODO remove once 3D is added back - return; - p_shader->spatial.blend_mode = Shader::Spatial::BLEND_MODE_MIX; - p_shader->spatial.depth_draw_mode = Shader::Spatial::DEPTH_DRAW_OPAQUE; - p_shader->spatial.cull_mode = Shader::Spatial::CULL_MODE_BACK; - p_shader->spatial.uses_alpha = false; - p_shader->spatial.uses_alpha_scissor = false; - p_shader->spatial.uses_discard = false; - p_shader->spatial.unshaded = false; - p_shader->spatial.no_depth_test = false; - p_shader->spatial.uses_sss = false; - p_shader->spatial.uses_time = false; - p_shader->spatial.uses_vertex_lighting = false; - p_shader->spatial.uses_screen_texture = false; - p_shader->spatial.uses_depth_texture = false; - p_shader->spatial.uses_vertex = false; - p_shader->spatial.uses_tangent = false; - p_shader->spatial.uses_ensure_correct_normals = false; - p_shader->spatial.writes_modelview_or_projection = false; - p_shader->spatial.uses_world_coordinates = false; - - shaders.actions_scene.render_mode_values["blend_add"] = Pair<int *, int>(&p_shader->spatial.blend_mode, Shader::Spatial::BLEND_MODE_ADD); - shaders.actions_scene.render_mode_values["blend_mix"] = Pair<int *, int>(&p_shader->spatial.blend_mode, Shader::Spatial::BLEND_MODE_MIX); - shaders.actions_scene.render_mode_values["blend_sub"] = Pair<int *, int>(&p_shader->spatial.blend_mode, Shader::Spatial::BLEND_MODE_SUB); - shaders.actions_scene.render_mode_values["blend_mul"] = Pair<int *, int>(&p_shader->spatial.blend_mode, Shader::Spatial::BLEND_MODE_MUL); - - shaders.actions_scene.render_mode_values["depth_draw_opaque"] = Pair<int *, int>(&p_shader->spatial.depth_draw_mode, Shader::Spatial::DEPTH_DRAW_OPAQUE); - shaders.actions_scene.render_mode_values["depth_draw_always"] = Pair<int *, int>(&p_shader->spatial.depth_draw_mode, Shader::Spatial::DEPTH_DRAW_ALWAYS); - shaders.actions_scene.render_mode_values["depth_draw_never"] = Pair<int *, int>(&p_shader->spatial.depth_draw_mode, Shader::Spatial::DEPTH_DRAW_NEVER); - shaders.actions_scene.render_mode_values["depth_draw_alpha_prepass"] = Pair<int *, int>(&p_shader->spatial.depth_draw_mode, Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS); - - shaders.actions_scene.render_mode_values["cull_front"] = Pair<int *, int>(&p_shader->spatial.cull_mode, Shader::Spatial::CULL_MODE_FRONT); - shaders.actions_scene.render_mode_values["cull_back"] = Pair<int *, int>(&p_shader->spatial.cull_mode, Shader::Spatial::CULL_MODE_BACK); - shaders.actions_scene.render_mode_values["cull_disabled"] = Pair<int *, int>(&p_shader->spatial.cull_mode, Shader::Spatial::CULL_MODE_DISABLED); - - shaders.actions_scene.render_mode_flags["unshaded"] = &p_shader->spatial.unshaded; - shaders.actions_scene.render_mode_flags["depth_test_disable"] = &p_shader->spatial.no_depth_test; - - shaders.actions_scene.render_mode_flags["vertex_lighting"] = &p_shader->spatial.uses_vertex_lighting; - - shaders.actions_scene.render_mode_flags["world_vertex_coords"] = &p_shader->spatial.uses_world_coordinates; - - shaders.actions_scene.render_mode_flags["ensure_correct_normals"] = &p_shader->spatial.uses_ensure_correct_normals; - - shaders.actions_scene.usage_flag_pointers["ALPHA"] = &p_shader->spatial.uses_alpha; - shaders.actions_scene.usage_flag_pointers["ALPHA_SCISSOR"] = &p_shader->spatial.uses_alpha_scissor; - - shaders.actions_scene.usage_flag_pointers["SSS_STRENGTH"] = &p_shader->spatial.uses_sss; - shaders.actions_scene.usage_flag_pointers["DISCARD"] = &p_shader->spatial.uses_discard; - shaders.actions_scene.usage_flag_pointers["SCREEN_TEXTURE"] = &p_shader->spatial.uses_screen_texture; - shaders.actions_scene.usage_flag_pointers["DEPTH_TEXTURE"] = &p_shader->spatial.uses_depth_texture; - shaders.actions_scene.usage_flag_pointers["TIME"] = &p_shader->spatial.uses_time; - - // Use of any of these BUILTINS indicate the need for transformed tangents. - // This is needed to know when to transform tangents in software skinning. - shaders.actions_scene.usage_flag_pointers["TANGENT"] = &p_shader->spatial.uses_tangent; - shaders.actions_scene.usage_flag_pointers["NORMALMAP"] = &p_shader->spatial.uses_tangent; - - shaders.actions_scene.write_flag_pointers["MODELVIEW_MATRIX"] = &p_shader->spatial.writes_modelview_or_projection; - shaders.actions_scene.write_flag_pointers["PROJECTION_MATRIX"] = &p_shader->spatial.writes_modelview_or_projection; - shaders.actions_scene.write_flag_pointers["VERTEX"] = &p_shader->spatial.uses_vertex; - - actions = &shaders.actions_scene; - actions->uniforms = &p_shader->uniforms; - } break; - - default: { - return; - } break; - } - - Error err = shaders.compiler.compile(p_shader->mode, p_shader->code, actions, p_shader->path, gen_code); - if (err != OK) { - return; - } - - Vector<StringName> texture_uniform_names; - for (int i = 0; i < gen_code.texture_uniforms.size(); i++) { - texture_uniform_names.push_back(gen_code.texture_uniforms[i].name); - } - - p_shader->shader->version_set_code(p_shader->version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX], gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT], gen_code.defines, texture_uniform_names); - - p_shader->texture_uniforms = gen_code.texture_uniforms; - - p_shader->uses_vertex_time = gen_code.uses_vertex_time; - p_shader->uses_fragment_time = gen_code.uses_fragment_time; - - for (SelfList<Material> *E = p_shader->materials.first(); E; E = E->next()) { - _material_make_dirty(E->self()); - } - - p_shader->valid = true; -} - -void RasterizerStorageGLES3::update_dirty_shaders() { - while (_shader_dirty_list.first()) { - _update_shader(_shader_dirty_list.first()->self()); - } -} - -void RasterizerStorageGLES3::shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const { - Shader *shader = shader_owner.get_or_null(p_shader); - ERR_FAIL_COND(!shader); - - if (shader->dirty_list.in_list()) { - _update_shader(shader); - } - - Map<int, StringName> order; - - for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = shader->uniforms.front(); E; E = E->next()) { - if (E->get().texture_order >= 0) { - order[E->get().texture_order + 100000] = E->key(); - } else { - order[E->get().order] = E->key(); - } - } - - for (Map<int, StringName>::Element *E = order.front(); E; E = E->next()) { - PropertyInfo pi; - ShaderLanguage::ShaderNode::Uniform &u = shader->uniforms[E->get()]; - - pi.name = E->get(); - - switch (u.type) { - case ShaderLanguage::TYPE_VOID: { - pi.type = Variant::NIL; - } break; - - case ShaderLanguage::TYPE_BOOL: { - pi.type = Variant::BOOL; - } break; - - // bool vectors - case ShaderLanguage::TYPE_BVEC2: { - pi.type = Variant::INT; - pi.hint = PROPERTY_HINT_FLAGS; - pi.hint_string = "x,y"; - } break; - case ShaderLanguage::TYPE_BVEC3: { - pi.type = Variant::INT; - pi.hint = PROPERTY_HINT_FLAGS; - pi.hint_string = "x,y,z"; - } break; - case ShaderLanguage::TYPE_BVEC4: { - pi.type = Variant::INT; - pi.hint = PROPERTY_HINT_FLAGS; - pi.hint_string = "x,y,z,w"; - } break; - - // int stuff - case ShaderLanguage::TYPE_UINT: - case ShaderLanguage::TYPE_INT: { - pi.type = Variant::INT; - - if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_RANGE) { - pi.hint = PROPERTY_HINT_RANGE; - pi.hint_string = rtos(u.hint_range[0]) + "," + rtos(u.hint_range[1]) + "," + rtos(u.hint_range[2]); - } - } break; - - case ShaderLanguage::TYPE_IVEC2: - case ShaderLanguage::TYPE_UVEC2: - case ShaderLanguage::TYPE_IVEC3: - case ShaderLanguage::TYPE_UVEC3: - case ShaderLanguage::TYPE_IVEC4: - case ShaderLanguage::TYPE_UVEC4: { - // not sure what this should be in godot 4 - // pi.type = Variant::POOL_INT_ARRAY; - pi.type = Variant::PACKED_INT32_ARRAY; - } break; - - case ShaderLanguage::TYPE_FLOAT: { - pi.type = Variant::FLOAT; - if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_RANGE) { - pi.hint = PROPERTY_HINT_RANGE; - pi.hint_string = rtos(u.hint_range[0]) + "," + rtos(u.hint_range[1]) + "," + rtos(u.hint_range[2]); - } - } break; - - case ShaderLanguage::TYPE_VEC2: { - pi.type = Variant::VECTOR2; - } break; - case ShaderLanguage::TYPE_VEC3: { - pi.type = Variant::VECTOR3; - } break; - - case ShaderLanguage::TYPE_VEC4: { - if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) { - pi.type = Variant::COLOR; - } else { - pi.type = Variant::PLANE; - } - } break; - - case ShaderLanguage::TYPE_MAT2: { - pi.type = Variant::TRANSFORM2D; - } break; - - case ShaderLanguage::TYPE_MAT3: { - pi.type = Variant::BASIS; - } break; - - case ShaderLanguage::TYPE_MAT4: { - pi.type = Variant::TRANSFORM3D; - } break; - - case ShaderLanguage::TYPE_SAMPLER2D: - // case ShaderLanguage::TYPE_SAMPLEREXT: - case ShaderLanguage::TYPE_ISAMPLER2D: - case ShaderLanguage::TYPE_USAMPLER2D: { - pi.type = Variant::OBJECT; - pi.hint = PROPERTY_HINT_RESOURCE_TYPE; - pi.hint_string = "Texture"; - } break; - - case ShaderLanguage::TYPE_SAMPLERCUBE: { - pi.type = Variant::OBJECT; - pi.hint = PROPERTY_HINT_RESOURCE_TYPE; - pi.hint_string = "CubeMap"; - } break; - - case ShaderLanguage::TYPE_SAMPLER2DARRAY: - case ShaderLanguage::TYPE_ISAMPLER2DARRAY: - case ShaderLanguage::TYPE_USAMPLER2DARRAY: - case ShaderLanguage::TYPE_SAMPLER3D: - case ShaderLanguage::TYPE_ISAMPLER3D: - case ShaderLanguage::TYPE_USAMPLER3D: { - // Not implemented in OpenGL - } break; - // new for godot 4 - case ShaderLanguage::TYPE_SAMPLERCUBEARRAY: - case ShaderLanguage::TYPE_STRUCT: - case ShaderLanguage::TYPE_MAX: { - } break; - } - - p_param_list->push_back(pi); - } -} - -void RasterizerStorageGLES3::shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture, int p_index) { - Shader *shader = shader_owner.get_or_null(p_shader); - ERR_FAIL_COND(!shader); - ERR_FAIL_COND(p_texture.is_valid() && !GLES3::TextureStorage::get_singleton()->owns_texture(p_texture)); - - if (!p_texture.is_valid()) { - if (shader->default_textures.has(p_name) && shader->default_textures[p_name].has(p_index)) { - shader->default_textures[p_name].erase(p_index); - - if (shader->default_textures[p_name].is_empty()) { - shader->default_textures.erase(p_name); - } - } - } else { - if (!shader->default_textures.has(p_name)) { - shader->default_textures[p_name] = Map<int, RID>(); - } - shader->default_textures[p_name][p_index] = p_texture; - } - - _shader_make_dirty(shader); -} - -RID RasterizerStorageGLES3::shader_get_default_texture_param(RID p_shader, const StringName &p_name, int p_index) const { - const Shader *shader = shader_owner.get_or_null(p_shader); - ERR_FAIL_COND_V(!shader, RID()); - - if (shader->default_textures.has(p_name) && shader->default_textures[p_name].has(p_index)) { - return shader->default_textures[p_name][p_index]; - } - - return RID(); -} - -/* COMMON MATERIAL API */ - -void RasterizerStorageGLES3::_material_make_dirty(Material *p_material) const { - if (p_material->dirty_list.in_list()) { - return; - } - - _material_dirty_list.add(&p_material->dirty_list); -} - -RID RasterizerStorageGLES3::material_allocate() { - Material *material = memnew(Material); - return material_owner.make_rid(material); -} - -void RasterizerStorageGLES3::material_initialize(RID p_rid) { -} - -//RID RasterizerStorageGLES3::material_create() { -// Material *material = memnew(Material); - -// return material_owner.make_rid(material); -//} - -void RasterizerStorageGLES3::material_set_shader(RID p_material, RID p_shader) { - Material *material = material_owner.get_or_null(p_material); - ERR_FAIL_COND(!material); - - Shader *shader = shader_owner.get_or_null(p_shader); - - if (material->shader) { - // if a shader is present, remove the old shader - material->shader->materials.remove(&material->list); - } - - material->shader = shader; - - if (shader) { - shader->materials.add(&material->list); - } - - _material_make_dirty(material); -} - -RID RasterizerStorageGLES3::material_get_shader(RID p_material) const { - const Material *material = material_owner.get_or_null(p_material); - ERR_FAIL_COND_V(!material, RID()); - - if (material->shader) { - return material->shader->self; - } - - return RID(); -} - -void RasterizerStorageGLES3::material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) { - Material *material = material_owner.get_or_null(p_material); - ERR_FAIL_COND(!material); - - if (p_value.get_type() == Variant::NIL) { - material->params.erase(p_param); - } else { - material->params[p_param] = p_value; - } - - _material_make_dirty(material); -} - -Variant RasterizerStorageGLES3::material_get_param(RID p_material, const StringName &p_param) const { - const Material *material = material_owner.get_or_null(p_material); - ERR_FAIL_COND_V(!material, RID()); - - if (material->params.has(p_param)) { - return material->params[p_param]; - } - - return material_get_param_default(p_material, p_param); -} - -Variant RasterizerStorageGLES3::material_get_param_default(RID p_material, const StringName &p_param) const { - const Material *material = material_owner.get_or_null(p_material); - ERR_FAIL_COND_V(!material, Variant()); - - if (material->shader) { - if (material->shader->uniforms.has(p_param)) { - ShaderLanguage::ShaderNode::Uniform uniform = material->shader->uniforms[p_param]; - Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value; - return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.hint); - } - } - return Variant(); -} - -void RasterizerStorageGLES3::material_set_line_width(RID p_material, float p_width) { - Material *material = material_owner.get_or_null(p_material); - ERR_FAIL_COND(!material); - - material->line_width = p_width; -} - -void RasterizerStorageGLES3::material_set_next_pass(RID p_material, RID p_next_material) { - Material *material = material_owner.get_or_null(p_material); - ERR_FAIL_COND(!material); - - material->next_pass = p_next_material; -} - -bool RasterizerStorageGLES3::material_is_animated(RID p_material) { - Material *material = material_owner.get_or_null(p_material); - ERR_FAIL_COND_V(!material, false); - if (material->dirty_list.in_list()) { - _update_material(material); - } - - bool animated = material->is_animated_cache; - if (!animated && material->next_pass.is_valid()) { - animated = material_is_animated(material->next_pass); - } - return animated; -} - -bool RasterizerStorageGLES3::material_casts_shadows(RID p_material) { - Material *material = material_owner.get_or_null(p_material); - ERR_FAIL_COND_V(!material, false); - if (material->dirty_list.in_list()) { - _update_material(material); - } - - bool casts_shadows = material->can_cast_shadow_cache; - - if (!casts_shadows && material->next_pass.is_valid()) { - casts_shadows = material_casts_shadows(material->next_pass); - } - - return casts_shadows; -} - -bool RasterizerStorageGLES3::material_uses_tangents(RID p_material) { - Material *material = material_owner.get_or_null(p_material); - ERR_FAIL_COND_V(!material, false); - - if (!material->shader) { - return false; - } - - if (material->shader->dirty_list.in_list()) { - _update_shader(material->shader); - } - - return material->shader->spatial.uses_tangent; -} - -bool RasterizerStorageGLES3::material_uses_ensure_correct_normals(RID p_material) { - Material *material = material_owner.get_or_null(p_material); - ERR_FAIL_COND_V(!material, false); - - if (!material->shader) { - return false; - } - - if (material->shader->dirty_list.in_list()) { - _update_shader(material->shader); - } - - return material->shader->spatial.uses_ensure_correct_normals; -} - -void RasterizerStorageGLES3::material_add_instance_owner(RID p_material, DependencyTracker *p_instance) { - /* - Material *material = material_owner.get_or_null(p_material); - ERR_FAIL_COND(!material); - - Map<InstanceBaseDependency *, int>::Element *E = material->instance_owners.find(p_instance); - if (E) { - E->get()++; - } else { - material->instance_owners[p_instance] = 1; - } -*/ -} - -void RasterizerStorageGLES3::material_remove_instance_owner(RID p_material, DependencyTracker *p_instance) { - /* - Material *material = material_owner.get_or_null(p_material); - ERR_FAIL_COND(!material); - - Map<InstanceBaseDependency *, int>::Element *E = material->instance_owners.find(p_instance); - ERR_FAIL_COND(!E); - - E->get()--; - - if (E->get() == 0) { - material->instance_owners.erase(E); - } -*/ -} - -void RasterizerStorageGLES3::material_set_render_priority(RID p_material, int priority) { - ERR_FAIL_COND(priority < RS::MATERIAL_RENDER_PRIORITY_MIN); - ERR_FAIL_COND(priority > RS::MATERIAL_RENDER_PRIORITY_MAX); - - Material *material = material_owner.get_or_null(p_material); - ERR_FAIL_COND(!material); - - material->render_priority = priority; -} - -void RasterizerStorageGLES3::_update_material(Material *p_material) { - if (p_material->dirty_list.in_list()) { - _material_dirty_list.remove(&p_material->dirty_list); - } - - if (p_material->shader && p_material->shader->dirty_list.in_list()) { - _update_shader(p_material->shader); - } - - if (p_material->shader && !p_material->shader->valid) { - return; - } - - { - bool can_cast_shadow = false; - bool is_animated = false; - - if (p_material->shader && p_material->shader->mode == RS::SHADER_SPATIAL) { - if (p_material->shader->spatial.blend_mode == Shader::Spatial::BLEND_MODE_MIX && - (!p_material->shader->spatial.uses_alpha || p_material->shader->spatial.depth_draw_mode == Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS)) { - can_cast_shadow = true; - } - - if (p_material->shader->spatial.uses_discard && p_material->shader->uses_fragment_time) { - is_animated = true; - } - - if (p_material->shader->spatial.uses_vertex && p_material->shader->uses_vertex_time) { - is_animated = true; - } - - if (can_cast_shadow != p_material->can_cast_shadow_cache || is_animated != p_material->is_animated_cache) { - p_material->can_cast_shadow_cache = can_cast_shadow; - p_material->is_animated_cache = is_animated; - - /* - for (Map<Geometry *, int>::Element *E = p_material->geometry_owners.front(); E; E = E->next()) { - E->key()->material_changed_notify(); - } - - for (Map<InstanceBaseDependency *, int>::Element *E = p_material->instance_owners.front(); E; E = E->next()) { - E->key()->base_changed(false, true); - } - */ - } - } - } - - // uniforms and other things will be set in the use_material method in ShaderGLES3 - - if (p_material->shader && p_material->shader->texture_uniforms.size() > 0) { - p_material->textures.resize(p_material->shader->texture_uniforms.size()); - - for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = p_material->shader->uniforms.front(); E; E = E->next()) { - if (E->get().texture_order < 0) { - continue; // not a texture, does not go here - } - - RID texture; - - Map<StringName, Variant>::Element *V = p_material->params.find(E->key()); - - if (V) { - texture = V->get(); - } - - if (!texture.is_valid()) { - Map<StringName, Map<int, RID>>::Element *W = p_material->shader->default_textures.find(E->key()); - - // TODO: make texture uniform array properly works with GLES3 - if (W && W->get().has(0)) { - texture = W->get()[0]; - } - } - - p_material->textures.write[E->get().texture_order] = Pair<StringName, RID>(E->key(), texture); - } - } else { - p_material->textures.clear(); - } -} -/* -void RasterizerStorageGLES3::_material_add_geometry(RID p_material, Geometry *p_geometry) { - Material *material = material_owner.get_or_null(p_material); - ERR_FAIL_COND(!material); - - Map<Geometry *, int>::Element *I = material->geometry_owners.find(p_geometry); - - if (I) { - I->get()++; - } else { - material->geometry_owners[p_geometry] = 1; - } -} - -void RasterizerStorageGLES3::_material_remove_geometry(RID p_material, Geometry *p_geometry) { - Material *material = material_owner.get_or_null(p_material); - ERR_FAIL_COND(!material); - - Map<Geometry *, int>::Element *I = material->geometry_owners.find(p_geometry); - ERR_FAIL_COND(!I); - - I->get()--; - - if (I->get() == 0) { - material->geometry_owners.erase(I); - } -} -*/ -void RasterizerStorageGLES3::update_dirty_materials() { - while (_material_dirty_list.first()) { - Material *material = _material_dirty_list.first()->self(); - _update_material(material); - } -} - -/* MESH API */ - -RID RasterizerStorageGLES3::mesh_allocate() { - return RID(); -} - -void RasterizerStorageGLES3::mesh_initialize(RID p_rid) { -} - -void RasterizerStorageGLES3::mesh_set_blend_shape_count(RID p_mesh, int p_blend_shape_count) { -} - -bool RasterizerStorageGLES3::mesh_needs_instance(RID p_mesh, bool p_has_skeleton) { - return false; -} - -RID RasterizerStorageGLES3::mesh_instance_create(RID p_base) { - return RID(); -} - -void RasterizerStorageGLES3::mesh_instance_set_skeleton(RID p_mesh_instance, RID p_skeleton) { -} - -void RasterizerStorageGLES3::mesh_instance_set_blend_shape_weight(RID p_mesh_instance, int p_shape, float p_weight) { -} - -void RasterizerStorageGLES3::mesh_instance_check_for_update(RID p_mesh_instance) { -} - -void RasterizerStorageGLES3::update_mesh_instances() { -} - -void RasterizerStorageGLES3::reflection_probe_set_mesh_lod_threshold(RID p_probe, float p_ratio) { -} - -float RasterizerStorageGLES3::reflection_probe_get_mesh_lod_threshold(RID p_probe) const { - return 0.0; -} - -void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) { -} - -int RasterizerStorageGLES3::mesh_get_blend_shape_count(RID p_mesh) const { - return 0; -} - -void RasterizerStorageGLES3::mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMode p_mode) { -} - -RS::BlendShapeMode RasterizerStorageGLES3::mesh_get_blend_shape_mode(RID p_mesh) const { - return RS::BLEND_SHAPE_MODE_NORMALIZED; -} - -void RasterizerStorageGLES3::mesh_surface_update_vertex_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) { -} - -void RasterizerStorageGLES3::mesh_surface_update_attribute_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) { -} - -void RasterizerStorageGLES3::mesh_surface_update_skin_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) { -} - -void RasterizerStorageGLES3::mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) { -} - -RID RasterizerStorageGLES3::mesh_surface_get_material(RID p_mesh, int p_surface) const { - return RID(); -} - -RS::SurfaceData RasterizerStorageGLES3::mesh_get_surface(RID p_mesh, int p_surface) const { - return RS::SurfaceData(); -} - -int RasterizerStorageGLES3::mesh_get_surface_count(RID p_mesh) const { - return 1; -} - -void RasterizerStorageGLES3::mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) { -} - -AABB RasterizerStorageGLES3::mesh_get_custom_aabb(RID p_mesh) const { - return AABB(); -} - -AABB RasterizerStorageGLES3::mesh_get_aabb(RID p_mesh, RID p_skeleton) { - return AABB(); -} - -void RasterizerStorageGLES3::mesh_set_shadow_mesh(RID p_mesh, RID p_shadow_mesh) { -} - -void RasterizerStorageGLES3::mesh_clear(RID p_mesh) { -} - -/* MULTIMESH API */ - -RID RasterizerStorageGLES3::multimesh_allocate() { - return RID(); -} - -void RasterizerStorageGLES3::multimesh_initialize(RID p_rid) { -} - -void RasterizerStorageGLES3::multimesh_allocate_data(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors, bool p_use_custom_data) { -} - -int RasterizerStorageGLES3::multimesh_get_instance_count(RID p_multimesh) const { - return 0; -} - -void RasterizerStorageGLES3::multimesh_set_mesh(RID p_multimesh, RID p_mesh) { -} - -void RasterizerStorageGLES3::multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform3D &p_transform) { -} - -void RasterizerStorageGLES3::multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform) { -} - -void RasterizerStorageGLES3::multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) { -} - -void RasterizerStorageGLES3::multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_color) { -} - -RID RasterizerStorageGLES3::multimesh_get_mesh(RID p_multimesh) const { - return RID(); -} - -AABB RasterizerStorageGLES3::multimesh_get_aabb(RID p_multimesh) const { - return AABB(); -} - -Transform3D RasterizerStorageGLES3::multimesh_instance_get_transform(RID p_multimesh, int p_index) const { - return Transform3D(); -} - -Transform2D RasterizerStorageGLES3::multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const { - return Transform2D(); -} - -Color RasterizerStorageGLES3::multimesh_instance_get_color(RID p_multimesh, int p_index) const { - return Color(); -} - -Color RasterizerStorageGLES3::multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const { - return Color(); -} - -void RasterizerStorageGLES3::multimesh_set_buffer(RID p_multimesh, const Vector<float> &p_buffer) { -} - -Vector<float> RasterizerStorageGLES3::multimesh_get_buffer(RID p_multimesh) const { - return Vector<float>(); -} - -void RasterizerStorageGLES3::multimesh_set_visible_instances(RID p_multimesh, int p_visible) { -} - -int RasterizerStorageGLES3::multimesh_get_visible_instances(RID p_multimesh) const { - return 0; -} - -/* SKELETON API */ - -RID RasterizerStorageGLES3::skeleton_allocate() { - return RID(); -} - -void RasterizerStorageGLES3::skeleton_initialize(RID p_rid) { -} - -void RasterizerStorageGLES3::skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_skeleton) { -} - -void RasterizerStorageGLES3::skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) { -} - -int RasterizerStorageGLES3::skeleton_get_bone_count(RID p_skeleton) const { - return 0; -} - -void RasterizerStorageGLES3::skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform3D &p_transform) { -} - -Transform3D RasterizerStorageGLES3::skeleton_bone_get_transform(RID p_skeleton, int p_bone) const { - return Transform3D(); -} - -void RasterizerStorageGLES3::skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) { -} - -Transform2D RasterizerStorageGLES3::skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const { - return Transform2D(); -} - -/* Light API */ - -RID RasterizerStorageGLES3::directional_light_allocate() { - return RID(); -} - -void RasterizerStorageGLES3::directional_light_initialize(RID p_rid) { -} - -RID RasterizerStorageGLES3::omni_light_allocate() { - return RID(); -} - -void RasterizerStorageGLES3::omni_light_initialize(RID p_rid) { -} - -RID RasterizerStorageGLES3::spot_light_allocate() { - return RID(); -} - -void RasterizerStorageGLES3::spot_light_initialize(RID p_rid) { -} - -RID RasterizerStorageGLES3::reflection_probe_allocate() { - return RID(); -} - -void RasterizerStorageGLES3::reflection_probe_initialize(RID p_rid) { -} - -void RasterizerStorageGLES3::light_set_color(RID p_light, const Color &p_color) { -} - -void RasterizerStorageGLES3::light_set_param(RID p_light, RS::LightParam p_param, float p_value) { -} - -void RasterizerStorageGLES3::light_set_shadow(RID p_light, bool p_enabled) { -} - -void RasterizerStorageGLES3::light_set_projector(RID p_light, RID p_texture) { -} - -void RasterizerStorageGLES3::light_set_negative(RID p_light, bool p_enable) { -} - -void RasterizerStorageGLES3::light_set_cull_mask(RID p_light, uint32_t p_mask) { -} - -void RasterizerStorageGLES3::light_set_distance_fade(RID p_light, bool p_enabled, float p_begin, float p_shadow, float p_length) { -} - -void RasterizerStorageGLES3::light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) { -} - -void RasterizerStorageGLES3::light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode) { -} - -void RasterizerStorageGLES3::light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) { -} - -void RasterizerStorageGLES3::light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) { -} - -void RasterizerStorageGLES3::light_directional_set_shadow_mode(RID p_light, RS::LightDirectionalShadowMode p_mode) { -} - -void RasterizerStorageGLES3::light_directional_set_blend_splits(RID p_light, bool p_enable) { -} - -bool RasterizerStorageGLES3::light_directional_get_blend_splits(RID p_light) const { - return false; -} - -void RasterizerStorageGLES3::light_directional_set_sky_mode(RID p_light, RS::LightDirectionalSkyMode p_mode) { -} - -RS::LightDirectionalSkyMode RasterizerStorageGLES3::light_directional_get_sky_mode(RID p_light) const { - return RS::LIGHT_DIRECTIONAL_SKY_MODE_LIGHT_AND_SKY; -} - -RS::LightDirectionalShadowMode RasterizerStorageGLES3::light_directional_get_shadow_mode(RID p_light) { - return RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL; -} - -RS::LightOmniShadowMode RasterizerStorageGLES3::light_omni_get_shadow_mode(RID p_light) { - return RS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID; -} - -bool RasterizerStorageGLES3::light_has_shadow(RID p_light) const { - return false; -} - -bool RasterizerStorageGLES3::light_has_projector(RID p_light) const { - return false; -} - -RS::LightType RasterizerStorageGLES3::light_get_type(RID p_light) const { - return RS::LIGHT_OMNI; -} - -AABB RasterizerStorageGLES3::light_get_aabb(RID p_light) const { - return AABB(); -} - -float RasterizerStorageGLES3::light_get_param(RID p_light, RS::LightParam p_param) { - return 0.0; -} - -Color RasterizerStorageGLES3::light_get_color(RID p_light) { - return Color(); -} - -RS::LightBakeMode RasterizerStorageGLES3::light_get_bake_mode(RID p_light) { - return RS::LIGHT_BAKE_DISABLED; -} - -uint32_t RasterizerStorageGLES3::light_get_max_sdfgi_cascade(RID p_light) { - return 0; -} - -uint64_t RasterizerStorageGLES3::light_get_version(RID p_light) const { - return 0; -} - -/* PROBE API */ - -void RasterizerStorageGLES3::reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) { -} - -void RasterizerStorageGLES3::reflection_probe_set_intensity(RID p_probe, float p_intensity) { -} - -void RasterizerStorageGLES3::reflection_probe_set_ambient_mode(RID p_probe, RS::ReflectionProbeAmbientMode p_mode) { -} - -void RasterizerStorageGLES3::reflection_probe_set_ambient_color(RID p_probe, const Color &p_color) { -} - -void RasterizerStorageGLES3::reflection_probe_set_ambient_energy(RID p_probe, float p_energy) { -} - -void RasterizerStorageGLES3::reflection_probe_set_max_distance(RID p_probe, float p_distance) { -} - -void RasterizerStorageGLES3::reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) { -} - -void RasterizerStorageGLES3::reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) { -} - -void RasterizerStorageGLES3::reflection_probe_set_as_interior(RID p_probe, bool p_enable) { -} - -void RasterizerStorageGLES3::reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) { -} - -void RasterizerStorageGLES3::reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) { -} - -void RasterizerStorageGLES3::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) { -} - -void RasterizerStorageGLES3::reflection_probe_set_resolution(RID p_probe, int p_resolution) { -} - -AABB RasterizerStorageGLES3::reflection_probe_get_aabb(RID p_probe) const { - return AABB(); -} - -RS::ReflectionProbeUpdateMode RasterizerStorageGLES3::reflection_probe_get_update_mode(RID p_probe) const { - return RenderingServer::REFLECTION_PROBE_UPDATE_ONCE; -} - -uint32_t RasterizerStorageGLES3::reflection_probe_get_cull_mask(RID p_probe) const { - return 0; -} - -Vector3 RasterizerStorageGLES3::reflection_probe_get_extents(RID p_probe) const { - return Vector3(); -} - -Vector3 RasterizerStorageGLES3::reflection_probe_get_origin_offset(RID p_probe) const { - return Vector3(); -} - -float RasterizerStorageGLES3::reflection_probe_get_origin_max_distance(RID p_probe) const { - return 0.0; -} - -bool RasterizerStorageGLES3::reflection_probe_renders_shadows(RID p_probe) const { - return false; -} - void RasterizerStorageGLES3::base_update_dependency(RID p_base, DependencyTracker *p_instance) { } -void RasterizerStorageGLES3::skeleton_update_dependency(RID p_base, DependencyTracker *p_instance) { -} - /* VOXEL GI API */ RID RasterizerStorageGLES3::voxel_gi_allocate() { @@ -1302,253 +159,12 @@ uint32_t RasterizerStorageGLES3::voxel_gi_get_version(RID p_voxel_gi) { return 0; } -/* LIGHTMAP CAPTURE */ -RID RasterizerStorageGLES3::lightmap_allocate() { - return RID(); -} - -void RasterizerStorageGLES3::lightmap_initialize(RID p_rid) { -} - -void RasterizerStorageGLES3::lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) { -} - -void RasterizerStorageGLES3::lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) { -} - -void RasterizerStorageGLES3::lightmap_set_probe_interior(RID p_lightmap, bool p_interior) { -} - -void RasterizerStorageGLES3::lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) { -} - -PackedVector3Array RasterizerStorageGLES3::lightmap_get_probe_capture_points(RID p_lightmap) const { - return PackedVector3Array(); -} - -PackedColorArray RasterizerStorageGLES3::lightmap_get_probe_capture_sh(RID p_lightmap) const { - return PackedColorArray(); -} - -PackedInt32Array RasterizerStorageGLES3::lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const { - return PackedInt32Array(); -} - -PackedInt32Array RasterizerStorageGLES3::lightmap_get_probe_capture_bsp_tree(RID p_lightmap) const { - return PackedInt32Array(); -} - -AABB RasterizerStorageGLES3::lightmap_get_aabb(RID p_lightmap) const { - return AABB(); -} - -void RasterizerStorageGLES3::lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point, Color *r_sh) { -} - -bool RasterizerStorageGLES3::lightmap_is_interior(RID p_lightmap) const { - return false; -} - -void RasterizerStorageGLES3::lightmap_set_probe_capture_update_speed(float p_speed) { -} - -float RasterizerStorageGLES3::lightmap_get_probe_capture_update_speed() const { - return 0; -} - /* OCCLUDER */ void RasterizerStorageGLES3::occluder_set_mesh(RID p_occluder, const PackedVector3Array &p_vertices, const PackedInt32Array &p_indices) { } -/* PARTICLES */ - -RID RasterizerStorageGLES3::particles_allocate() { - return RID(); -} - -void RasterizerStorageGLES3::particles_initialize(RID p_rid) { -} - -void RasterizerStorageGLES3::particles_set_mode(RID p_particles, RS::ParticlesMode p_mode) { -} - -void RasterizerStorageGLES3::particles_emit(RID p_particles, const Transform3D &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) { -} - -void RasterizerStorageGLES3::particles_set_emitting(RID p_particles, bool p_emitting) { -} - -void RasterizerStorageGLES3::particles_set_amount(RID p_particles, int p_amount) { -} - -void RasterizerStorageGLES3::particles_set_lifetime(RID p_particles, double p_lifetime) { -} - -void RasterizerStorageGLES3::particles_set_one_shot(RID p_particles, bool p_one_shot) { -} - -void RasterizerStorageGLES3::particles_set_pre_process_time(RID p_particles, double p_time) { -} - -void RasterizerStorageGLES3::particles_set_explosiveness_ratio(RID p_particles, real_t p_ratio) { -} - -void RasterizerStorageGLES3::particles_set_randomness_ratio(RID p_particles, real_t p_ratio) { -} - -void RasterizerStorageGLES3::particles_set_custom_aabb(RID p_particles, const AABB &p_aabb) { -} - -void RasterizerStorageGLES3::particles_set_speed_scale(RID p_particles, double p_scale) { -} - -void RasterizerStorageGLES3::particles_set_use_local_coordinates(RID p_particles, bool p_enable) { -} - -void RasterizerStorageGLES3::particles_set_process_material(RID p_particles, RID p_material) { -} -RID RasterizerStorageGLES3::particles_get_process_material(RID p_particles) const { - return RID(); -} - -void RasterizerStorageGLES3::particles_set_fixed_fps(RID p_particles, int p_fps) { -} - -void RasterizerStorageGLES3::particles_set_interpolate(RID p_particles, bool p_enable) { -} - -void RasterizerStorageGLES3::particles_set_fractional_delta(RID p_particles, bool p_enable) { -} - -void RasterizerStorageGLES3::particles_set_subemitter(RID p_particles, RID p_subemitter_particles) { -} - -void RasterizerStorageGLES3::particles_set_view_axis(RID p_particles, const Vector3 &p_axis, const Vector3 &p_up_axis) { -} - -void RasterizerStorageGLES3::particles_set_collision_base_size(RID p_particles, real_t p_size) { -} - -void RasterizerStorageGLES3::particles_set_transform_align(RID p_particles, RS::ParticlesTransformAlign p_transform_align) { -} - -void RasterizerStorageGLES3::particles_set_trails(RID p_particles, bool p_enable, double p_length) { -} - -void RasterizerStorageGLES3::particles_set_trail_bind_poses(RID p_particles, const Vector<Transform3D> &p_bind_poses) { -} - -void RasterizerStorageGLES3::particles_restart(RID p_particles) { -} - -void RasterizerStorageGLES3::particles_set_draw_order(RID p_particles, RS::ParticlesDrawOrder p_order) { -} - -void RasterizerStorageGLES3::particles_set_draw_passes(RID p_particles, int p_count) { -} - -void RasterizerStorageGLES3::particles_set_draw_pass_mesh(RID p_particles, int p_pass, RID p_mesh) { -} - -void RasterizerStorageGLES3::particles_request_process(RID p_particles) { -} - -AABB RasterizerStorageGLES3::particles_get_current_aabb(RID p_particles) { - return AABB(); -} - -AABB RasterizerStorageGLES3::particles_get_aabb(RID p_particles) const { - return AABB(); -} - -void RasterizerStorageGLES3::particles_set_emission_transform(RID p_particles, const Transform3D &p_transform) { -} - -bool RasterizerStorageGLES3::particles_get_emitting(RID p_particles) { - return false; -} - -int RasterizerStorageGLES3::particles_get_draw_passes(RID p_particles) const { - return 0; -} - -RID RasterizerStorageGLES3::particles_get_draw_pass_mesh(RID p_particles, int p_pass) const { - return RID(); -} - -void RasterizerStorageGLES3::particles_add_collision(RID p_particles, RID p_instance) { -} - -void RasterizerStorageGLES3::particles_remove_collision(RID p_particles, RID p_instance) { -} - -void RasterizerStorageGLES3::particles_set_canvas_sdf_collision(RID p_particles, bool p_enable, const Transform2D &p_xform, const Rect2 &p_to_screen, RID p_texture) { -} - -void RasterizerStorageGLES3::update_particles() { -} - -/* PARTICLES COLLISION */ - -RID RasterizerStorageGLES3::particles_collision_allocate() { - return RID(); -} - -void RasterizerStorageGLES3::particles_collision_initialize(RID p_rid) { -} - -void RasterizerStorageGLES3::particles_collision_set_collision_type(RID p_particles_collision, RS::ParticlesCollisionType p_type) { -} - -void RasterizerStorageGLES3::particles_collision_set_cull_mask(RID p_particles_collision, uint32_t p_cull_mask) { -} - -void RasterizerStorageGLES3::particles_collision_set_sphere_radius(RID p_particles_collision, real_t p_radius) { -} - -void RasterizerStorageGLES3::particles_collision_set_box_extents(RID p_particles_collision, const Vector3 &p_extents) { -} - -void RasterizerStorageGLES3::particles_collision_set_attractor_strength(RID p_particles_collision, real_t p_strength) { -} - -void RasterizerStorageGLES3::particles_collision_set_attractor_directionality(RID p_particles_collision, real_t p_directionality) { -} - -void RasterizerStorageGLES3::particles_collision_set_attractor_attenuation(RID p_particles_collision, real_t p_curve) { -} - -void RasterizerStorageGLES3::particles_collision_set_field_texture(RID p_particles_collision, RID p_texture) { -} - -void RasterizerStorageGLES3::particles_collision_height_field_update(RID p_particles_collision) { -} - -void RasterizerStorageGLES3::particles_collision_set_height_field_resolution(RID p_particles_collision, RS::ParticlesCollisionHeightfieldResolution p_resolution) { -} - -AABB RasterizerStorageGLES3::particles_collision_get_aabb(RID p_particles_collision) const { - return AABB(); -} - -bool RasterizerStorageGLES3::particles_collision_is_heightfield(RID p_particles_collision) const { - return false; -} - -RID RasterizerStorageGLES3::particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const { - return RID(); -} - -RID RasterizerStorageGLES3::particles_collision_instance_create(RID p_collision) { - return RID(); -} - -void RasterizerStorageGLES3::particles_collision_instance_set_transform(RID p_collision_instance, const Transform3D &p_transform) { -} - -void RasterizerStorageGLES3::particles_collision_instance_set_active(RID p_collision_instance, bool p_active) { -} +/* FOG */ RID RasterizerStorageGLES3::fog_volume_allocate() { return RID(); @@ -1595,804 +211,6 @@ AABB RasterizerStorageGLES3::visibility_notifier_get_aabb(RID p_notifier) const void RasterizerStorageGLES3::visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred) { } -/* GLOBAL VARIABLES */ - -void RasterizerStorageGLES3::global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) { -} - -void RasterizerStorageGLES3::global_variable_remove(const StringName &p_name) { -} - -Vector<StringName> RasterizerStorageGLES3::global_variable_get_list() const { - return Vector<StringName>(); -} - -void RasterizerStorageGLES3::global_variable_set(const StringName &p_name, const Variant &p_value) { -} - -void RasterizerStorageGLES3::global_variable_set_override(const StringName &p_name, const Variant &p_value) { -} - -Variant RasterizerStorageGLES3::global_variable_get(const StringName &p_name) const { - return Variant(); -} - -RS::GlobalVariableType RasterizerStorageGLES3::global_variable_get_type(const StringName &p_name) const { - return RS::GLOBAL_VAR_TYPE_MAX; -} - -void RasterizerStorageGLES3::global_variables_load_settings(bool p_load_textures) { -} - -void RasterizerStorageGLES3::global_variables_clear() { -} - -int32_t RasterizerStorageGLES3::global_variables_instance_allocate(RID p_instance) { - return 0; -} - -void RasterizerStorageGLES3::global_variables_instance_free(RID p_instance) { -} - -void RasterizerStorageGLES3::global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) { -} - -bool RasterizerStorageGLES3::particles_is_inactive(RID p_particles) const { - return false; -} - -/* RENDER TARGET */ - -void RasterizerStorageGLES3::_set_current_render_target(RID p_render_target) { - GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target); - - if (rt) { - if (rt->allocate_is_dirty) { - rt->allocate_is_dirty = false; - _render_target_allocate(rt); - } - - frame.current_rt = rt; - ERR_FAIL_COND(!rt); - frame.clear_request = false; - - glViewport(0, 0, rt->width, rt->height); - - _dims.rt_width = rt->width; - _dims.rt_height = rt->height; - _dims.win_width = rt->width; - _dims.win_height = rt->height; - - } else { - frame.current_rt = nullptr; - frame.clear_request = false; - bind_framebuffer_system(); - } -} - -void RasterizerStorageGLES3::_render_target_allocate(GLES3::RenderTarget *rt) { - // do not allocate a render target with no size - if (rt->width <= 0 || rt->height <= 0) { - return; - } - - // do not allocate a render target that is attached to the screen - if (rt->flags[RENDER_TARGET_DIRECT_TO_SCREEN]) { - rt->fbo = RasterizerStorageGLES3::system_fbo; - return; - } - - GLuint color_internal_format; - GLuint color_format; - GLuint color_type = GL_UNSIGNED_BYTE; - Image::Format image_format; - - if (rt->flags[RendererStorage::RENDER_TARGET_TRANSPARENT]) { -#ifdef GLES_OVER_GL - color_internal_format = GL_RGBA8; -#else - color_internal_format = GL_RGBA; -#endif - color_format = GL_RGBA; - image_format = Image::FORMAT_RGBA8; - } else { -#ifdef GLES_OVER_GL - color_internal_format = GL_RGB8; -#else - color_internal_format = GL_RGB; -#endif - color_format = GL_RGB; - image_format = Image::FORMAT_RGB8; - } - - rt->used_dof_blur_near = false; - rt->mip_maps_allocated = false; - - { - /* Front FBO */ - - GLES3::Texture *texture = GLES3::TextureStorage::get_singleton()->get_texture(rt->texture); - ERR_FAIL_COND(!texture); - - // framebuffer - glGenFramebuffers(1, &rt->fbo); - bind_framebuffer(rt->fbo); - - // color - glGenTextures(1, &rt->color); - glBindTexture(GL_TEXTURE_2D, rt->color); - - glTexImage2D(GL_TEXTURE_2D, 0, color_internal_format, rt->width, rt->height, 0, color_format, color_type, nullptr); - - if (texture->flags & GLES3::TEXTURE_FLAG_FILTER) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - } else { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - } - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->color, 0); - - // depth - - if (config->support_depth_texture) { - glGenTextures(1, &rt->depth); - glBindTexture(GL_TEXTURE_2D, rt->depth); - glTexImage2D(GL_TEXTURE_2D, 0, config->depth_internalformat, rt->width, rt->height, 0, GL_DEPTH_COMPONENT, config->depth_type, nullptr); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->depth, 0); - } else { - glGenRenderbuffers(1, &rt->depth); - glBindRenderbuffer(GL_RENDERBUFFER, rt->depth); - - glRenderbufferStorage(GL_RENDERBUFFER, config->depth_buffer_internalformat, rt->width, rt->height); - - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth); - } - - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - - if (status != GL_FRAMEBUFFER_COMPLETE) { - glDeleteFramebuffers(1, &rt->fbo); - if (config->support_depth_texture) { - glDeleteTextures(1, &rt->depth); - } else { - glDeleteRenderbuffers(1, &rt->depth); - } - - glDeleteTextures(1, &rt->color); - rt->fbo = 0; - rt->width = 0; - rt->height = 0; - rt->color = 0; - rt->depth = 0; - texture->tex_id = 0; - texture->active = false; - WARN_PRINT("Could not create framebuffer!!"); - return; - } - - texture->format = image_format; - texture->gl_format_cache = color_format; - texture->gl_type_cache = GL_UNSIGNED_BYTE; - texture->gl_internal_format_cache = color_internal_format; - texture->tex_id = rt->color; - texture->width = rt->width; - texture->alloc_width = rt->width; - texture->height = rt->height; - texture->alloc_height = rt->height; - texture->active = true; - - GLES3::TextureStorage::get_singleton()->texture_set_flags(rt->texture, texture->flags); - } - - /* BACK FBO */ - /* For MSAA */ - -#ifndef JAVASCRIPT_ENABLED - if (rt->msaa >= RS::VIEWPORT_MSAA_2X && rt->msaa <= RS::VIEWPORT_MSAA_8X) { - rt->multisample_active = true; - - static const int msaa_value[] = { 0, 2, 4, 8, 16 }; - int msaa = msaa_value[rt->msaa]; - - int max_samples = 0; - glGetIntegerv(GL_MAX_SAMPLES, &max_samples); - if (msaa > max_samples) { - WARN_PRINT("MSAA must be <= GL_MAX_SAMPLES, falling-back to GL_MAX_SAMPLES = " + itos(max_samples)); - msaa = max_samples; - } - - //regular fbo - glGenFramebuffers(1, &rt->multisample_fbo); - bind_framebuffer(rt->multisample_fbo); - - glGenRenderbuffers(1, &rt->multisample_depth); - glBindRenderbuffer(GL_RENDERBUFFER, rt->multisample_depth); - glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, config->depth_buffer_internalformat, rt->width, rt->height); - - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->multisample_depth); - - glGenRenderbuffers(1, &rt->multisample_color); - glBindRenderbuffer(GL_RENDERBUFFER, rt->multisample_color); - glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, color_internal_format, rt->width, rt->height); - - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rt->multisample_color); - - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - - if (status != GL_FRAMEBUFFER_COMPLETE) { - // Delete allocated resources and default to no MSAA - WARN_PRINT_ONCE("Cannot allocate back framebuffer for MSAA"); - printf("err status: %x\n", status); - rt->multisample_active = false; - - glDeleteFramebuffers(1, &rt->multisample_fbo); - rt->multisample_fbo = 0; - - glDeleteRenderbuffers(1, &rt->multisample_depth); - rt->multisample_depth = 0; - - glDeleteRenderbuffers(1, &rt->multisample_color); - rt->multisample_color = 0; - } - - glBindRenderbuffer(GL_RENDERBUFFER, 0); - bind_framebuffer(0); - - } else -#endif // JAVASCRIPT_ENABLED - { - rt->multisample_active = false; - } - - glClearColor(0, 0, 0, 0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - // copy texscreen buffers - // if (!(rt->flags[RendererStorage::RENDER_TARGET_NO_SAMPLING])) { - if (true) { - glGenTextures(1, &rt->copy_screen_effect.color); - glBindTexture(GL_TEXTURE_2D, rt->copy_screen_effect.color); - - if (rt->flags[RendererStorage::RENDER_TARGET_TRANSPARENT]) { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rt->width, rt->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); - } else { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, rt->width, rt->height, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr); - } - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - glGenFramebuffers(1, &rt->copy_screen_effect.fbo); - bind_framebuffer(rt->copy_screen_effect.fbo); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->copy_screen_effect.color, 0); - - glClearColor(0, 0, 0, 0); - glClear(GL_COLOR_BUFFER_BIT); - - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - if (status != GL_FRAMEBUFFER_COMPLETE) { - _render_target_clear(rt); - ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE); - } - } - - // Allocate mipmap chains for post_process effects - // if (!rt->flags[RendererStorage::RENDER_TARGET_NO_3D] && rt->width >= 2 && rt->height >= 2) { - if (rt->width >= 2 && rt->height >= 2) { - for (int i = 0; i < 2; i++) { - ERR_FAIL_COND(rt->mip_maps[i].sizes.size()); - int w = rt->width; - int h = rt->height; - - if (i > 0) { - w >>= 1; - h >>= 1; - } - - int level = 0; - int fb_w = w; - int fb_h = h; - - while (true) { - GLES3::RenderTarget::MipMaps::Size mm; - mm.width = w; - mm.height = h; - rt->mip_maps[i].sizes.push_back(mm); - - w >>= 1; - h >>= 1; - - if (w < 2 || h < 2) { - break; - } - - level++; - } - - GLsizei width = fb_w; - GLsizei height = fb_h; - - if (config->render_to_mipmap_supported) { - glGenTextures(1, &rt->mip_maps[i].color); - glBindTexture(GL_TEXTURE_2D, rt->mip_maps[i].color); - - for (int l = 0; l < level + 1; l++) { - glTexImage2D(GL_TEXTURE_2D, l, color_internal_format, width, height, 0, color_format, color_type, nullptr); - width = MAX(1, (width / 2)); - height = MAX(1, (height / 2)); - } -#ifdef GLES_OVER_GL - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level); -#endif - } else { - // Can't render to specific levels of a mipmap in ES 2.0 or Webgl so create a texture for each level - for (int l = 0; l < level + 1; l++) { - glGenTextures(1, &rt->mip_maps[i].sizes.write[l].color); - glBindTexture(GL_TEXTURE_2D, rt->mip_maps[i].sizes[l].color); - glTexImage2D(GL_TEXTURE_2D, 0, color_internal_format, width, height, 0, color_format, color_type, nullptr); - width = MAX(1, (width / 2)); - height = MAX(1, (height / 2)); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - } - } - - glDisable(GL_SCISSOR_TEST); - glColorMask(1, 1, 1, 1); - glDepthMask(GL_TRUE); - - for (int j = 0; j < rt->mip_maps[i].sizes.size(); j++) { - GLES3::RenderTarget::MipMaps::Size &mm = rt->mip_maps[i].sizes.write[j]; - - glGenFramebuffers(1, &mm.fbo); - bind_framebuffer(mm.fbo); - - if (config->render_to_mipmap_supported) { - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->mip_maps[i].color, j); - } else { - glBindTexture(GL_TEXTURE_2D, rt->mip_maps[i].sizes[j].color); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->mip_maps[i].sizes[j].color, 0); - } - - bool used_depth = false; - if (j == 0 && i == 0) { //use always - if (config->support_depth_texture) { - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->depth, 0); - } else { - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth); - } - used_depth = true; - } - - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - if (status != GL_FRAMEBUFFER_COMPLETE) { - WARN_PRINT_ONCE("Cannot allocate mipmaps for 3D post processing effects"); - bind_framebuffer_system(); - return; - } - - glClearColor(1.0, 0.0, 1.0, 0.0); - glClear(GL_COLOR_BUFFER_BIT); - if (used_depth) { - glClearDepth(1.0); - glClear(GL_DEPTH_BUFFER_BIT); - } - } - - rt->mip_maps[i].levels = level; - - if (config->render_to_mipmap_supported) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - } - } - rt->mip_maps_allocated = true; - } - - bind_framebuffer_system(); -} - -void RasterizerStorageGLES3::_render_target_clear(GLES3::RenderTarget *rt) { - // there is nothing to clear when DIRECT_TO_SCREEN is used - if (rt->flags[RENDER_TARGET_DIRECT_TO_SCREEN]) { - return; - } - - if (rt->fbo) { - glDeleteFramebuffers(1, &rt->fbo); - glDeleteTextures(1, &rt->color); - rt->fbo = 0; - } - - if (rt->external.fbo != 0) { - // free this - glDeleteFramebuffers(1, &rt->external.fbo); - - // clean up our texture - GLES3::Texture *t = GLES3::TextureStorage::get_singleton()->get_texture(rt->external.texture); - t->alloc_height = 0; - t->alloc_width = 0; - t->width = 0; - t->height = 0; - t->active = false; - GLES3::TextureStorage::get_singleton()->texture_free(rt->external.texture); - memdelete(t); - - rt->external.fbo = 0; - } - - if (rt->depth) { - if (config->support_depth_texture) { - glDeleteTextures(1, &rt->depth); - } else { - glDeleteRenderbuffers(1, &rt->depth); - } - - rt->depth = 0; - } - - GLES3::Texture *tex = GLES3::TextureStorage::get_singleton()->get_texture(rt->texture); - tex->alloc_height = 0; - tex->alloc_width = 0; - tex->width = 0; - tex->height = 0; - tex->active = false; - - if (rt->copy_screen_effect.color) { - glDeleteFramebuffers(1, &rt->copy_screen_effect.fbo); - rt->copy_screen_effect.fbo = 0; - - glDeleteTextures(1, &rt->copy_screen_effect.color); - rt->copy_screen_effect.color = 0; - } - - for (int i = 0; i < 2; i++) { - if (rt->mip_maps[i].sizes.size()) { - for (int j = 0; j < rt->mip_maps[i].sizes.size(); j++) { - glDeleteFramebuffers(1, &rt->mip_maps[i].sizes[j].fbo); - glDeleteTextures(1, &rt->mip_maps[i].sizes[j].color); - } - - glDeleteTextures(1, &rt->mip_maps[i].color); - rt->mip_maps[i].sizes.clear(); - rt->mip_maps[i].levels = 0; - rt->mip_maps[i].color = 0; - } - } - - if (rt->multisample_active) { - glDeleteFramebuffers(1, &rt->multisample_fbo); - rt->multisample_fbo = 0; - - glDeleteRenderbuffers(1, &rt->multisample_depth); - rt->multisample_depth = 0; - - glDeleteRenderbuffers(1, &rt->multisample_color); - - rt->multisample_color = 0; - } -} - -RID RasterizerStorageGLES3::render_target_create() { - GLES3::RenderTarget *rt = memnew(GLES3::RenderTarget); - GLES3::Texture *t = memnew(GLES3::Texture); - - t->type = RenderingDevice::TEXTURE_TYPE_2D; - t->flags = 0; - t->width = 0; - t->height = 0; - t->alloc_height = 0; - t->alloc_width = 0; - t->format = Image::FORMAT_R8; - t->target = GL_TEXTURE_2D; - t->gl_format_cache = 0; - t->gl_internal_format_cache = 0; - t->gl_type_cache = 0; - t->data_size = 0; - t->total_data_size = 0; - t->ignore_mipmaps = false; - t->compressed = false; - t->mipmaps = 1; - t->active = true; - t->tex_id = 0; - t->render_target = rt; - - rt->texture = GLES3::TextureStorage::get_singleton()->make_rid(t); - return render_target_owner.make_rid(rt); -} - -void RasterizerStorageGLES3::render_target_set_position(RID p_render_target, int p_x, int p_y) { - GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target); - ERR_FAIL_COND(!rt); - - rt->x = p_x; - rt->y = p_y; -} - -void RasterizerStorageGLES3::render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) { - GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target); - ERR_FAIL_COND(!rt); - - if (p_width == rt->width && p_height == rt->height) { - return; - } - - _render_target_clear(rt); - - rt->width = p_width; - rt->height = p_height; - - // print_line("render_target_set_size " + itos(p_render_target.get_id()) + ", w " + itos(p_width) + " h " + itos(p_height)); - - rt->allocate_is_dirty = true; - //_render_target_allocate(rt); -} - -// TODO: convert to Size2i internally -Size2i RasterizerStorageGLES3::render_target_get_size(RID p_render_target) { - GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target); - ERR_FAIL_COND_V(!rt, Size2()); - - return Size2i(rt->width, rt->height); -} - -RID RasterizerStorageGLES3::render_target_get_texture(RID p_render_target) { - GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target); - ERR_FAIL_COND_V(!rt, RID()); - - if (rt->external.fbo == 0) { - return rt->texture; - } else { - return rt->external.texture; - } -} - -void RasterizerStorageGLES3::render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) { - GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target); - ERR_FAIL_COND(!rt); - - if (p_texture_id == 0) { - if (rt->external.fbo != 0) { - // free this - glDeleteFramebuffers(1, &rt->external.fbo); - - // and this - if (rt->external.depth != 0) { - glDeleteRenderbuffers(1, &rt->external.depth); - } - - // clean up our texture - GLES3::Texture *t = GLES3::TextureStorage::get_singleton()->get_texture(rt->external.texture); - t->alloc_height = 0; - t->alloc_width = 0; - t->width = 0; - t->height = 0; - t->active = false; - GLES3::TextureStorage::get_singleton()->texture_free(rt->external.texture); - memdelete(t); - - rt->external.fbo = 0; - rt->external.color = 0; - rt->external.depth = 0; - } - } else { - GLES3::Texture *t; - - if (rt->external.fbo == 0) { - // create our fbo - glGenFramebuffers(1, &rt->external.fbo); - bind_framebuffer(rt->external.fbo); - - // allocate a texture - t = memnew(GLES3::Texture); - - t->type = RenderingDevice::TEXTURE_TYPE_2D; - t->flags = 0; - t->width = 0; - t->height = 0; - t->alloc_height = 0; - t->alloc_width = 0; - t->format = Image::FORMAT_RGBA8; - t->target = GL_TEXTURE_2D; - t->gl_format_cache = 0; - t->gl_internal_format_cache = 0; - t->gl_type_cache = 0; - t->data_size = 0; - t->compressed = false; - t->srgb = false; - t->total_data_size = 0; - t->ignore_mipmaps = false; - t->mipmaps = 1; - t->active = true; - t->tex_id = 0; - t->render_target = rt; - - rt->external.texture = GLES3::TextureStorage::get_singleton()->make_rid(t); - - } else { - // bind our frame buffer - bind_framebuffer(rt->external.fbo); - - // find our texture - t = GLES3::TextureStorage::get_singleton()->get_texture(rt->external.texture); - } - - // set our texture - t->tex_id = p_texture_id; - rt->external.color = p_texture_id; - - // size shouldn't be different - t->width = rt->width; - t->height = rt->height; - t->alloc_height = rt->width; - t->alloc_width = rt->height; - - // Switch our texture on our frame buffer - { - // set our texture as the destination for our framebuffer - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, p_texture_id, 0); - - // seeing we're rendering into this directly, better also use our depth buffer, just use our existing one :) - if (config->support_depth_texture) { - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->depth, 0); - } else { - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth); - } - } - - // check status and unbind - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - bind_framebuffer_system(); - - if (status != GL_FRAMEBUFFER_COMPLETE) { - printf("framebuffer fail, status: %x\n", status); - } - - ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE); - } -} - -void RasterizerStorageGLES3::render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) { - GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target); - ERR_FAIL_COND(!rt); - - // When setting DIRECT_TO_SCREEN, you need to clear before the value is set, but allocate after as - // those functions change how they operate depending on the value of DIRECT_TO_SCREEN - if (p_flag == RENDER_TARGET_DIRECT_TO_SCREEN && p_value != rt->flags[RENDER_TARGET_DIRECT_TO_SCREEN]) { - _render_target_clear(rt); - rt->flags[p_flag] = p_value; - _render_target_allocate(rt); - } - - rt->flags[p_flag] = p_value; - - switch (p_flag) { - case RENDER_TARGET_TRANSPARENT: - /* - case RENDER_TARGET_HDR: - case RENDER_TARGET_NO_3D: - case RENDER_TARGET_NO_SAMPLING: - case RENDER_TARGET_NO_3D_EFFECTS: */ - { - //must reset for these formats - _render_target_clear(rt); - _render_target_allocate(rt); - } - break; - default: { - } - } -} - -bool RasterizerStorageGLES3::render_target_was_used(RID p_render_target) { - GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target); - ERR_FAIL_COND_V(!rt, false); - - return rt->used_in_frame; -} - -void RasterizerStorageGLES3::render_target_clear_used(RID p_render_target) { - GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target); - ERR_FAIL_COND(!rt); - - rt->used_in_frame = false; -} - -void RasterizerStorageGLES3::render_target_set_msaa(RID p_render_target, RS::ViewportMSAA p_msaa) { - GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target); - ERR_FAIL_COND(!rt); - - if (rt->msaa == p_msaa) { - return; - } - - _render_target_clear(rt); - rt->msaa = p_msaa; - _render_target_allocate(rt); -} - -//RasterizerStorageGLES3::GLES3::RenderTarget * RasterizerStorageGLES3::render_target_get(RID p_render_target) -//{ -// return render_target_owner.get_or_null(p_render_target); -//} - -void RasterizerStorageGLES3::render_target_set_use_fxaa(RID p_render_target, bool p_fxaa) { - GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target); - ERR_FAIL_COND(!rt); - - rt->use_fxaa = p_fxaa; -} - -void RasterizerStorageGLES3::render_target_set_use_debanding(RID p_render_target, bool p_debanding) { - GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target); - ERR_FAIL_COND(!rt); - - if (p_debanding) { - WARN_PRINT_ONCE("Debanding is not supported in the OpenGL backend. Switch to the Vulkan backend and make sure HDR is enabled."); - } - - rt->use_debanding = p_debanding; -} - -void RasterizerStorageGLES3::render_target_request_clear(RID p_render_target, const Color &p_clear_color) { - GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target); - ERR_FAIL_COND(!rt); - rt->clear_requested = true; - rt->clear_color = p_clear_color; - - // ERR_FAIL_COND(!frame.current_rt); - // frame.clear_request = true; - // frame.clear_request_color = p_color; -} - -bool RasterizerStorageGLES3::render_target_is_clear_requested(RID p_render_target) { - GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target); - ERR_FAIL_COND_V(!rt, false); - return rt->clear_requested; -} -Color RasterizerStorageGLES3::render_target_get_clear_request_color(RID p_render_target) { - GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target); - ERR_FAIL_COND_V(!rt, Color()); - return rt->clear_color; -} - -void RasterizerStorageGLES3::render_target_disable_clear_request(RID p_render_target) { - GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target); - ERR_FAIL_COND(!rt); - rt->clear_requested = false; -} - -void RasterizerStorageGLES3::render_target_do_clear_request(RID p_render_target) { -} - -void RasterizerStorageGLES3::render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) { -} - -Rect2i RasterizerStorageGLES3::render_target_get_sdf_rect(RID p_render_target) const { - return Rect2i(); -} - -void RasterizerStorageGLES3::render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled) { -} - /* CANVAS SHADOW */ RID RasterizerStorageGLES3::canvas_light_shadow_buffer_create(int p_width) { @@ -2408,7 +226,7 @@ RID RasterizerStorageGLES3::canvas_light_shadow_buffer_create(int p_width) { glActiveTexture(GL_TEXTURE0); glGenFramebuffers(1, &cls->fbo); - bind_framebuffer(cls->fbo); + glBindFramebuffer(GL_FRAMEBUFFER, cls->fbo); glGenRenderbuffers(1, &cls->depth); glBindRenderbuffer(GL_RENDERBUFFER, cls->depth); @@ -2435,7 +253,7 @@ RID RasterizerStorageGLES3::canvas_light_shadow_buffer_create(int p_width) { GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); //printf("errnum: %x\n",status); - bind_framebuffer_system(); + glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo); if (status != GL_FRAMEBUFFER_COMPLETE) { memdelete(cls); @@ -2568,24 +386,14 @@ RS::InstanceType RasterizerStorageGLES3::get_base_type(RID p_rid) const { } bool RasterizerStorageGLES3::free(RID p_rid) { - if (render_target_owner.owns(p_rid)) { - GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_rid); - _render_target_clear(rt); - - GLES3::Texture *t = GLES3::TextureStorage::get_singleton()->get_texture(rt->texture); - if (t) { - GLES3::TextureStorage::get_singleton()->texture_free(rt->texture); - memdelete(t); - } - render_target_owner.free(p_rid); - memdelete(rt); - + if (GLES3::TextureStorage::get_singleton()->owns_render_target(p_rid)) { + GLES3::TextureStorage::get_singleton()->render_target_free(p_rid); return true; } else if (GLES3::TextureStorage::get_singleton()->owns_texture(p_rid)) { GLES3::TextureStorage::get_singleton()->texture_free(p_rid); return true; - } else if (GLES3::CanvasTextureStorage::get_singleton()->owns_canvas_texture(p_rid)) { - GLES3::CanvasTextureStorage::get_singleton()->canvas_texture_free(p_rid); + } else if (GLES3::TextureStorage::get_singleton()->owns_canvas_texture(p_rid)) { + GLES3::TextureStorage::get_singleton()->canvas_texture_free(p_rid); return true; } else if (sky_owner.owns(p_rid)) { Sky *sky = sky_owner.get_or_null(p_rid); @@ -2594,63 +402,12 @@ bool RasterizerStorageGLES3::free(RID p_rid) { memdelete(sky); return true; - } else if (shader_owner.owns(p_rid)) { - Shader *shader = shader_owner.get_or_null(p_rid); - - if (shader->shader && shader->version.is_valid()) { - shader->shader->version_free(shader->version); - } - - if (shader->dirty_list.in_list()) { - _shader_dirty_list.remove(&shader->dirty_list); - } - - while (shader->materials.first()) { - Material *m = shader->materials.first()->self(); - - m->shader = nullptr; - _material_make_dirty(m); - - shader->materials.remove(shader->materials.first()); - } - - shader_owner.free(p_rid); - memdelete(shader); - + } else if (GLES3::MaterialStorage::get_singleton()->owns_shader(p_rid)) { + GLES3::MaterialStorage::get_singleton()->shader_free(p_rid); return true; - } else if (material_owner.owns(p_rid)) { - Material *m = material_owner.get_or_null(p_rid); - - if (m->shader) { - m->shader->materials.remove(&m->list); - } - - /* - for (Map<Geometry *, int>::Element *E = m->geometry_owners.front(); E; E = E->next()) { - Geometry *g = E->key(); - g->material = RID(); - } - - for (Map<InstanceBaseDependency *, int>::Element *E = m->instance_owners.front(); E; E = E->next()) { - InstanceBaseDependency *ins = E->key(); - - if (ins->material_override == p_rid) { - ins->material_override = RID(); - } - - for (int i = 0; i < ins->materials.size(); i++) { - if (ins->materials[i] == p_rid) { - ins->materials.write[i] = RID(); - } - } - } -*/ - - material_owner.free(p_rid); - memdelete(m); - + } else if (GLES3::MaterialStorage::get_singleton()->owns_material(p_rid)) { + GLES3::MaterialStorage::get_singleton()->material_free(p_rid); return true; - } else { return false; } @@ -2893,95 +650,15 @@ RenderingDevice::DeviceType RasterizerStorageGLES3::get_video_adapter_type() con } void RasterizerStorageGLES3::initialize() { - RasterizerStorageGLES3::system_fbo = 0; config = GLES3::Config::get_singleton(); - config->initialize(); - - //determine formats for depth textures (or renderbuffers) - if (config->support_depth_texture) { - // Will use texture for depth - // have to manually see if we can create a valid framebuffer texture using UNSIGNED_INT, - // as there is no extension to test for this. - GLuint fbo; - glGenFramebuffers(1, &fbo); - bind_framebuffer(fbo); - GLuint depth; - glGenTextures(1, &depth); - glBindTexture(GL_TEXTURE_2D, depth); - glTexImage2D(GL_TEXTURE_2D, 0, config->depth_internalformat, 32, 32, 0, GL_DEPTH_COMPONENT, config->depth_type, nullptr); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth, 0); - - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - - bind_framebuffer_system(); - glDeleteFramebuffers(1, &fbo); - glBindTexture(GL_TEXTURE_2D, 0); - glDeleteTextures(1, &depth); - - if (status != GL_FRAMEBUFFER_COMPLETE) { - // If it fails, test to see if it supports a framebuffer texture using UNSIGNED_SHORT - // This is needed because many OSX devices don't support either UNSIGNED_INT or UNSIGNED_SHORT -#ifdef GLES_OVER_GL - config->depth_internalformat = GL_DEPTH_COMPONENT16; -#else - // OES_depth_texture extension only specifies GL_DEPTH_COMPONENT. - config->depth_internalformat = GL_DEPTH_COMPONENT; -#endif - config->depth_type = GL_UNSIGNED_SHORT; - - glGenFramebuffers(1, &fbo); - bind_framebuffer(fbo); - - glGenTextures(1, &depth); - glBindTexture(GL_TEXTURE_2D, depth); - glTexImage2D(GL_TEXTURE_2D, 0, config->depth_internalformat, 32, 32, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, nullptr); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth, 0); - - status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - if (status != GL_FRAMEBUFFER_COMPLETE) { - //if it fails again depth textures aren't supported, use rgba shadows and renderbuffer for depth - config->support_depth_texture = false; - config->use_rgba_3d_shadows = true; - } - - bind_framebuffer_system(); - glDeleteFramebuffers(1, &fbo); - glBindTexture(GL_TEXTURE_2D, 0); - glDeleteTextures(1, &depth); - } - } //picky requirements for these config->support_shadow_cubemaps = config->support_depth_texture && config->support_write_depth && config->support_depth_cubemaps; - frame.count = 0; - frame.delta = 0; - frame.current_rt = nullptr; - frame.clear_request = false; - // the use skeleton software path should be used if either float texture is not supported, // OR max_vertex_texture_image_units is zero config->use_skeleton_software = (config->float_texture_supported == false) || (config->max_vertex_texture_image_units == 0); - shaders.copy.initialize(); - shaders.copy_version = shaders.copy.version_create(); //TODO - shaders.copy.version_bind_shader(shaders.copy_version, CopyShaderGLES3::MODE_COPY_SECTION); - //shaders.cubemap_filter.init(); - //bool ggx_hq = GLOBAL_GET("rendering/quality/reflections/high_quality_ggx"); - //shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::LOW_QUALITY, !ggx_hq); - { // quad for copying stuff @@ -3139,18 +816,17 @@ uint64_t RasterizerStorageGLES3::get_rendering_info(RS::RenderingInfo p_info) { } void RasterizerStorageGLES3::update_dirty_resources() { - update_dirty_shaders(); - update_dirty_materials(); + GLES3::MaterialStorage::get_singleton()->update_dirty_shaders(); + GLES3::MaterialStorage::get_singleton()->update_dirty_materials(); // update_dirty_skeletons(); // update_dirty_multimeshes(); } RasterizerStorageGLES3::RasterizerStorageGLES3() { - RasterizerStorageGLES3::system_fbo = 0; + initialize(); } RasterizerStorageGLES3::~RasterizerStorageGLES3() { - shaders.copy.version_free(shaders.copy_version); } #endif // GLES3_ENABLED diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h index 4e04b918c2..da1dd0e66b 100644 --- a/drivers/gles3/rasterizer_storage_gles3.h +++ b/drivers/gles3/rasterizer_storage_gles3.h @@ -40,22 +40,17 @@ #include "servers/rendering/renderer_storage.h" #include "servers/rendering/shader_compiler.h" #include "servers/rendering/shader_language.h" -#include "storage/canvas_texture_storage.h" #include "storage/config.h" -#include "storage/render_target_storage.h" +#include "storage/material_storage.h" #include "storage/texture_storage.h" -#include "shaders/copy.glsl.gen.h" - -class RasterizerCanvasGLES3; -class RasterizerSceneGLES3; +// class RasterizerCanvasGLES3; +// class RasterizerSceneGLES3; class RasterizerStorageGLES3 : public RendererStorage { public: - RasterizerCanvasGLES3 *canvas; - RasterizerSceneGLES3 *scene; - - static GLuint system_fbo; + // RasterizerCanvasGLES3 *canvas; + // RasterizerSceneGLES3 *scene; GLES3::Config *config; @@ -79,19 +74,6 @@ public: } resources; - mutable struct Shaders { - ShaderCompiler compiler; - - CopyShaderGLES3 copy; - RID copy_version; - //CubemapFilterShaderGLES3 cubemap_filter; - - ShaderCompiler::IdentifierActions actions_canvas; - ShaderCompiler::IdentifierActions actions_scene; - ShaderCompiler::IdentifierActions actions_particles; - - } shaders; - struct Info { uint64_t texture_mem = 0; uint64_t vertex_mem = 0; @@ -132,6 +114,8 @@ public: ///////////////////////////////////////////////////////////////////////////////////////// public: + virtual void base_update_dependency(RID p_base, DependencyTracker *p_instance) override; + /* SKY API */ // not sure if used in godot 4? struct Sky { @@ -146,439 +130,6 @@ public: RID sky_create(); void sky_set_texture(RID p_sky, RID p_panorama, int p_radiance_size); - // SHADER API - - struct Material; - - struct Shader { - RID self; - - RS::ShaderMode mode; - ShaderGLES3 *shader; - String code; - SelfList<Material>::List materials; - - Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; - - RID version; - - SelfList<Shader> dirty_list; - - Map<StringName, Map<int, RID>> default_textures; - - Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms; - - bool valid; - - String path; - - uint32_t index; - uint64_t last_pass; - - struct CanvasItem { - enum BlendMode { - BLEND_MODE_MIX, - BLEND_MODE_ADD, - BLEND_MODE_SUB, - BLEND_MODE_MUL, - BLEND_MODE_PMALPHA, - }; - - int blend_mode; - - enum LightMode { - LIGHT_MODE_NORMAL, - LIGHT_MODE_UNSHADED, - LIGHT_MODE_LIGHT_ONLY - }; - - int light_mode; - - bool uses_screen_texture; - bool uses_screen_uv; - bool uses_time; - bool uses_modulate; - bool uses_color; - bool uses_vertex; - - // all these should disable item joining if used in a custom shader - bool uses_model_matrix; - bool uses_extra_matrix; - bool uses_projection_matrix; - bool uses_instance_custom; - - } canvas_item; - - struct Spatial { - enum BlendMode { - BLEND_MODE_MIX, - BLEND_MODE_ADD, - BLEND_MODE_SUB, - BLEND_MODE_MUL, - }; - - int blend_mode; - - enum DepthDrawMode { - DEPTH_DRAW_OPAQUE, - DEPTH_DRAW_ALWAYS, - DEPTH_DRAW_NEVER, - DEPTH_DRAW_ALPHA_PREPASS, - }; - - int depth_draw_mode; - - enum CullMode { - CULL_MODE_FRONT, - CULL_MODE_BACK, - CULL_MODE_DISABLED, - }; - - int cull_mode; - - bool uses_alpha; - bool uses_alpha_scissor; - bool unshaded; - bool no_depth_test; - bool uses_vertex; - bool uses_discard; - bool uses_sss; - bool uses_screen_texture; - bool uses_depth_texture; - bool uses_time; - bool uses_tangent; - bool uses_ensure_correct_normals; - bool writes_modelview_or_projection; - bool uses_vertex_lighting; - bool uses_world_coordinates; - - } spatial; - - struct Particles { - } particles; - - bool uses_vertex_time; - bool uses_fragment_time; - - Shader() : - dirty_list(this) { - shader = nullptr; - valid = false; - version = RID(); - last_pass = 0; - } - }; - - mutable RID_PtrOwner<Shader> shader_owner; - mutable SelfList<Shader>::List _shader_dirty_list; - - void _shader_make_dirty(Shader *p_shader); - - RID shader_allocate() override; - void shader_initialize(RID p_rid) override; - - //RID shader_create() override; - - void shader_set_code(RID p_shader, const String &p_code) override; - String shader_get_code(RID p_shader) const override; - void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const override; - - void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture, int p_index) override; - RID shader_get_default_texture_param(RID p_shader, const StringName &p_name, int p_index) const override; - - RS::ShaderNativeSourceCode shader_get_native_source_code(RID p_shader) const override { return RS::ShaderNativeSourceCode(); }; - - void _update_shader(Shader *p_shader) const; - void update_dirty_shaders(); - - // new - Variant shader_get_param_default(RID p_material, const StringName &p_param) const override { return Variant(); } - - // COMMON MATERIAL API - - struct Material { - RID self; - Shader *shader; - Map<StringName, Variant> params; - SelfList<Material> list; - SelfList<Material> dirty_list; - Vector<Pair<StringName, RID>> textures; - float line_width; - int render_priority; - - RID next_pass; - - uint32_t index; - uint64_t last_pass; - - // Map<Geometry *, int> geometry_owners; - // Map<InstanceBaseDependency *, int> instance_owners; - - bool can_cast_shadow_cache; - bool is_animated_cache; - - Material() : - list(this), - dirty_list(this) { - can_cast_shadow_cache = false; - is_animated_cache = false; - shader = nullptr; - line_width = 1.0; - last_pass = 0; - render_priority = 0; - } - }; - - mutable SelfList<Material>::List _material_dirty_list; - void _material_make_dirty(Material *p_material) const; - - // void _material_add_geometry(RID p_material, Geometry *p_geometry); - // void _material_remove_geometry(RID p_material, Geometry *p_geometry); - - void _update_material(Material *p_material); - - mutable RID_PtrOwner<Material> material_owner; - - // new - void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) override {} - void material_update_dependency(RID p_material, DependencyTracker *p_instance) override {} - - // old - RID material_allocate() override; - void material_initialize(RID p_rid) override; - - //RID material_create() override; - - void material_set_shader(RID p_material, RID p_shader) override; - RID material_get_shader(RID p_material) const; - - void material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) override; - Variant material_get_param(RID p_material, const StringName &p_param) const override; - Variant material_get_param_default(RID p_material, const StringName &p_param) const; - - void material_set_line_width(RID p_material, float p_width); - void material_set_next_pass(RID p_material, RID p_next_material) override; - - bool material_is_animated(RID p_material) override; - bool material_casts_shadows(RID p_material) override; - bool material_uses_tangents(RID p_material); - bool material_uses_ensure_correct_normals(RID p_material); - - void material_add_instance_owner(RID p_material, DependencyTracker *p_instance); - void material_remove_instance_owner(RID p_material, DependencyTracker *p_instance); - - void material_set_render_priority(RID p_material, int priority) override; - - void update_dirty_materials(); - - /* MESH API */ - - RID mesh_allocate() override; - void mesh_initialize(RID p_rid) override; - void mesh_set_blend_shape_count(RID p_mesh, int p_blend_shape_count) override; - bool mesh_needs_instance(RID p_mesh, bool p_has_skeleton) override; - RID mesh_instance_create(RID p_base) override; - void mesh_instance_set_skeleton(RID p_mesh_instance, RID p_skeleton) override; - void mesh_instance_set_blend_shape_weight(RID p_mesh_instance, int p_shape, float p_weight) override; - void mesh_instance_check_for_update(RID p_mesh_instance) override; - void update_mesh_instances() override; - void reflection_probe_set_mesh_lod_threshold(RID p_probe, float p_ratio) override; - float reflection_probe_get_mesh_lod_threshold(RID p_probe) const override; - - void mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) override; - - int mesh_get_blend_shape_count(RID p_mesh) const override; - - void mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMode p_mode) override; - RS::BlendShapeMode mesh_get_blend_shape_mode(RID p_mesh) const override; - - void mesh_surface_update_vertex_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) override; - void mesh_surface_update_attribute_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) override; - void mesh_surface_update_skin_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) override; - - void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) override; - RID mesh_surface_get_material(RID p_mesh, int p_surface) const override; - - RS::SurfaceData mesh_get_surface(RID p_mesh, int p_surface) const override; - int mesh_get_surface_count(RID p_mesh) const override; - - void mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) override; - AABB mesh_get_custom_aabb(RID p_mesh) const override; - - AABB mesh_get_aabb(RID p_mesh, RID p_skeleton = RID()) override; - void mesh_set_shadow_mesh(RID p_mesh, RID p_shadow_mesh) override; - void mesh_clear(RID p_mesh) override; - - /* MULTIMESH API */ - - struct MultiMesh { - RID mesh; - int instances = 0; - RS::MultimeshTransformFormat xform_format = RS::MULTIMESH_TRANSFORM_3D; - bool uses_colors = false; - bool uses_custom_data = false; - int visible_instances = -1; - AABB aabb; - bool aabb_dirty = false; - bool buffer_set = false; - uint32_t stride_cache = 0; - uint32_t color_offset_cache = 0; - uint32_t custom_data_offset_cache = 0; - - Vector<float> data_cache; //used if individual setting is used - bool *data_cache_dirty_regions = nullptr; - uint32_t data_cache_used_dirty_regions = 0; - - RID buffer; //storage buffer - RID uniform_set_3d; - RID uniform_set_2d; - - bool dirty = false; - MultiMesh *dirty_list = nullptr; - - Dependency dependency; - }; - - mutable RID_Owner<MultiMesh, true> multimesh_owner; - - MultiMesh *multimesh_dirty_list = nullptr; - - _FORCE_INLINE_ void _multimesh_make_local(MultiMesh *multimesh) const; - _FORCE_INLINE_ void _multimesh_mark_dirty(MultiMesh *multimesh, int p_index, bool p_aabb); - _FORCE_INLINE_ void _multimesh_mark_all_dirty(MultiMesh *multimesh, bool p_data, bool p_aabb); - _FORCE_INLINE_ void _multimesh_re_create_aabb(MultiMesh *multimesh, const float *p_data, int p_instances); - void _update_dirty_multimeshes(); - - RID multimesh_allocate() override; - void multimesh_initialize(RID p_rid) override; - void multimesh_allocate_data(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false) override; - int multimesh_get_instance_count(RID p_multimesh) const override; - - void multimesh_set_mesh(RID p_multimesh, RID p_mesh) override; - void multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform3D &p_transform) override; - void multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform) override; - void multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) override; - void multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_color) override; - - RID multimesh_get_mesh(RID p_multimesh) const override; - AABB multimesh_get_aabb(RID p_multimesh) const override; - - Transform3D multimesh_instance_get_transform(RID p_multimesh, int p_index) const override; - Transform2D multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const override; - Color multimesh_instance_get_color(RID p_multimesh, int p_index) const override; - Color multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const override; - void multimesh_set_buffer(RID p_multimesh, const Vector<float> &p_buffer) override; - Vector<float> multimesh_get_buffer(RID p_multimesh) const override; - - void multimesh_set_visible_instances(RID p_multimesh, int p_visible) override; - int multimesh_get_visible_instances(RID p_multimesh) const override; - - _FORCE_INLINE_ RS::MultimeshTransformFormat multimesh_get_transform_format(RID p_multimesh) const { - MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); - return multimesh->xform_format; - } - - _FORCE_INLINE_ bool multimesh_uses_colors(RID p_multimesh) const { - MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); - return multimesh->uses_colors; - } - - _FORCE_INLINE_ bool multimesh_uses_custom_data(RID p_multimesh) const { - MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); - return multimesh->uses_custom_data; - } - - _FORCE_INLINE_ uint32_t multimesh_get_instances_to_draw(RID p_multimesh) const { - MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); - if (multimesh->visible_instances >= 0) { - return multimesh->visible_instances; - } - return multimesh->instances; - } - - /* SKELETON API */ - - RID skeleton_allocate() override; - void skeleton_initialize(RID p_rid) override; - void skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_skeleton = false) override; - void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) override; - int skeleton_get_bone_count(RID p_skeleton) const override; - void skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform3D &p_transform) override; - Transform3D skeleton_bone_get_transform(RID p_skeleton, int p_bone) const override; - void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) override; - Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const override; - - /* Light API */ - - RID directional_light_allocate() override; - void directional_light_initialize(RID p_rid) override; - RID omni_light_allocate() override; - void omni_light_initialize(RID p_rid) override; - RID spot_light_allocate() override; - void spot_light_initialize(RID p_rid) override; - RID reflection_probe_allocate() override; - void reflection_probe_initialize(RID p_rid) override; - - void light_set_color(RID p_light, const Color &p_color) override; - void light_set_param(RID p_light, RS::LightParam p_param, float p_value) override; - void light_set_shadow(RID p_light, bool p_enabled) override; - void light_set_projector(RID p_light, RID p_texture) override; - void light_set_negative(RID p_light, bool p_enable) override; - void light_set_cull_mask(RID p_light, uint32_t p_mask) override; - void light_set_distance_fade(RID p_light, bool p_enabled, float p_begin, float p_shadow, float p_length) override; - void light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) override; - void light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode) override; - void light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) override; - - void light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) override; - - void light_directional_set_shadow_mode(RID p_light, RS::LightDirectionalShadowMode p_mode) override; - void light_directional_set_blend_splits(RID p_light, bool p_enable) override; - bool light_directional_get_blend_splits(RID p_light) const override; - void light_directional_set_sky_mode(RID p_light, RS::LightDirectionalSkyMode p_mode) override; - RS::LightDirectionalSkyMode light_directional_get_sky_mode(RID p_light) const override; - - RS::LightDirectionalShadowMode light_directional_get_shadow_mode(RID p_light) override; - RS::LightOmniShadowMode light_omni_get_shadow_mode(RID p_light) override; - - bool light_has_shadow(RID p_light) const override; - bool light_has_projector(RID p_light) const override; - - RS::LightType light_get_type(RID p_light) const override; - AABB light_get_aabb(RID p_light) const override; - float light_get_param(RID p_light, RS::LightParam p_param) override; - Color light_get_color(RID p_light) override; - RS::LightBakeMode light_get_bake_mode(RID p_light) override; - uint32_t light_get_max_sdfgi_cascade(RID p_light) override; - uint64_t light_get_version(RID p_light) const override; - - /* PROBE API */ - - void reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) override; - void reflection_probe_set_intensity(RID p_probe, float p_intensity) override; - void reflection_probe_set_ambient_mode(RID p_probe, RS::ReflectionProbeAmbientMode p_mode) override; - void reflection_probe_set_ambient_color(RID p_probe, const Color &p_color) override; - void reflection_probe_set_ambient_energy(RID p_probe, float p_energy) override; - void reflection_probe_set_max_distance(RID p_probe, float p_distance) override; - void reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) override; - void reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) override; - void reflection_probe_set_as_interior(RID p_probe, bool p_enable) override; - void reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) override; - void reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) override; - void reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) override; - void reflection_probe_set_resolution(RID p_probe, int p_resolution) override; - - AABB reflection_probe_get_aabb(RID p_probe) const override; - RS::ReflectionProbeUpdateMode reflection_probe_get_update_mode(RID p_probe) const override; - uint32_t reflection_probe_get_cull_mask(RID p_probe) const override; - Vector3 reflection_probe_get_extents(RID p_probe) const override; - Vector3 reflection_probe_get_origin_offset(RID p_probe) const override; - float reflection_probe_get_origin_max_distance(RID p_probe) const override; - bool reflection_probe_renders_shadows(RID p_probe) const override; - - void base_update_dependency(RID p_base, DependencyTracker *p_instance) override; - void skeleton_update_dependency(RID p_base, DependencyTracker *p_instance) override; - /* VOXEL GI API */ RID voxel_gi_allocate() override; @@ -620,103 +171,10 @@ public: uint32_t voxel_gi_get_version(RID p_voxel_gi) override; - /* LIGHTMAP CAPTURE */ - RID lightmap_allocate() override; - void lightmap_initialize(RID p_rid) override; - void lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) override; - void lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) override; - void lightmap_set_probe_interior(RID p_lightmap, bool p_interior) override; - void lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) override; - PackedVector3Array lightmap_get_probe_capture_points(RID p_lightmap) const override; - PackedColorArray lightmap_get_probe_capture_sh(RID p_lightmap) const override; - PackedInt32Array lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const override; - PackedInt32Array lightmap_get_probe_capture_bsp_tree(RID p_lightmap) const override; - AABB lightmap_get_aabb(RID p_lightmap) const override; - void lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point, Color *r_sh) override; - bool lightmap_is_interior(RID p_lightmap) const override; - void lightmap_set_probe_capture_update_speed(float p_speed) override; - float lightmap_get_probe_capture_update_speed() const override; - /* OCCLUDER */ void occluder_set_mesh(RID p_occluder, const PackedVector3Array &p_vertices, const PackedInt32Array &p_indices); - /* PARTICLES */ - - RID particles_allocate() override; - void particles_initialize(RID p_rid) override; - void particles_set_mode(RID p_particles, RS::ParticlesMode p_mode) override; - void particles_emit(RID p_particles, const Transform3D &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) override; - void particles_set_emitting(RID p_particles, bool p_emitting) override; - void particles_set_amount(RID p_particles, int p_amount) override; - void particles_set_lifetime(RID p_particles, double p_lifetime) override; - void particles_set_one_shot(RID p_particles, bool p_one_shot) override; - void particles_set_pre_process_time(RID p_particles, double p_time) override; - void particles_set_explosiveness_ratio(RID p_particles, real_t p_ratio) override; - void particles_set_randomness_ratio(RID p_particles, real_t p_ratio) override; - void particles_set_custom_aabb(RID p_particles, const AABB &p_aabb) override; - void particles_set_speed_scale(RID p_particles, double p_scale) override; - void particles_set_use_local_coordinates(RID p_particles, bool p_enable) override; - void particles_set_process_material(RID p_particles, RID p_material) override; - RID particles_get_process_material(RID p_particles) const override; - void particles_set_fixed_fps(RID p_particles, int p_fps) override; - void particles_set_interpolate(RID p_particles, bool p_enable) override; - void particles_set_fractional_delta(RID p_particles, bool p_enable) override; - void particles_set_subemitter(RID p_particles, RID p_subemitter_particles) override; - void particles_set_view_axis(RID p_particles, const Vector3 &p_axis, const Vector3 &p_up_axis) override; - void particles_set_collision_base_size(RID p_particles, real_t p_size) override; - - void particles_set_transform_align(RID p_particles, RS::ParticlesTransformAlign p_transform_align) override; - - void particles_set_trails(RID p_particles, bool p_enable, double p_length) override; - void particles_set_trail_bind_poses(RID p_particles, const Vector<Transform3D> &p_bind_poses) override; - - void particles_restart(RID p_particles) override; - - void particles_set_draw_order(RID p_particles, RS::ParticlesDrawOrder p_order) override; - - void particles_set_draw_passes(RID p_particles, int p_count) override; - void particles_set_draw_pass_mesh(RID p_particles, int p_pass, RID p_mesh) override; - - void particles_request_process(RID p_particles) override; - AABB particles_get_current_aabb(RID p_particles) override; - AABB particles_get_aabb(RID p_particles) const override; - - void particles_set_emission_transform(RID p_particles, const Transform3D &p_transform) override; - - bool particles_get_emitting(RID p_particles) override; - int particles_get_draw_passes(RID p_particles) const override; - RID particles_get_draw_pass_mesh(RID p_particles, int p_pass) const override; - - void particles_add_collision(RID p_particles, RID p_instance) override; - void particles_remove_collision(RID p_particles, RID p_instance) override; - - void particles_set_canvas_sdf_collision(RID p_particles, bool p_enable, const Transform2D &p_xform, const Rect2 &p_to_screen, RID p_texture) override; - - void update_particles() override; - - /* PARTICLES COLLISION */ - - RID particles_collision_allocate() override; - void particles_collision_initialize(RID p_rid) override; - void particles_collision_set_collision_type(RID p_particles_collision, RS::ParticlesCollisionType p_type) override; - void particles_collision_set_cull_mask(RID p_particles_collision, uint32_t p_cull_mask) override; - void particles_collision_set_sphere_radius(RID p_particles_collision, real_t p_radius) override; - void particles_collision_set_box_extents(RID p_particles_collision, const Vector3 &p_extents) override; - void particles_collision_set_attractor_strength(RID p_particles_collision, real_t p_strength) override; - void particles_collision_set_attractor_directionality(RID p_particles_collision, real_t p_directionality) override; - void particles_collision_set_attractor_attenuation(RID p_particles_collision, real_t p_curve) override; - void particles_collision_set_field_texture(RID p_particles_collision, RID p_texture) override; - void particles_collision_height_field_update(RID p_particles_collision) override; - void particles_collision_set_height_field_resolution(RID p_particles_collision, RS::ParticlesCollisionHeightfieldResolution p_resolution) override; - AABB particles_collision_get_aabb(RID p_particles_collision) const override; - bool particles_collision_is_heightfield(RID p_particles_collision) const override; - RID particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const override; - - RID particles_collision_instance_create(RID p_collision) override; - void particles_collision_instance_set_transform(RID p_collision_instance, const Transform3D &p_transform) override; - void particles_collision_instance_set_active(RID p_collision_instance, bool p_active) override; - /* FOG VOLUMES */ RID fog_volume_allocate() override; @@ -737,63 +195,6 @@ public: AABB visibility_notifier_get_aabb(RID p_notifier) const override; void visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred) override; - /* GLOBAL VARIABLES */ - - void global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) override; - void global_variable_remove(const StringName &p_name) override; - Vector<StringName> global_variable_get_list() const override; - - void global_variable_set(const StringName &p_name, const Variant &p_value) override; - void global_variable_set_override(const StringName &p_name, const Variant &p_value) override; - Variant global_variable_get(const StringName &p_name) const override; - RS::GlobalVariableType global_variable_get_type(const StringName &p_name) const override; - - void global_variables_load_settings(bool p_load_textures = true) override; - void global_variables_clear() override; - - int32_t global_variables_instance_allocate(RID p_instance) override; - void global_variables_instance_free(RID p_instance) override; - void global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) override; - - bool particles_is_inactive(RID p_particles) const override; - - // RENDER TARGET - - mutable RID_PtrOwner<GLES3::RenderTarget> render_target_owner; - - void _render_target_clear(GLES3::RenderTarget *rt); - void _render_target_allocate(GLES3::RenderTarget *rt); - void _set_current_render_target(RID p_render_target); - - RID render_target_create() override; - void render_target_set_position(RID p_render_target, int p_x, int p_y) override; - void render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) override; - Size2i render_target_get_size(RID p_render_target); - RID render_target_get_texture(RID p_render_target) override; - void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) override; - - void render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) override; - bool render_target_was_used(RID p_render_target) override; - void render_target_clear_used(RID p_render_target); - void render_target_set_msaa(RID p_render_target, RS::ViewportMSAA p_msaa); - void render_target_set_use_fxaa(RID p_render_target, bool p_fxaa); - void render_target_set_use_debanding(RID p_render_target, bool p_debanding); - - // new - void render_target_set_as_unused(RID p_render_target) override { - render_target_clear_used(p_render_target); - } - - void render_target_request_clear(RID p_render_target, const Color &p_clear_color) override; - bool render_target_is_clear_requested(RID p_render_target) override; - Color render_target_get_clear_request_color(RID p_render_target) override; - void render_target_disable_clear_request(RID p_render_target) override; - void render_target_do_clear_request(RID p_render_target) override; - - void render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) override; - Rect2i render_target_get_sdf_rect(RID p_render_target) const override; - void render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled) override; - // access from canvas // GLES3::RenderTarget * render_target_get(RID p_render_target); @@ -833,24 +234,6 @@ public: bool free(RID p_rid) override; - struct Frame { - GLES3::RenderTarget *current_rt; - - // these 2 may have been superseded by the equivalents in the render target. - // these may be able to be removed. - bool clear_request; - Color clear_request_color; - - float time; - float delta; - uint64_t count; - - Frame() { - // current_rt = nullptr; - // clear_request = false; - } - } frame; - void initialize(); void finalize(); @@ -892,34 +275,9 @@ public: return String(); } - // make access easier to these - struct Dimensions { - // render target - int rt_width; - int rt_height; - - // window - int win_width; - int win_height; - Dimensions() { - rt_width = 0; - rt_height = 0; - win_width = 0; - win_height = 0; - } - } _dims; - void buffer_orphan_and_upload(unsigned int p_buffer_size, unsigned int p_offset, unsigned int p_data_size, const void *p_data, GLenum p_target = GL_ARRAY_BUFFER, GLenum p_usage = GL_DYNAMIC_DRAW, bool p_optional_orphan = false) const; bool safe_buffer_sub_data(unsigned int p_total_buffer_size, GLenum p_target, unsigned int p_offset, unsigned int p_data_size, const void *p_data, unsigned int &r_offset_after) const; - void bind_framebuffer(GLuint framebuffer) { - glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); - } - - void bind_framebuffer_system() { - glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES3::system_fbo); - } - RasterizerStorageGLES3(); ~RasterizerStorageGLES3(); }; diff --git a/drivers/gles3/shader_gles3.cpp b/drivers/gles3/shader_gles3.cpp index 9349722625..1c946895a5 100644 --- a/drivers/gles3/shader_gles3.cpp +++ b/drivers/gles3/shader_gles3.cpp @@ -464,8 +464,8 @@ bool ShaderGLES3::_load_from_cache(Version *p_version) { String sha1 = _version_get_sha1(p_version); String path = shader_cache_dir.plus_file(name).plus_file(base_sha256).plus_file(sha1) + ".cache"; - FileAccessRef f = FileAccess::open(path, FileAccess::READ); - if (!f) { + Ref<FileAccess> f = FileAccess::open(path, FileAccess::READ); + if (f.is_null()) { return false; } @@ -530,8 +530,8 @@ void ShaderGLES3::_save_to_cache(Version *p_version) { String sha1 = _version_get_sha1(p_version); String path = shader_cache_dir.plus_file(name).plus_file(base_sha256).plus_file(sha1) + ".cache"; - FileAccessRef f = FileAccess::open(path, FileAccess::WRITE); - ERR_FAIL_COND(!f); + Ref<FileAccess> f = FileAccess::open(path, FileAccess::WRITE); + ERR_FAIL_COND(f.is_null()); f->store_buffer((const uint8_t *)shader_file_header, 4); f->store_32(cache_file_version); //file version uint32_t variant_count = variant_count; @@ -541,8 +541,6 @@ void ShaderGLES3::_save_to_cache(Version *p_version) { f->store_32(p_version->variant_data[i].size()); //stage count f->store_buffer(p_version->variant_data[i].ptr(), p_version->variant_data[i].size()); } - - f->close(); #endif } @@ -554,11 +552,9 @@ void ShaderGLES3::_clear_version(Version *p_version) { for (int i = 0; i < variant_count; i++) { for (OAHashMap<uint64_t, Version::Specialization>::Iterator it = p_version->variants[i].iter(); it.valid; it = p_version->variants[i].next_iter(it)) { - if (it.valid) { - glDeleteShader(it.value->vert_id); - glDeleteShader(it.value->frag_id); - glDeleteProgram(it.value->id); - } + glDeleteShader(it.value->vert_id); + glDeleteShader(it.value->frag_id); + glDeleteProgram(it.value->id); } } @@ -644,8 +640,8 @@ void ShaderGLES3::initialize(const String &p_general_defines, int p_base_texture base_sha256 = hash_build.as_string().sha256_text(); - DirAccessRef d = DirAccess::open(shader_cache_dir); - ERR_FAIL_COND(!d); + Ref<DirAccess> d = DirAccess::open(shader_cache_dir); + ERR_FAIL_COND(d.is_null()); if (d->change_dir(name) != OK) { Error err = d->make_dir(name); ERR_FAIL_COND(err != OK); diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl index 8812447f6e..f7db1d950c 100644 --- a/drivers/gles3/shaders/canvas.glsl +++ b/drivers/gles3/shaders/canvas.glsl @@ -478,10 +478,6 @@ float msdf_median(float r, float g, float b, float a) { return min(max(min(r, g), min(max(r, g), b)), a); } -vec2 msdf_map(vec2 value, vec2 in_min, vec2 in_max, vec2 out_min, vec2 out_max) { - return out_min + (out_max - out_min) * (value - in_min) / (in_max - in_min); -} - void main() { vec4 color = color_interp; vec2 uv = uv_interp; diff --git a/drivers/gles3/storage/canvas_texture_storage.cpp b/drivers/gles3/storage/canvas_texture_storage.cpp deleted file mode 100644 index fe12700c21..0000000000 --- a/drivers/gles3/storage/canvas_texture_storage.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/*************************************************************************/ -/* canvas_texture_storage.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 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. */ -/*************************************************************************/ - -#ifdef GLES3_ENABLED - -#include "canvas_texture_storage.h" - -using namespace GLES3; - -CanvasTextureStorage *CanvasTextureStorage::singleton = nullptr; - -CanvasTextureStorage *CanvasTextureStorage::get_singleton() { - return singleton; -} - -CanvasTextureStorage::CanvasTextureStorage() { - singleton = this; -} - -CanvasTextureStorage::~CanvasTextureStorage() { - singleton = nullptr; -} - -RID CanvasTextureStorage::canvas_texture_allocate() { - return canvas_texture_owner.allocate_rid(); -} - -void CanvasTextureStorage::canvas_texture_initialize(RID p_rid) { - canvas_texture_owner.initialize_rid(p_rid); -} - -void CanvasTextureStorage::canvas_texture_free(RID p_rid) { - canvas_texture_owner.free(p_rid); -} - -void CanvasTextureStorage::canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) { - CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture); - switch (p_channel) { - case RS::CANVAS_TEXTURE_CHANNEL_DIFFUSE: { - ct->diffuse = p_texture; - } break; - case RS::CANVAS_TEXTURE_CHANNEL_NORMAL: { - ct->normal_map = p_texture; - } break; - case RS::CANVAS_TEXTURE_CHANNEL_SPECULAR: { - ct->specular = p_texture; - } break; - } -} - -void CanvasTextureStorage::canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_specular_color, float p_shininess) { - CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture); - ct->specular_color.r = p_specular_color.r; - ct->specular_color.g = p_specular_color.g; - ct->specular_color.b = p_specular_color.b; - ct->specular_color.a = p_shininess; -} - -void CanvasTextureStorage::canvas_texture_set_texture_filter(RID p_canvas_texture, RS::CanvasItemTextureFilter p_filter) { - CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture); - ct->texture_filter = p_filter; -} - -void CanvasTextureStorage::canvas_texture_set_texture_repeat(RID p_canvas_texture, RS::CanvasItemTextureRepeat p_repeat) { - CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture); - ct->texture_repeat = p_repeat; -} - -#endif // !GLES3_ENABLED diff --git a/drivers/gles3/storage/canvas_texture_storage.h b/drivers/gles3/storage/canvas_texture_storage.h deleted file mode 100644 index 5930e927fe..0000000000 --- a/drivers/gles3/storage/canvas_texture_storage.h +++ /dev/null @@ -1,87 +0,0 @@ -/*************************************************************************/ -/* canvas_texture_storage.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 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 CANVAS_TEXTURE_STORAGE_GLES3_H -#define CANVAS_TEXTURE_STORAGE_GLES3_H - -#ifdef GLES3_ENABLED - -#include "core/templates/rid_owner.h" -#include "servers/rendering/storage/canvas_texture_storage.h" - -namespace GLES3 { - -struct CanvasTexture { - RID diffuse; - RID normal_map; - RID specular; - Color specular_color = Color(1, 1, 1, 1); - float shininess = 1.0; - - RS::CanvasItemTextureFilter texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT; - RS::CanvasItemTextureRepeat texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT; - - Size2i size_cache = Size2i(1, 1); - bool use_normal_cache = false; - bool use_specular_cache = false; - bool cleared_cache = true; -}; - -class CanvasTextureStorage : public RendererCanvasTextureStorage { -private: - static CanvasTextureStorage *singleton; - - RID_Owner<CanvasTexture, true> canvas_texture_owner; - -public: - static CanvasTextureStorage *get_singleton(); - - CanvasTextureStorage(); - virtual ~CanvasTextureStorage(); - - CanvasTexture *get_canvas_texture(RID p_rid) { return canvas_texture_owner.get_or_null(p_rid); }; - bool owns_canvas_texture(RID p_rid) { return canvas_texture_owner.owns(p_rid); }; - - virtual RID canvas_texture_allocate() override; - virtual void canvas_texture_initialize(RID p_rid) override; - virtual void canvas_texture_free(RID p_rid) override; - - virtual void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) override; - virtual void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) override; - - virtual void canvas_texture_set_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) override; - virtual void canvas_texture_set_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) override; -}; - -} // namespace GLES3 - -#endif // !GLES3_ENABLED - -#endif // !CANVAS_TEXTURE_STORAGE_GLES3_H diff --git a/drivers/gles3/storage/config.cpp b/drivers/gles3/storage/config.cpp index 1f66401427..a83ad34d4c 100644 --- a/drivers/gles3/storage/config.cpp +++ b/drivers/gles3/storage/config.cpp @@ -39,14 +39,7 @@ Config *Config::singleton = nullptr; Config::Config() { singleton = this; - should_orphan = true; -} - -Config::~Config() { - singleton = nullptr; -} -void Config::initialize() { { const GLubyte *extension_string = glGetString(GL_EXTENSIONS); @@ -153,4 +146,8 @@ void Config::initialize() { // should_orphan = GLOBAL_GET("rendering/options/api_usage_legacy/orphan_buffers"); } +Config::~Config() { + singleton = nullptr; +} + #endif // GLES3_ENABLED diff --git a/drivers/gles3/storage/config.h b/drivers/gles3/storage/config.h index 25bd3fd9a1..11a7cc8499 100644 --- a/drivers/gles3/storage/config.h +++ b/drivers/gles3/storage/config.h @@ -103,7 +103,6 @@ public: Config(); ~Config(); - void initialize(); }; } // namespace GLES3 diff --git a/drivers/gles3/storage/decal_atlas_storage.cpp b/drivers/gles3/storage/decal_atlas_storage.cpp deleted file mode 100644 index 7bac34ea19..0000000000 --- a/drivers/gles3/storage/decal_atlas_storage.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/*************************************************************************/ -/* decal_atlas_storage.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 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. */ -/*************************************************************************/ - -#ifdef GLES3_ENABLED - -#include "decal_atlas_storage.h" - -using namespace GLES3; - -RID DecalAtlasStorage::decal_allocate() { - return RID(); -} - -void DecalAtlasStorage::decal_initialize(RID p_rid) { -} - -void DecalAtlasStorage::decal_set_extents(RID p_decal, const Vector3 &p_extents) { -} - -void DecalAtlasStorage::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) { -} - -void DecalAtlasStorage::decal_set_emission_energy(RID p_decal, float p_energy) { -} - -void DecalAtlasStorage::decal_set_albedo_mix(RID p_decal, float p_mix) { -} - -void DecalAtlasStorage::decal_set_modulate(RID p_decal, const Color &p_modulate) { -} - -void DecalAtlasStorage::decal_set_cull_mask(RID p_decal, uint32_t p_layers) { -} - -void DecalAtlasStorage::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) { -} - -void DecalAtlasStorage::decal_set_fade(RID p_decal, float p_above, float p_below) { -} - -void DecalAtlasStorage::decal_set_normal_fade(RID p_decal, float p_fade) { -} - -AABB DecalAtlasStorage::decal_get_aabb(RID p_decal) const { - return AABB(); -} - -#endif // !GLES3_ENABLED diff --git a/drivers/gles3/storage/decal_atlas_storage.h b/drivers/gles3/storage/decal_atlas_storage.h deleted file mode 100644 index f5dc36b1fb..0000000000 --- a/drivers/gles3/storage/decal_atlas_storage.h +++ /dev/null @@ -1,67 +0,0 @@ -/*************************************************************************/ -/* decal_atlas_storage.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 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 DECAL_ATLAS_STORAGE_GLES3_H -#define DECAL_ATLAS_STORAGE_GLES3_H - -#ifdef GLES3_ENABLED - -#include "core/templates/rid_owner.h" -#include "servers/rendering/storage/decal_atlas_storage.h" - -namespace GLES3 { - -class DecalAtlasStorage : public RendererDecalAtlasStorage { -public: - virtual RID decal_allocate() override; - virtual void decal_initialize(RID p_rid) override; - virtual void decal_free(RID p_rid) override{}; - - virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) override; - virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) override; - virtual void decal_set_emission_energy(RID p_decal, float p_energy) override; - virtual void decal_set_albedo_mix(RID p_decal, float p_mix) override; - virtual void decal_set_modulate(RID p_decal, const Color &p_modulate) override; - virtual void decal_set_cull_mask(RID p_decal, uint32_t p_layers) override; - virtual void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) override; - virtual void decal_set_fade(RID p_decal, float p_above, float p_below) override; - virtual void decal_set_normal_fade(RID p_decal, float p_fade) override; - - virtual AABB decal_get_aabb(RID p_decal) const override; - - virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {} - virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {} -}; - -} // namespace GLES3 - -#endif // !GLES3_ENABLED - -#endif // !DECAL_ATLAS_STORAGE_GLES3_H diff --git a/drivers/gles3/storage/light_storage.cpp b/drivers/gles3/storage/light_storage.cpp new file mode 100644 index 0000000000..7395611d71 --- /dev/null +++ b/drivers/gles3/storage/light_storage.cpp @@ -0,0 +1,316 @@ +/*************************************************************************/ +/* light_storage.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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. */ +/*************************************************************************/ + +#ifdef GLES3_ENABLED + +#include "light_storage.h" +#include "config.h" + +using namespace GLES3; + +LightStorage *LightStorage::singleton = nullptr; + +LightStorage *LightStorage::get_singleton() { + return singleton; +} + +LightStorage::LightStorage() { + singleton = this; +} + +LightStorage::~LightStorage() { + singleton = nullptr; +} + +/* Light API */ + +RID LightStorage::directional_light_allocate() { + return RID(); +} + +void LightStorage::directional_light_initialize(RID p_rid) { +} + +RID LightStorage::omni_light_allocate() { + return RID(); +} + +void LightStorage::omni_light_initialize(RID p_rid) { +} + +RID LightStorage::spot_light_allocate() { + return RID(); +} + +void LightStorage::spot_light_initialize(RID p_rid) { +} + +void LightStorage::light_free(RID p_rid) { +} + +void LightStorage::light_set_color(RID p_light, const Color &p_color) { +} + +void LightStorage::light_set_param(RID p_light, RS::LightParam p_param, float p_value) { +} + +void LightStorage::light_set_shadow(RID p_light, bool p_enabled) { +} + +void LightStorage::light_set_projector(RID p_light, RID p_texture) { +} + +void LightStorage::light_set_negative(RID p_light, bool p_enable) { +} + +void LightStorage::light_set_cull_mask(RID p_light, uint32_t p_mask) { +} + +void LightStorage::light_set_distance_fade(RID p_light, bool p_enabled, float p_begin, float p_shadow, float p_length) { +} + +void LightStorage::light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) { +} + +void LightStorage::light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode) { +} + +void LightStorage::light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) { +} + +void LightStorage::light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) { +} + +void LightStorage::light_directional_set_shadow_mode(RID p_light, RS::LightDirectionalShadowMode p_mode) { +} + +void LightStorage::light_directional_set_blend_splits(RID p_light, bool p_enable) { +} + +bool LightStorage::light_directional_get_blend_splits(RID p_light) const { + return false; +} + +void LightStorage::light_directional_set_sky_mode(RID p_light, RS::LightDirectionalSkyMode p_mode) { +} + +RS::LightDirectionalSkyMode LightStorage::light_directional_get_sky_mode(RID p_light) const { + return RS::LIGHT_DIRECTIONAL_SKY_MODE_LIGHT_AND_SKY; +} + +RS::LightDirectionalShadowMode LightStorage::light_directional_get_shadow_mode(RID p_light) { + return RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL; +} + +RS::LightOmniShadowMode LightStorage::light_omni_get_shadow_mode(RID p_light) { + return RS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID; +} + +bool LightStorage::light_has_shadow(RID p_light) const { + return false; +} + +bool LightStorage::light_has_projector(RID p_light) const { + return false; +} + +RS::LightType LightStorage::light_get_type(RID p_light) const { + return RS::LIGHT_OMNI; +} + +AABB LightStorage::light_get_aabb(RID p_light) const { + return AABB(); +} + +float LightStorage::light_get_param(RID p_light, RS::LightParam p_param) { + return 0.0; +} + +Color LightStorage::light_get_color(RID p_light) { + return Color(); +} + +RS::LightBakeMode LightStorage::light_get_bake_mode(RID p_light) { + return RS::LIGHT_BAKE_DISABLED; +} + +uint32_t LightStorage::light_get_max_sdfgi_cascade(RID p_light) { + return 0; +} + +uint64_t LightStorage::light_get_version(RID p_light) const { + return 0; +} + +/* PROBE API */ + +RID LightStorage::reflection_probe_allocate() { + return RID(); +} + +void LightStorage::reflection_probe_initialize(RID p_rid) { +} + +void LightStorage::reflection_probe_free(RID p_rid) { +} + +void LightStorage::reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) { +} + +void LightStorage::reflection_probe_set_intensity(RID p_probe, float p_intensity) { +} + +void LightStorage::reflection_probe_set_ambient_mode(RID p_probe, RS::ReflectionProbeAmbientMode p_mode) { +} + +void LightStorage::reflection_probe_set_ambient_color(RID p_probe, const Color &p_color) { +} + +void LightStorage::reflection_probe_set_ambient_energy(RID p_probe, float p_energy) { +} + +void LightStorage::reflection_probe_set_max_distance(RID p_probe, float p_distance) { +} + +void LightStorage::reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) { +} + +void LightStorage::reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) { +} + +void LightStorage::reflection_probe_set_as_interior(RID p_probe, bool p_enable) { +} + +void LightStorage::reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) { +} + +void LightStorage::reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) { +} + +void LightStorage::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) { +} + +void LightStorage::reflection_probe_set_resolution(RID p_probe, int p_resolution) { +} + +AABB LightStorage::reflection_probe_get_aabb(RID p_probe) const { + return AABB(); +} + +RS::ReflectionProbeUpdateMode LightStorage::reflection_probe_get_update_mode(RID p_probe) const { + return RenderingServer::REFLECTION_PROBE_UPDATE_ONCE; +} + +uint32_t LightStorage::reflection_probe_get_cull_mask(RID p_probe) const { + return 0; +} + +Vector3 LightStorage::reflection_probe_get_extents(RID p_probe) const { + return Vector3(); +} + +Vector3 LightStorage::reflection_probe_get_origin_offset(RID p_probe) const { + return Vector3(); +} + +float LightStorage::reflection_probe_get_origin_max_distance(RID p_probe) const { + return 0.0; +} + +bool LightStorage::reflection_probe_renders_shadows(RID p_probe) const { + return false; +} + +void LightStorage::reflection_probe_set_mesh_lod_threshold(RID p_probe, float p_ratio) { +} + +float LightStorage::reflection_probe_get_mesh_lod_threshold(RID p_probe) const { + return 0.0; +} + +/* LIGHTMAP CAPTURE */ + +RID LightStorage::lightmap_allocate() { + return RID(); +} + +void LightStorage::lightmap_initialize(RID p_rid) { +} + +void LightStorage::lightmap_free(RID p_rid) { +} + +void LightStorage::lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) { +} + +void LightStorage::lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) { +} + +void LightStorage::lightmap_set_probe_interior(RID p_lightmap, bool p_interior) { +} + +void LightStorage::lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) { +} + +PackedVector3Array LightStorage::lightmap_get_probe_capture_points(RID p_lightmap) const { + return PackedVector3Array(); +} + +PackedColorArray LightStorage::lightmap_get_probe_capture_sh(RID p_lightmap) const { + return PackedColorArray(); +} + +PackedInt32Array LightStorage::lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const { + return PackedInt32Array(); +} + +PackedInt32Array LightStorage::lightmap_get_probe_capture_bsp_tree(RID p_lightmap) const { + return PackedInt32Array(); +} + +AABB LightStorage::lightmap_get_aabb(RID p_lightmap) const { + return AABB(); +} + +void LightStorage::lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point, Color *r_sh) { +} + +bool LightStorage::lightmap_is_interior(RID p_lightmap) const { + return false; +} + +void LightStorage::lightmap_set_probe_capture_update_speed(float p_speed) { +} + +float LightStorage::lightmap_get_probe_capture_update_speed() const { + return 0; +} + +#endif // !GLES3_ENABLED diff --git a/drivers/gles3/storage/light_storage.h b/drivers/gles3/storage/light_storage.h new file mode 100644 index 0000000000..6f24e467bc --- /dev/null +++ b/drivers/gles3/storage/light_storage.h @@ -0,0 +1,154 @@ +/*************************************************************************/ +/* light_storage.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 LIGHT_STORAGE_GLES3_H +#define LIGHT_STORAGE_GLES3_H + +#ifdef GLES3_ENABLED + +#include "core/templates/local_vector.h" +#include "core/templates/rid_owner.h" +#include "core/templates/self_list.h" +#include "servers/rendering/renderer_compositor.h" +#include "servers/rendering/renderer_storage.h" +#include "servers/rendering/storage/light_storage.h" + +namespace GLES3 { + +class LightStorage : public RendererLightStorage { +private: + static LightStorage *singleton; + +public: + static LightStorage *get_singleton(); + + LightStorage(); + virtual ~LightStorage(); + + /* Light API */ + + virtual RID directional_light_allocate() override; + virtual void directional_light_initialize(RID p_rid) override; + virtual RID omni_light_allocate() override; + virtual void omni_light_initialize(RID p_rid) override; + virtual RID spot_light_allocate() override; + virtual void spot_light_initialize(RID p_rid) override; + + virtual void light_free(RID p_rid) override; + + virtual void light_set_color(RID p_light, const Color &p_color) override; + virtual void light_set_param(RID p_light, RS::LightParam p_param, float p_value) override; + virtual void light_set_shadow(RID p_light, bool p_enabled) override; + virtual void light_set_projector(RID p_light, RID p_texture) override; + virtual void light_set_negative(RID p_light, bool p_enable) override; + virtual void light_set_cull_mask(RID p_light, uint32_t p_mask) override; + virtual void light_set_distance_fade(RID p_light, bool p_enabled, float p_begin, float p_shadow, float p_length) override; + virtual void light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) override; + virtual void light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode) override; + virtual void light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) override; + + virtual void light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) override; + + virtual void light_directional_set_shadow_mode(RID p_light, RS::LightDirectionalShadowMode p_mode) override; + virtual void light_directional_set_blend_splits(RID p_light, bool p_enable) override; + virtual bool light_directional_get_blend_splits(RID p_light) const override; + virtual void light_directional_set_sky_mode(RID p_light, RS::LightDirectionalSkyMode p_mode) override; + virtual RS::LightDirectionalSkyMode light_directional_get_sky_mode(RID p_light) const override; + + virtual RS::LightDirectionalShadowMode light_directional_get_shadow_mode(RID p_light) override; + virtual RS::LightOmniShadowMode light_omni_get_shadow_mode(RID p_light) override; + + virtual bool light_has_shadow(RID p_light) const override; + virtual bool light_has_projector(RID p_light) const override; + + virtual RS::LightType light_get_type(RID p_light) const override; + virtual AABB light_get_aabb(RID p_light) const override; + virtual float light_get_param(RID p_light, RS::LightParam p_param) override; + virtual Color light_get_color(RID p_light) override; + virtual RS::LightBakeMode light_get_bake_mode(RID p_light) override; + virtual uint32_t light_get_max_sdfgi_cascade(RID p_light) override; + virtual uint64_t light_get_version(RID p_light) const override; + + /* PROBE API */ + + virtual RID reflection_probe_allocate() override; + virtual void reflection_probe_initialize(RID p_rid) override; + virtual void reflection_probe_free(RID p_rid) override; + + virtual void reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) override; + virtual void reflection_probe_set_intensity(RID p_probe, float p_intensity) override; + virtual void reflection_probe_set_ambient_mode(RID p_probe, RS::ReflectionProbeAmbientMode p_mode) override; + virtual void reflection_probe_set_ambient_color(RID p_probe, const Color &p_color) override; + virtual void reflection_probe_set_ambient_energy(RID p_probe, float p_energy) override; + virtual void reflection_probe_set_max_distance(RID p_probe, float p_distance) override; + virtual void reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) override; + virtual void reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) override; + virtual void reflection_probe_set_as_interior(RID p_probe, bool p_enable) override; + virtual void reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) override; + virtual void reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) override; + virtual void reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) override; + virtual void reflection_probe_set_resolution(RID p_probe, int p_resolution) override; + virtual void reflection_probe_set_mesh_lod_threshold(RID p_probe, float p_ratio) override; + virtual float reflection_probe_get_mesh_lod_threshold(RID p_probe) const override; + + virtual AABB reflection_probe_get_aabb(RID p_probe) const override; + virtual RS::ReflectionProbeUpdateMode reflection_probe_get_update_mode(RID p_probe) const override; + virtual uint32_t reflection_probe_get_cull_mask(RID p_probe) const override; + virtual Vector3 reflection_probe_get_extents(RID p_probe) const override; + virtual Vector3 reflection_probe_get_origin_offset(RID p_probe) const override; + virtual float reflection_probe_get_origin_max_distance(RID p_probe) const override; + virtual bool reflection_probe_renders_shadows(RID p_probe) const override; + + /* LIGHTMAP CAPTURE */ + + virtual RID lightmap_allocate() override; + virtual void lightmap_initialize(RID p_rid) override; + virtual void lightmap_free(RID p_rid) override; + + virtual void lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) override; + virtual void lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) override; + virtual void lightmap_set_probe_interior(RID p_lightmap, bool p_interior) override; + virtual void lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) override; + virtual PackedVector3Array lightmap_get_probe_capture_points(RID p_lightmap) const override; + virtual PackedColorArray lightmap_get_probe_capture_sh(RID p_lightmap) const override; + virtual PackedInt32Array lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const override; + virtual PackedInt32Array lightmap_get_probe_capture_bsp_tree(RID p_lightmap) const override; + virtual AABB lightmap_get_aabb(RID p_lightmap) const override; + virtual void lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point, Color *r_sh) override; + virtual bool lightmap_is_interior(RID p_lightmap) const override; + virtual void lightmap_set_probe_capture_update_speed(float p_speed) override; + virtual float lightmap_get_probe_capture_update_speed() const override; +}; + +} // namespace GLES3 + +#endif // !GLES3_ENABLED + +#endif // !LIGHT_STORAGE_GLES3_H diff --git a/drivers/gles3/storage/material_storage.cpp b/drivers/gles3/storage/material_storage.cpp new file mode 100644 index 0000000000..0a2922fbd6 --- /dev/null +++ b/drivers/gles3/storage/material_storage.cpp @@ -0,0 +1,914 @@ +/*************************************************************************/ +/* material_storage.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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. */ +/*************************************************************************/ + +#ifdef GLES3_ENABLED + +#include "material_storage.h" +#include "config.h" +#include "texture_storage.h" + +#include "drivers/gles3/rasterizer_canvas_gles3.h" + +using namespace GLES3; + +MaterialStorage *MaterialStorage::singleton = nullptr; + +MaterialStorage *MaterialStorage::get_singleton() { + return singleton; +} + +MaterialStorage::MaterialStorage() { + singleton = this; + + shaders.copy.initialize(); + shaders.copy_version = shaders.copy.version_create(); //TODO + shaders.copy.version_bind_shader(shaders.copy_version, CopyShaderGLES3::MODE_COPY_SECTION); + //shaders.cubemap_filter.init(); + //bool ggx_hq = GLOBAL_GET("rendering/quality/reflections/high_quality_ggx"); + //shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::LOW_QUALITY, !ggx_hq); +} + +MaterialStorage::~MaterialStorage() { + shaders.copy.version_free(shaders.copy_version); + + singleton = nullptr; +} + +/* GLOBAL VARIABLE API */ + +void MaterialStorage::global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) { +} + +void MaterialStorage::global_variable_remove(const StringName &p_name) { +} + +Vector<StringName> MaterialStorage::global_variable_get_list() const { + return Vector<StringName>(); +} + +void MaterialStorage::global_variable_set(const StringName &p_name, const Variant &p_value) { +} + +void MaterialStorage::global_variable_set_override(const StringName &p_name, const Variant &p_value) { +} + +Variant MaterialStorage::global_variable_get(const StringName &p_name) const { + return Variant(); +} + +RS::GlobalVariableType MaterialStorage::global_variable_get_type(const StringName &p_name) const { + return RS::GLOBAL_VAR_TYPE_MAX; +} + +void MaterialStorage::global_variables_load_settings(bool p_load_textures) { +} + +void MaterialStorage::global_variables_clear() { +} + +int32_t MaterialStorage::global_variables_instance_allocate(RID p_instance) { + return 0; +} + +void MaterialStorage::global_variables_instance_free(RID p_instance) { +} + +void MaterialStorage::global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) { +} + +/* SHADER API */ + +void MaterialStorage::_shader_make_dirty(GLES3::Shader *p_shader) { + if (p_shader->dirty_list.in_list()) { + return; + } + + _shader_dirty_list.add(&p_shader->dirty_list); +} + +RID MaterialStorage::shader_allocate() { + GLES3::Shader *shader = memnew(GLES3::Shader); + shader->mode = RS::SHADER_CANVAS_ITEM; + //shader->shader = &scene->state.scene_shader; + RID rid = shader_owner.make_rid(shader); + _shader_make_dirty(shader); + shader->self = rid; + + return rid; +} + +void MaterialStorage::shader_initialize(RID p_rid) { + // noop +} + +//RID MaterialStorage::shader_create() { +// GLES3::Shader *shader = memnew(GLES3::Shader); +// shader->mode = RS::SHADER_SPATIAL; +// shader->shader = &scene->state.scene_shader; +// RID rid = shader_owner.make_rid(shader); +// _shader_make_dirty(shader); +// shader->self = rid; + +// return rid; +//} + +void MaterialStorage::shader_free(RID p_rid) { + GLES3::Shader *shader = shader_owner.get_or_null(p_rid); + + if (shader->shader && shader->version.is_valid()) { + shader->shader->version_free(shader->version); + } + + if (shader->dirty_list.in_list()) { + _shader_dirty_list.remove(&shader->dirty_list); + } + + while (shader->materials.first()) { + GLES3::Material *m = shader->materials.first()->self(); + + m->shader = nullptr; + _material_make_dirty(m); + + shader->materials.remove(shader->materials.first()); + } + + shader_owner.free(p_rid); + memdelete(shader); +} + +void MaterialStorage::shader_set_code(RID p_shader, const String &p_code) { + GLES3::Shader *shader = shader_owner.get_or_null(p_shader); + ERR_FAIL_COND(!shader); + + shader->code = p_code; + + String mode_string = ShaderLanguage::get_shader_type(p_code); + RS::ShaderMode mode; + + if (mode_string == "canvas_item") { + mode = RS::SHADER_CANVAS_ITEM; + } else if (mode_string == "particles") { + mode = RS::SHADER_PARTICLES; + } else if (mode_string == "sky") { + mode = RS::SHADER_SKY; + } else if (mode_string == "spatial") { + mode = RS::SHADER_SPATIAL; + } else { + mode = RS::SHADER_MAX; + ERR_PRINT("shader type " + mode_string + " not supported in OpenGL renderer"); + } + + if (shader->version.is_valid() && mode != shader->mode) { + shader->shader->version_free(shader->version); + shader->version = RID(); + } + + shader->mode = mode; + + // TODO handle all shader types + if (mode == RS::SHADER_CANVAS_ITEM) { + shader->shader = &RasterizerCanvasGLES3::get_singleton()->state.canvas_shader; + } else if (mode == RS::SHADER_SPATIAL) { + //shader->shader = &scene->state.scene_shader; + } else if (mode == RS::SHADER_PARTICLES) { + } else if (mode == RS::SHADER_SKY) { + } else { + return; + } + + if (shader->version.is_null() && shader->shader) { + shader->version = shader->shader->version_create(); + } + + _shader_make_dirty(shader); +} + +String MaterialStorage::shader_get_code(RID p_shader) const { + const GLES3::Shader *shader = shader_owner.get_or_null(p_shader); + ERR_FAIL_COND_V(!shader, ""); + + return shader->code; +} + +void MaterialStorage::shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const { + GLES3::Shader *shader = shader_owner.get_or_null(p_shader); + ERR_FAIL_COND(!shader); + + if (shader->dirty_list.in_list()) { + _update_shader(shader); + } + + Map<int, StringName> order; + + for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = shader->uniforms.front(); E; E = E->next()) { + if (E->get().texture_order >= 0) { + order[E->get().texture_order + 100000] = E->key(); + } else { + order[E->get().order] = E->key(); + } + } + + for (Map<int, StringName>::Element *E = order.front(); E; E = E->next()) { + PropertyInfo pi; + ShaderLanguage::ShaderNode::Uniform &u = shader->uniforms[E->get()]; + + pi.name = E->get(); + + switch (u.type) { + case ShaderLanguage::TYPE_VOID: { + pi.type = Variant::NIL; + } break; + + case ShaderLanguage::TYPE_BOOL: { + pi.type = Variant::BOOL; + } break; + + // bool vectors + case ShaderLanguage::TYPE_BVEC2: { + pi.type = Variant::INT; + pi.hint = PROPERTY_HINT_FLAGS; + pi.hint_string = "x,y"; + } break; + case ShaderLanguage::TYPE_BVEC3: { + pi.type = Variant::INT; + pi.hint = PROPERTY_HINT_FLAGS; + pi.hint_string = "x,y,z"; + } break; + case ShaderLanguage::TYPE_BVEC4: { + pi.type = Variant::INT; + pi.hint = PROPERTY_HINT_FLAGS; + pi.hint_string = "x,y,z,w"; + } break; + + // int stuff + case ShaderLanguage::TYPE_UINT: + case ShaderLanguage::TYPE_INT: { + pi.type = Variant::INT; + + if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_RANGE) { + pi.hint = PROPERTY_HINT_RANGE; + pi.hint_string = rtos(u.hint_range[0]) + "," + rtos(u.hint_range[1]) + "," + rtos(u.hint_range[2]); + } + } break; + + case ShaderLanguage::TYPE_IVEC2: + case ShaderLanguage::TYPE_UVEC2: + case ShaderLanguage::TYPE_IVEC3: + case ShaderLanguage::TYPE_UVEC3: + case ShaderLanguage::TYPE_IVEC4: + case ShaderLanguage::TYPE_UVEC4: { + // not sure what this should be in godot 4 + // pi.type = Variant::POOL_INT_ARRAY; + pi.type = Variant::PACKED_INT32_ARRAY; + } break; + + case ShaderLanguage::TYPE_FLOAT: { + pi.type = Variant::FLOAT; + if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_RANGE) { + pi.hint = PROPERTY_HINT_RANGE; + pi.hint_string = rtos(u.hint_range[0]) + "," + rtos(u.hint_range[1]) + "," + rtos(u.hint_range[2]); + } + } break; + + case ShaderLanguage::TYPE_VEC2: { + pi.type = Variant::VECTOR2; + } break; + case ShaderLanguage::TYPE_VEC3: { + pi.type = Variant::VECTOR3; + } break; + + case ShaderLanguage::TYPE_VEC4: { + if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) { + pi.type = Variant::COLOR; + } else { + pi.type = Variant::QUATERNION; + } + } break; + + case ShaderLanguage::TYPE_MAT2: { + pi.type = Variant::TRANSFORM2D; + } break; + + case ShaderLanguage::TYPE_MAT3: { + pi.type = Variant::BASIS; + } break; + + case ShaderLanguage::TYPE_MAT4: { + pi.type = Variant::TRANSFORM3D; + } break; + + case ShaderLanguage::TYPE_SAMPLER2D: + // case ShaderLanguage::TYPE_SAMPLEREXT: + case ShaderLanguage::TYPE_ISAMPLER2D: + case ShaderLanguage::TYPE_USAMPLER2D: { + pi.type = Variant::OBJECT; + pi.hint = PROPERTY_HINT_RESOURCE_TYPE; + pi.hint_string = "Texture"; + } break; + + case ShaderLanguage::TYPE_SAMPLERCUBE: { + pi.type = Variant::OBJECT; + pi.hint = PROPERTY_HINT_RESOURCE_TYPE; + pi.hint_string = "CubeMap"; + } break; + + case ShaderLanguage::TYPE_SAMPLER2DARRAY: + case ShaderLanguage::TYPE_ISAMPLER2DARRAY: + case ShaderLanguage::TYPE_USAMPLER2DARRAY: + case ShaderLanguage::TYPE_SAMPLER3D: + case ShaderLanguage::TYPE_ISAMPLER3D: + case ShaderLanguage::TYPE_USAMPLER3D: { + // Not implemented in OpenGL + } break; + // new for godot 4 + case ShaderLanguage::TYPE_SAMPLERCUBEARRAY: + case ShaderLanguage::TYPE_STRUCT: + case ShaderLanguage::TYPE_MAX: { + } break; + } + + p_param_list->push_back(pi); + } +} + +void MaterialStorage::shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture, int p_index) { + GLES3::Shader *shader = shader_owner.get_or_null(p_shader); + ERR_FAIL_COND(!shader); + ERR_FAIL_COND(p_texture.is_valid() && !TextureStorage::get_singleton()->owns_texture(p_texture)); + + if (!p_texture.is_valid()) { + if (shader->default_textures.has(p_name) && shader->default_textures[p_name].has(p_index)) { + shader->default_textures[p_name].erase(p_index); + + if (shader->default_textures[p_name].is_empty()) { + shader->default_textures.erase(p_name); + } + } + } else { + if (!shader->default_textures.has(p_name)) { + shader->default_textures[p_name] = Map<int, RID>(); + } + shader->default_textures[p_name][p_index] = p_texture; + } + + _shader_make_dirty(shader); +} + +RID MaterialStorage::shader_get_default_texture_param(RID p_shader, const StringName &p_name, int p_index) const { + const GLES3::Shader *shader = shader_owner.get_or_null(p_shader); + ERR_FAIL_COND_V(!shader, RID()); + + if (shader->default_textures.has(p_name) && shader->default_textures[p_name].has(p_index)) { + return shader->default_textures[p_name][p_index]; + } + + return RID(); +} + +void MaterialStorage::_update_shader(GLES3::Shader *p_shader) const { + _shader_dirty_list.remove(&p_shader->dirty_list); + + p_shader->valid = false; + + p_shader->uniforms.clear(); + + if (p_shader->code.is_empty()) { + return; //just invalid, but no error + } + + ShaderCompiler::GeneratedCode gen_code; + ShaderCompiler::IdentifierActions *actions = nullptr; + + switch (p_shader->mode) { + case RS::SHADER_CANVAS_ITEM: { + p_shader->canvas_item.light_mode = GLES3::Shader::CanvasItem::LIGHT_MODE_NORMAL; + p_shader->canvas_item.blend_mode = GLES3::Shader::CanvasItem::BLEND_MODE_MIX; + + p_shader->canvas_item.uses_screen_texture = false; + p_shader->canvas_item.uses_screen_uv = false; + p_shader->canvas_item.uses_time = false; + p_shader->canvas_item.uses_modulate = false; + p_shader->canvas_item.uses_color = false; + p_shader->canvas_item.uses_vertex = false; + + p_shader->canvas_item.uses_model_matrix = false; + p_shader->canvas_item.uses_extra_matrix = false; + p_shader->canvas_item.uses_projection_matrix = false; + p_shader->canvas_item.uses_instance_custom = false; + + shaders.actions_canvas.render_mode_values["blend_add"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, GLES3::Shader::CanvasItem::BLEND_MODE_ADD); + shaders.actions_canvas.render_mode_values["blend_mix"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, GLES3::Shader::CanvasItem::BLEND_MODE_MIX); + shaders.actions_canvas.render_mode_values["blend_sub"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, GLES3::Shader::CanvasItem::BLEND_MODE_SUB); + shaders.actions_canvas.render_mode_values["blend_mul"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, GLES3::Shader::CanvasItem::BLEND_MODE_MUL); + shaders.actions_canvas.render_mode_values["blend_premul_alpha"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, GLES3::Shader::CanvasItem::BLEND_MODE_PMALPHA); + + shaders.actions_canvas.render_mode_values["unshaded"] = Pair<int *, int>(&p_shader->canvas_item.light_mode, GLES3::Shader::CanvasItem::LIGHT_MODE_UNSHADED); + shaders.actions_canvas.render_mode_values["light_only"] = Pair<int *, int>(&p_shader->canvas_item.light_mode, GLES3::Shader::CanvasItem::LIGHT_MODE_LIGHT_ONLY); + + shaders.actions_canvas.usage_flag_pointers["SCREEN_UV"] = &p_shader->canvas_item.uses_screen_uv; + shaders.actions_canvas.usage_flag_pointers["SCREEN_PIXEL_SIZE"] = &p_shader->canvas_item.uses_screen_uv; + shaders.actions_canvas.usage_flag_pointers["SCREEN_TEXTURE"] = &p_shader->canvas_item.uses_screen_texture; + shaders.actions_canvas.usage_flag_pointers["TIME"] = &p_shader->canvas_item.uses_time; + shaders.actions_canvas.usage_flag_pointers["MODULATE"] = &p_shader->canvas_item.uses_modulate; + shaders.actions_canvas.usage_flag_pointers["COLOR"] = &p_shader->canvas_item.uses_color; + + shaders.actions_canvas.usage_flag_pointers["VERTEX"] = &p_shader->canvas_item.uses_vertex; + + shaders.actions_canvas.usage_flag_pointers["MODEL_MATRIX"] = &p_shader->canvas_item.uses_model_matrix; + shaders.actions_canvas.usage_flag_pointers["EXTRA_MATRIX"] = &p_shader->canvas_item.uses_extra_matrix; + shaders.actions_canvas.usage_flag_pointers["PROJECTION_MATRIX"] = &p_shader->canvas_item.uses_projection_matrix; + shaders.actions_canvas.usage_flag_pointers["INSTANCE_CUSTOM"] = &p_shader->canvas_item.uses_instance_custom; + + actions = &shaders.actions_canvas; + actions->uniforms = &p_shader->uniforms; + } break; + + case RS::SHADER_SPATIAL: { + // TODO remove once 3D is added back + return; + p_shader->spatial.blend_mode = GLES3::Shader::Spatial::BLEND_MODE_MIX; + p_shader->spatial.depth_draw_mode = GLES3::Shader::Spatial::DEPTH_DRAW_OPAQUE; + p_shader->spatial.cull_mode = GLES3::Shader::Spatial::CULL_MODE_BACK; + p_shader->spatial.uses_alpha = false; + p_shader->spatial.uses_alpha_scissor = false; + p_shader->spatial.uses_discard = false; + p_shader->spatial.unshaded = false; + p_shader->spatial.no_depth_test = false; + p_shader->spatial.uses_sss = false; + p_shader->spatial.uses_time = false; + p_shader->spatial.uses_vertex_lighting = false; + p_shader->spatial.uses_screen_texture = false; + p_shader->spatial.uses_depth_texture = false; + p_shader->spatial.uses_vertex = false; + p_shader->spatial.uses_tangent = false; + p_shader->spatial.uses_ensure_correct_normals = false; + p_shader->spatial.writes_modelview_or_projection = false; + p_shader->spatial.uses_world_coordinates = false; + + shaders.actions_scene.render_mode_values["blend_add"] = Pair<int *, int>(&p_shader->spatial.blend_mode, GLES3::Shader::Spatial::BLEND_MODE_ADD); + shaders.actions_scene.render_mode_values["blend_mix"] = Pair<int *, int>(&p_shader->spatial.blend_mode, GLES3::Shader::Spatial::BLEND_MODE_MIX); + shaders.actions_scene.render_mode_values["blend_sub"] = Pair<int *, int>(&p_shader->spatial.blend_mode, GLES3::Shader::Spatial::BLEND_MODE_SUB); + shaders.actions_scene.render_mode_values["blend_mul"] = Pair<int *, int>(&p_shader->spatial.blend_mode, GLES3::Shader::Spatial::BLEND_MODE_MUL); + + shaders.actions_scene.render_mode_values["depth_draw_opaque"] = Pair<int *, int>(&p_shader->spatial.depth_draw_mode, GLES3::Shader::Spatial::DEPTH_DRAW_OPAQUE); + shaders.actions_scene.render_mode_values["depth_draw_always"] = Pair<int *, int>(&p_shader->spatial.depth_draw_mode, GLES3::Shader::Spatial::DEPTH_DRAW_ALWAYS); + shaders.actions_scene.render_mode_values["depth_draw_never"] = Pair<int *, int>(&p_shader->spatial.depth_draw_mode, GLES3::Shader::Spatial::DEPTH_DRAW_NEVER); + shaders.actions_scene.render_mode_values["depth_draw_alpha_prepass"] = Pair<int *, int>(&p_shader->spatial.depth_draw_mode, GLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS); + + shaders.actions_scene.render_mode_values["cull_front"] = Pair<int *, int>(&p_shader->spatial.cull_mode, GLES3::Shader::Spatial::CULL_MODE_FRONT); + shaders.actions_scene.render_mode_values["cull_back"] = Pair<int *, int>(&p_shader->spatial.cull_mode, GLES3::Shader::Spatial::CULL_MODE_BACK); + shaders.actions_scene.render_mode_values["cull_disabled"] = Pair<int *, int>(&p_shader->spatial.cull_mode, GLES3::Shader::Spatial::CULL_MODE_DISABLED); + + shaders.actions_scene.render_mode_flags["unshaded"] = &p_shader->spatial.unshaded; + shaders.actions_scene.render_mode_flags["depth_test_disable"] = &p_shader->spatial.no_depth_test; + + shaders.actions_scene.render_mode_flags["vertex_lighting"] = &p_shader->spatial.uses_vertex_lighting; + + shaders.actions_scene.render_mode_flags["world_vertex_coords"] = &p_shader->spatial.uses_world_coordinates; + + shaders.actions_scene.render_mode_flags["ensure_correct_normals"] = &p_shader->spatial.uses_ensure_correct_normals; + + shaders.actions_scene.usage_flag_pointers["ALPHA"] = &p_shader->spatial.uses_alpha; + shaders.actions_scene.usage_flag_pointers["ALPHA_SCISSOR"] = &p_shader->spatial.uses_alpha_scissor; + + shaders.actions_scene.usage_flag_pointers["SSS_STRENGTH"] = &p_shader->spatial.uses_sss; + shaders.actions_scene.usage_flag_pointers["DISCARD"] = &p_shader->spatial.uses_discard; + shaders.actions_scene.usage_flag_pointers["SCREEN_TEXTURE"] = &p_shader->spatial.uses_screen_texture; + shaders.actions_scene.usage_flag_pointers["DEPTH_TEXTURE"] = &p_shader->spatial.uses_depth_texture; + shaders.actions_scene.usage_flag_pointers["TIME"] = &p_shader->spatial.uses_time; + + // Use of any of these BUILTINS indicate the need for transformed tangents. + // This is needed to know when to transform tangents in software skinning. + shaders.actions_scene.usage_flag_pointers["TANGENT"] = &p_shader->spatial.uses_tangent; + shaders.actions_scene.usage_flag_pointers["NORMALMAP"] = &p_shader->spatial.uses_tangent; + + shaders.actions_scene.write_flag_pointers["MODELVIEW_MATRIX"] = &p_shader->spatial.writes_modelview_or_projection; + shaders.actions_scene.write_flag_pointers["PROJECTION_MATRIX"] = &p_shader->spatial.writes_modelview_or_projection; + shaders.actions_scene.write_flag_pointers["VERTEX"] = &p_shader->spatial.uses_vertex; + + actions = &shaders.actions_scene; + actions->uniforms = &p_shader->uniforms; + } break; + + default: { + return; + } break; + } + + Error err = shaders.compiler.compile(p_shader->mode, p_shader->code, actions, p_shader->path, gen_code); + if (err != OK) { + return; + } + + Vector<StringName> texture_uniform_names; + for (int i = 0; i < gen_code.texture_uniforms.size(); i++) { + texture_uniform_names.push_back(gen_code.texture_uniforms[i].name); + } + + p_shader->shader->version_set_code(p_shader->version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX], gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT], gen_code.defines, texture_uniform_names); + + p_shader->texture_uniforms = gen_code.texture_uniforms; + + p_shader->uses_vertex_time = gen_code.uses_vertex_time; + p_shader->uses_fragment_time = gen_code.uses_fragment_time; + + for (SelfList<GLES3::Material> *E = p_shader->materials.first(); E; E = E->next()) { + _material_make_dirty(E->self()); + } + + p_shader->valid = true; +} + +void MaterialStorage::update_dirty_shaders() { + while (_shader_dirty_list.first()) { + _update_shader(_shader_dirty_list.first()->self()); + } +} + +/* MATERIAL API */ + +void MaterialStorage::_material_make_dirty(GLES3::Material *p_material) const { + if (p_material->dirty_list.in_list()) { + return; + } + + _material_dirty_list.add(&p_material->dirty_list); +} + +void MaterialStorage::_update_material(GLES3::Material *p_material) { + if (p_material->dirty_list.in_list()) { + _material_dirty_list.remove(&p_material->dirty_list); + } + + if (p_material->shader && p_material->shader->dirty_list.in_list()) { + _update_shader(p_material->shader); + } + + if (p_material->shader && !p_material->shader->valid) { + return; + } + + { + if (p_material->shader && p_material->shader->mode == RS::SHADER_SPATIAL) { + bool can_cast_shadow = false; + bool is_animated = false; + + if (p_material->shader->spatial.blend_mode == GLES3::Shader::Spatial::BLEND_MODE_MIX && + + (!p_material->shader->spatial.uses_alpha || p_material->shader->spatial.depth_draw_mode == Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS)) { + can_cast_shadow = true; + } + + if (p_material->shader->spatial.uses_discard && p_material->shader->uses_fragment_time) { + is_animated = true; + } + + if (p_material->shader->spatial.uses_vertex && p_material->shader->uses_vertex_time) { + is_animated = true; + } + + if (can_cast_shadow != p_material->can_cast_shadow_cache || is_animated != p_material->is_animated_cache) { + p_material->can_cast_shadow_cache = can_cast_shadow; + p_material->is_animated_cache = is_animated; + + /* + for (Map<Geometry *, int>::Element *E = p_material->geometry_owners.front(); E; E = E->next()) { + E->key()->material_changed_notify(); + } + + for (Map<InstanceBaseDependency *, int>::Element *E = p_material->instance_owners.front(); E; E = E->next()) { + E->key()->base_changed(false, true); + } + */ + } + } + } + + // uniforms and other things will be set in the use_material method in ShaderGLES3 + + if (p_material->shader && p_material->shader->texture_uniforms.size() > 0) { + p_material->textures.resize(p_material->shader->texture_uniforms.size()); + + for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = p_material->shader->uniforms.front(); E; E = E->next()) { + if (E->get().texture_order < 0) { + continue; // not a texture, does not go here + } + + RID texture; + + Map<StringName, Variant>::Element *V = p_material->params.find(E->key()); + + if (V) { + texture = V->get(); + } + + if (!texture.is_valid()) { + Map<StringName, Map<int, RID>>::Element *W = p_material->shader->default_textures.find(E->key()); + + // TODO: make texture uniform array properly works with GLES3 + if (W && W->get().has(0)) { + texture = W->get()[0]; + } + } + + p_material->textures.write[E->get().texture_order] = Pair<StringName, RID>(E->key(), texture); + } + } else { + p_material->textures.clear(); + } +} + +RID MaterialStorage::material_allocate() { + GLES3::Material *material = memnew(GLES3::Material); + return material_owner.make_rid(material); +} + +void MaterialStorage::material_initialize(RID p_rid) { +} + +//RID MaterialStorage::material_create() { +// Material *material = memnew(Material); + +// return material_owner.make_rid(material); +//} + +void MaterialStorage::material_free(RID p_rid) { + GLES3::Material *m = material_owner.get_or_null(p_rid); + + if (m->shader) { + m->shader->materials.remove(&m->list); + } + + /* + for (Map<Geometry *, int>::Element *E = m->geometry_owners.front(); E; E = E->next()) { + Geometry *g = E->key(); + g->material = RID(); + } + + for (Map<InstanceBaseDependency *, int>::Element *E = m->instance_owners.front(); E; E = E->next()) { + InstanceBaseDependency *ins = E->key(); + + if (ins->material_override == p_rid) { + ins->material_override = RID(); + } + + for (int i = 0; i < ins->materials.size(); i++) { + if (ins->materials[i] == p_rid) { + ins->materials.write[i] = RID(); + } + } + } +*/ + + material_owner.free(p_rid); + memdelete(m); +} + +void MaterialStorage::material_set_shader(RID p_material, RID p_shader) { + GLES3::Material *material = material_owner.get_or_null(p_material); + ERR_FAIL_COND(!material); + + GLES3::Shader *shader = get_shader(p_shader); + + if (material->shader) { + // if a shader is present, remove the old shader + material->shader->materials.remove(&material->list); + } + + material->shader = shader; + + if (shader) { + shader->materials.add(&material->list); + } + + _material_make_dirty(material); +} + +void MaterialStorage::material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) { + GLES3::Material *material = material_owner.get_or_null(p_material); + ERR_FAIL_COND(!material); + + if (p_value.get_type() == Variant::NIL) { + material->params.erase(p_param); + } else { + material->params[p_param] = p_value; + } + + _material_make_dirty(material); +} + +Variant MaterialStorage::material_get_param(RID p_material, const StringName &p_param) const { + const GLES3::Material *material = material_owner.get_or_null(p_material); + ERR_FAIL_COND_V(!material, RID()); + + if (material->params.has(p_param)) { + return material->params[p_param]; + } + + return material_get_param_default(p_material, p_param); +} + +void MaterialStorage::material_set_next_pass(RID p_material, RID p_next_material) { + GLES3::Material *material = material_owner.get_or_null(p_material); + ERR_FAIL_COND(!material); + + material->next_pass = p_next_material; +} + +void MaterialStorage::material_set_render_priority(RID p_material, int priority) { + ERR_FAIL_COND(priority < RS::MATERIAL_RENDER_PRIORITY_MIN); + ERR_FAIL_COND(priority > RS::MATERIAL_RENDER_PRIORITY_MAX); + + GLES3::Material *material = material_owner.get_or_null(p_material); + ERR_FAIL_COND(!material); + + material->render_priority = priority; +} + +bool MaterialStorage::material_is_animated(RID p_material) { + GLES3::Material *material = material_owner.get_or_null(p_material); + ERR_FAIL_COND_V(!material, false); + if (material->dirty_list.in_list()) { + _update_material(material); + } + + bool animated = material->is_animated_cache; + if (!animated && material->next_pass.is_valid()) { + animated = material_is_animated(material->next_pass); + } + return animated; +} + +bool MaterialStorage::material_casts_shadows(RID p_material) { + GLES3::Material *material = material_owner.get_or_null(p_material); + ERR_FAIL_COND_V(!material, false); + if (material->dirty_list.in_list()) { + _update_material(material); + } + + bool casts_shadows = material->can_cast_shadow_cache; + + if (!casts_shadows && material->next_pass.is_valid()) { + casts_shadows = material_casts_shadows(material->next_pass); + } + + return casts_shadows; +} + +Variant MaterialStorage::material_get_param_default(RID p_material, const StringName &p_param) const { + const GLES3::Material *material = material_owner.get_or_null(p_material); + ERR_FAIL_COND_V(!material, Variant()); + + if (material->shader) { + if (material->shader->uniforms.has(p_param)) { + ShaderLanguage::ShaderNode::Uniform uniform = material->shader->uniforms[p_param]; + Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value; + return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.hint); + } + } + return Variant(); +} + +void MaterialStorage::update_dirty_materials() { + while (_material_dirty_list.first()) { + GLES3::Material *material = _material_dirty_list.first()->self(); + _update_material(material); + } +} + +/* are these still used? */ +RID MaterialStorage::material_get_shader(RID p_material) const { + const GLES3::Material *material = material_owner.get_or_null(p_material); + ERR_FAIL_COND_V(!material, RID()); + + if (material->shader) { + return material->shader->self; + } + + return RID(); +} + +void MaterialStorage::material_set_line_width(RID p_material, float p_width) { + GLES3::Material *material = material_owner.get_or_null(p_material); + ERR_FAIL_COND(!material); + + material->line_width = p_width; +} + +bool MaterialStorage::material_uses_tangents(RID p_material) { + GLES3::Material *material = material_owner.get_or_null(p_material); + ERR_FAIL_COND_V(!material, false); + + if (!material->shader) { + return false; + } + + if (material->shader->dirty_list.in_list()) { + _update_shader(material->shader); + } + + return material->shader->spatial.uses_tangent; +} + +bool MaterialStorage::material_uses_ensure_correct_normals(RID p_material) { + GLES3::Material *material = material_owner.get_or_null(p_material); + ERR_FAIL_COND_V(!material, false); + + if (!material->shader) { + return false; + } + + if (material->shader->dirty_list.in_list()) { + _update_shader(material->shader); + } + + return material->shader->spatial.uses_ensure_correct_normals; +} + +void MaterialStorage::material_add_instance_owner(RID p_material, RendererStorage::DependencyTracker *p_instance) { + /* + GLES3::Material *material = material_owner.get_or_null(p_material); + ERR_FAIL_COND(!material); + + Map<InstanceBaseDependency *, int>::Element *E = material->instance_owners.find(p_instance); + if (E) { + E->get()++; + } else { + material->instance_owners[p_instance] = 1; + } +*/ +} + +void MaterialStorage::material_remove_instance_owner(RID p_material, RendererStorage::DependencyTracker *p_instance) { + /* + GLES3::Material *material = material_owner.get_or_null(p_material); + ERR_FAIL_COND(!material); + + Map<InstanceBaseDependency *, int>::Element *E = material->instance_owners.find(p_instance); + ERR_FAIL_COND(!E); + + E->get()--; + + if (E->get() == 0) { + material->instance_owners.erase(E); + } +*/ +} + +/* +void MaterialStorage::_material_add_geometry(RID p_material, Geometry *p_geometry) { + GLES3::Material *material = material_owner.get_or_null(p_material); + ERR_FAIL_COND(!material); + + Map<Geometry *, int>::Element *I = material->geometry_owners.find(p_geometry); + + if (I) { + I->get()++; + } else { + material->geometry_owners[p_geometry] = 1; + } +} + +void MaterialStorage::_material_remove_geometry(RID p_material, Geometry *p_geometry) { + GLES3::Material *material = material_owner.get_or_null(p_material); + ERR_FAIL_COND(!material); + + Map<Geometry *, int>::Element *I = material->geometry_owners.find(p_geometry); + ERR_FAIL_COND(!I); + + I->get()--; + + if (I->get() == 0) { + material->geometry_owners.erase(I); + } +} +*/ + +#endif // !GLES3_ENABLED diff --git a/drivers/gles3/storage/material_storage.h b/drivers/gles3/storage/material_storage.h new file mode 100644 index 0000000000..450ee7191f --- /dev/null +++ b/drivers/gles3/storage/material_storage.h @@ -0,0 +1,338 @@ +/*************************************************************************/ +/* material_storage.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 MATERIAL_STORAGE_GLES3_H +#define MATERIAL_STORAGE_GLES3_H + +#ifdef GLES3_ENABLED + +#include "core/templates/local_vector.h" +#include "core/templates/rid_owner.h" +#include "core/templates/self_list.h" +#include "servers/rendering/renderer_compositor.h" +#include "servers/rendering/renderer_storage.h" +#include "servers/rendering/shader_compiler.h" +#include "servers/rendering/shader_language.h" +#include "servers/rendering/storage/material_storage.h" + +#include "drivers/gles3/shaders/copy.glsl.gen.h" + +namespace GLES3 { + +/* SHADER Structs */ + +struct Shaders { + ShaderCompiler compiler; + + CopyShaderGLES3 copy; + RID copy_version; + //CubemapFilterShaderGLES3 cubemap_filter; + + ShaderCompiler::IdentifierActions actions_canvas; + ShaderCompiler::IdentifierActions actions_scene; + ShaderCompiler::IdentifierActions actions_particles; +}; + +struct Material; + +struct Shader { + RID self; + + RS::ShaderMode mode; + ShaderGLES3 *shader = nullptr; + String code; + SelfList<Material>::List materials; + + Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; + + RID version; + + SelfList<Shader> dirty_list; + + Map<StringName, Map<int, RID>> default_textures; + + Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms; + + bool valid; + + String path; + + uint32_t index; + uint64_t last_pass; + + struct CanvasItem { + enum BlendMode { + BLEND_MODE_MIX, + BLEND_MODE_ADD, + BLEND_MODE_SUB, + BLEND_MODE_MUL, + BLEND_MODE_PMALPHA, + }; + + int blend_mode; + + enum LightMode { + LIGHT_MODE_NORMAL, + LIGHT_MODE_UNSHADED, + LIGHT_MODE_LIGHT_ONLY + }; + + int light_mode; + + bool uses_screen_texture; + bool uses_screen_uv; + bool uses_time; + bool uses_modulate; + bool uses_color; + bool uses_vertex; + + // all these should disable item joining if used in a custom shader + bool uses_model_matrix; + bool uses_extra_matrix; + bool uses_projection_matrix; + bool uses_instance_custom; + + } canvas_item; + + struct Spatial { + enum BlendMode { + BLEND_MODE_MIX, + BLEND_MODE_ADD, + BLEND_MODE_SUB, + BLEND_MODE_MUL, + }; + + int blend_mode; + + enum DepthDrawMode { + DEPTH_DRAW_OPAQUE, + DEPTH_DRAW_ALWAYS, + DEPTH_DRAW_NEVER, + DEPTH_DRAW_ALPHA_PREPASS, + }; + + int depth_draw_mode; + + enum CullMode { + CULL_MODE_FRONT, + CULL_MODE_BACK, + CULL_MODE_DISABLED, + }; + + int cull_mode; + + bool uses_alpha; + bool uses_alpha_scissor; + bool unshaded; + bool no_depth_test; + bool uses_vertex; + bool uses_discard; + bool uses_sss; + bool uses_screen_texture; + bool uses_depth_texture; + bool uses_time; + bool uses_tangent; + bool uses_ensure_correct_normals; + bool writes_modelview_or_projection; + bool uses_vertex_lighting; + bool uses_world_coordinates; + + } spatial; + + struct Particles { + } particles; + + bool uses_vertex_time; + bool uses_fragment_time; + + Shader() : + dirty_list(this) { + shader = nullptr; + valid = false; + version = RID(); + last_pass = 0; + } +}; + +/* MATERIAL Structs */ + +struct Material { + RID self; + Shader *shader = nullptr; + Map<StringName, Variant> params; + SelfList<Material> list; + SelfList<Material> dirty_list; + Vector<Pair<StringName, RID>> textures; + float line_width; + int render_priority; + + RID next_pass; + + uint32_t index; + uint64_t last_pass; + + // Map<Geometry *, int> geometry_owners; + // Map<InstanceBaseDependency *, int> instance_owners; + + bool can_cast_shadow_cache; + bool is_animated_cache; + + Material() : + list(this), + dirty_list(this) { + can_cast_shadow_cache = false; + is_animated_cache = false; + shader = nullptr; + line_width = 1.0; + last_pass = 0; + render_priority = 0; + } +}; + +class MaterialStorage : public RendererMaterialStorage { +private: + static MaterialStorage *singleton; + + /* SHADER API */ + + mutable Shaders shaders; + + mutable RID_PtrOwner<Shader> shader_owner; + mutable SelfList<Shader>::List _shader_dirty_list; + + /* MATERIAL API */ + + mutable SelfList<Material>::List _material_dirty_list; + mutable RID_PtrOwner<Material> material_owner; + +public: + static MaterialStorage *get_singleton(); + + MaterialStorage(); + virtual ~MaterialStorage(); + + /* GLOBAL VARIABLE API */ + + virtual void global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) override; + virtual void global_variable_remove(const StringName &p_name) override; + virtual Vector<StringName> global_variable_get_list() const override; + + virtual void global_variable_set(const StringName &p_name, const Variant &p_value) override; + virtual void global_variable_set_override(const StringName &p_name, const Variant &p_value) override; + virtual Variant global_variable_get(const StringName &p_name) const override; + virtual RS::GlobalVariableType global_variable_get_type(const StringName &p_name) const override; + + virtual void global_variables_load_settings(bool p_load_textures = true) override; + virtual void global_variables_clear() override; + + virtual int32_t global_variables_instance_allocate(RID p_instance) override; + virtual void global_variables_instance_free(RID p_instance) override; + virtual void global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) override; + + /* SHADER API */ + + Shader *get_shader(RID p_rid) { return shader_owner.get_or_null(p_rid); }; + bool owns_shader(RID p_rid) { return shader_owner.owns(p_rid); }; + + void _shader_make_dirty(Shader *p_shader); + + virtual RID shader_allocate() override; + virtual void shader_initialize(RID p_rid) override; + virtual void shader_free(RID p_rid) override; + + //RID shader_create() override; + + virtual void shader_set_code(RID p_shader, const String &p_code) override; + virtual String shader_get_code(RID p_shader) const override; + virtual void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const override; + + virtual void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture, int p_index) override; + virtual RID shader_get_default_texture_param(RID p_shader, const StringName &p_name, int p_index) const override; + + virtual RS::ShaderNativeSourceCode shader_get_native_source_code(RID p_shader) const override { return RS::ShaderNativeSourceCode(); }; + + void _update_shader(Shader *p_shader) const; + void update_dirty_shaders(); + + // new + Variant shader_get_param_default(RID p_material, const StringName &p_param) const override { return Variant(); } + + /* MATERIAL API */ + + Material *get_material(RID p_rid) { return material_owner.get_or_null(p_rid); }; + bool owns_material(RID p_rid) { return material_owner.owns(p_rid); }; + + void _material_make_dirty(Material *p_material) const; + + // void _material_add_geometry(RID p_material, Geometry *p_geometry); + // void _material_remove_geometry(RID p_material, Geometry *p_geometry); + + void _update_material(Material *p_material); + + // new + virtual void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) override {} + virtual void material_update_dependency(RID p_material, RendererStorage::DependencyTracker *p_instance) override {} + + // old + virtual RID material_allocate() override; + virtual void material_initialize(RID p_rid) override; + + virtual void material_free(RID p_rid) override; + + //RID material_create() override; + + virtual void material_set_shader(RID p_material, RID p_shader) override; + virtual RID material_get_shader(RID p_material) const; + + virtual void material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) override; + virtual Variant material_get_param(RID p_material, const StringName &p_param) const override; + virtual Variant material_get_param_default(RID p_material, const StringName &p_param) const; + + void material_set_line_width(RID p_material, float p_width); + virtual void material_set_next_pass(RID p_material, RID p_next_material) override; + + virtual bool material_is_animated(RID p_material) override; + virtual bool material_casts_shadows(RID p_material) override; + bool material_uses_tangents(RID p_material); + bool material_uses_ensure_correct_normals(RID p_material); + + void material_add_instance_owner(RID p_material, RendererStorage::DependencyTracker *p_instance); + void material_remove_instance_owner(RID p_material, RendererStorage::DependencyTracker *p_instance); + + void material_set_render_priority(RID p_material, int priority) override; + + void update_dirty_materials(); +}; + +} // namespace GLES3 + +#endif // GLES3_ENABLED + +#endif // !MATERIAL_STORAGE_GLES3_H diff --git a/drivers/gles3/storage/mesh_storage.cpp b/drivers/gles3/storage/mesh_storage.cpp new file mode 100644 index 0000000000..c2a431aff1 --- /dev/null +++ b/drivers/gles3/storage/mesh_storage.cpp @@ -0,0 +1,257 @@ +/*************************************************************************/ +/* mesh_storage.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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. */ +/*************************************************************************/ + +#ifdef GLES3_ENABLED + +#include "mesh_storage.h" + +using namespace GLES3; + +MeshStorage *MeshStorage::singleton = nullptr; + +MeshStorage *MeshStorage::get_singleton() { + return singleton; +} + +MeshStorage::MeshStorage() { + singleton = this; +} + +MeshStorage::~MeshStorage() { + singleton = nullptr; +} + +/* MESH API */ + +RID MeshStorage::mesh_allocate() { + return RID(); +} + +void MeshStorage::mesh_initialize(RID p_rid) { +} + +void MeshStorage::mesh_free(RID p_rid) { +} + +void MeshStorage::mesh_set_blend_shape_count(RID p_mesh, int p_blend_shape_count) { +} + +bool MeshStorage::mesh_needs_instance(RID p_mesh, bool p_has_skeleton) { + return false; +} + +void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) { +} + +int MeshStorage::mesh_get_blend_shape_count(RID p_mesh) const { + return 0; +} + +void MeshStorage::mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMode p_mode) { +} + +RS::BlendShapeMode MeshStorage::mesh_get_blend_shape_mode(RID p_mesh) const { + return RS::BLEND_SHAPE_MODE_NORMALIZED; +} + +void MeshStorage::mesh_surface_update_vertex_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) { +} + +void MeshStorage::mesh_surface_update_attribute_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) { +} + +void MeshStorage::mesh_surface_update_skin_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) { +} + +void MeshStorage::mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) { +} + +RID MeshStorage::mesh_surface_get_material(RID p_mesh, int p_surface) const { + return RID(); +} + +RS::SurfaceData MeshStorage::mesh_get_surface(RID p_mesh, int p_surface) const { + return RS::SurfaceData(); +} + +int MeshStorage::mesh_get_surface_count(RID p_mesh) const { + return 1; +} + +void MeshStorage::mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) { +} + +AABB MeshStorage::mesh_get_custom_aabb(RID p_mesh) const { + return AABB(); +} + +AABB MeshStorage::mesh_get_aabb(RID p_mesh, RID p_skeleton) { + return AABB(); +} + +void MeshStorage::mesh_set_shadow_mesh(RID p_mesh, RID p_shadow_mesh) { +} + +void MeshStorage::mesh_clear(RID p_mesh) { +} + +/* MESH INSTANCE API */ + +RID MeshStorage::mesh_instance_create(RID p_base) { + return RID(); +} + +void MeshStorage::mesh_instance_free(RID p_rid) { +} + +void MeshStorage::mesh_instance_set_skeleton(RID p_mesh_instance, RID p_skeleton) { +} + +void MeshStorage::mesh_instance_set_blend_shape_weight(RID p_mesh_instance, int p_shape, float p_weight) { +} + +void MeshStorage::mesh_instance_check_for_update(RID p_mesh_instance) { +} + +void MeshStorage::update_mesh_instances() { +} + +/* MULTIMESH API */ + +RID MeshStorage::multimesh_allocate() { + return RID(); +} + +void MeshStorage::multimesh_initialize(RID p_rid) { +} + +void MeshStorage::multimesh_free(RID p_rid) { +} + +void MeshStorage::multimesh_allocate_data(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors, bool p_use_custom_data) { +} + +int MeshStorage::multimesh_get_instance_count(RID p_multimesh) const { + return 0; +} + +void MeshStorage::multimesh_set_mesh(RID p_multimesh, RID p_mesh) { +} + +void MeshStorage::multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform3D &p_transform) { +} + +void MeshStorage::multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform) { +} + +void MeshStorage::multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) { +} + +void MeshStorage::multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_color) { +} + +RID MeshStorage::multimesh_get_mesh(RID p_multimesh) const { + return RID(); +} + +AABB MeshStorage::multimesh_get_aabb(RID p_multimesh) const { + return AABB(); +} + +Transform3D MeshStorage::multimesh_instance_get_transform(RID p_multimesh, int p_index) const { + return Transform3D(); +} + +Transform2D MeshStorage::multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const { + return Transform2D(); +} + +Color MeshStorage::multimesh_instance_get_color(RID p_multimesh, int p_index) const { + return Color(); +} + +Color MeshStorage::multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const { + return Color(); +} + +void MeshStorage::multimesh_set_buffer(RID p_multimesh, const Vector<float> &p_buffer) { +} + +Vector<float> MeshStorage::multimesh_get_buffer(RID p_multimesh) const { + return Vector<float>(); +} + +void MeshStorage::multimesh_set_visible_instances(RID p_multimesh, int p_visible) { +} + +int MeshStorage::multimesh_get_visible_instances(RID p_multimesh) const { + return 0; +} + +/* SKELETON API */ + +RID MeshStorage::skeleton_allocate() { + return RID(); +} + +void MeshStorage::skeleton_initialize(RID p_rid) { +} + +void MeshStorage::skeleton_free(RID p_rid) { +} + +void MeshStorage::skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_skeleton) { +} + +void MeshStorage::skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) { +} + +int MeshStorage::skeleton_get_bone_count(RID p_skeleton) const { + return 0; +} + +void MeshStorage::skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform3D &p_transform) { +} + +Transform3D MeshStorage::skeleton_bone_get_transform(RID p_skeleton, int p_bone) const { + return Transform3D(); +} + +void MeshStorage::skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) { +} + +Transform2D MeshStorage::skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const { + return Transform2D(); +} + +void MeshStorage::skeleton_update_dependency(RID p_base, RendererStorage::DependencyTracker *p_instance) { +} + +#endif // GLES3_ENABLED diff --git a/drivers/gles3/storage/mesh_storage.h b/drivers/gles3/storage/mesh_storage.h new file mode 100644 index 0000000000..3f44908049 --- /dev/null +++ b/drivers/gles3/storage/mesh_storage.h @@ -0,0 +1,204 @@ +/*************************************************************************/ +/* mesh_storage.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 MESH_STORAGE_GLES3_H +#define MESH_STORAGE_GLES3_H + +#ifdef GLES3_ENABLED + +#include "core/templates/local_vector.h" +#include "core/templates/rid_owner.h" +#include "core/templates/self_list.h" +#include "servers/rendering/storage/mesh_storage.h" + +namespace GLES3 { + +class MeshStorage : public RendererMeshStorage { +private: + static MeshStorage *singleton; + +public: + static MeshStorage *get_singleton(); + + MeshStorage(); + virtual ~MeshStorage(); + + /* MESH API */ + + virtual RID mesh_allocate() override; + virtual void mesh_initialize(RID p_rid) override; + virtual void mesh_free(RID p_rid) override; + + virtual void mesh_set_blend_shape_count(RID p_mesh, int p_blend_shape_count) override; + virtual bool mesh_needs_instance(RID p_mesh, bool p_has_skeleton) override; + + virtual void mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) override; + + virtual int mesh_get_blend_shape_count(RID p_mesh) const override; + + virtual void mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMode p_mode) override; + virtual RS::BlendShapeMode mesh_get_blend_shape_mode(RID p_mesh) const override; + + virtual void mesh_surface_update_vertex_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) override; + virtual void mesh_surface_update_attribute_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) override; + virtual void mesh_surface_update_skin_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) override; + + virtual void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) override; + virtual RID mesh_surface_get_material(RID p_mesh, int p_surface) const override; + + virtual RS::SurfaceData mesh_get_surface(RID p_mesh, int p_surface) const override; + virtual int mesh_get_surface_count(RID p_mesh) const override; + + virtual void mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) override; + virtual AABB mesh_get_custom_aabb(RID p_mesh) const override; + + virtual AABB mesh_get_aabb(RID p_mesh, RID p_skeleton = RID()) override; + virtual void mesh_set_shadow_mesh(RID p_mesh, RID p_shadow_mesh) override; + virtual void mesh_clear(RID p_mesh) override; + + /* MESH INSTANCE API */ + + virtual RID mesh_instance_create(RID p_base) override; + virtual void mesh_instance_free(RID p_rid) override; + virtual void mesh_instance_set_skeleton(RID p_mesh_instance, RID p_skeleton) override; + virtual void mesh_instance_set_blend_shape_weight(RID p_mesh_instance, int p_shape, float p_weight) override; + virtual void mesh_instance_check_for_update(RID p_mesh_instance) override; + virtual void update_mesh_instances() override; + + /* MULTIMESH API */ + + struct MultiMesh { + RID mesh; + int instances = 0; + RS::MultimeshTransformFormat xform_format = RS::MULTIMESH_TRANSFORM_3D; + bool uses_colors = false; + bool uses_custom_data = false; + int visible_instances = -1; + AABB aabb; + bool aabb_dirty = false; + bool buffer_set = false; + uint32_t stride_cache = 0; + uint32_t color_offset_cache = 0; + uint32_t custom_data_offset_cache = 0; + + Vector<float> data_cache; //used if individual setting is used + bool *data_cache_dirty_regions = nullptr; + uint32_t data_cache_used_dirty_regions = 0; + + RID buffer; //storage buffer + RID uniform_set_3d; + RID uniform_set_2d; + + bool dirty = false; + MultiMesh *dirty_list = nullptr; + + RendererStorage::Dependency dependency; + }; + + mutable RID_Owner<MultiMesh, true> multimesh_owner; + + MultiMesh *multimesh_dirty_list = nullptr; + + _FORCE_INLINE_ void _multimesh_make_local(MultiMesh *multimesh) const; + _FORCE_INLINE_ void _multimesh_mark_dirty(MultiMesh *multimesh, int p_index, bool p_aabb); + _FORCE_INLINE_ void _multimesh_mark_all_dirty(MultiMesh *multimesh, bool p_data, bool p_aabb); + _FORCE_INLINE_ void _multimesh_re_create_aabb(MultiMesh *multimesh, const float *p_data, int p_instances); + void _update_dirty_multimeshes(); + + virtual RID multimesh_allocate() override; + virtual void multimesh_initialize(RID p_rid) override; + virtual void multimesh_free(RID p_rid) override; + virtual void multimesh_allocate_data(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false) override; + virtual int multimesh_get_instance_count(RID p_multimesh) const override; + + virtual void multimesh_set_mesh(RID p_multimesh, RID p_mesh) override; + virtual void multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform3D &p_transform) override; + virtual void multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform) override; + virtual void multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) override; + virtual void multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_color) override; + + virtual RID multimesh_get_mesh(RID p_multimesh) const override; + virtual AABB multimesh_get_aabb(RID p_multimesh) const override; + + virtual Transform3D multimesh_instance_get_transform(RID p_multimesh, int p_index) const override; + virtual Transform2D multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const override; + virtual Color multimesh_instance_get_color(RID p_multimesh, int p_index) const override; + virtual Color multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const override; + virtual void multimesh_set_buffer(RID p_multimesh, const Vector<float> &p_buffer) override; + virtual Vector<float> multimesh_get_buffer(RID p_multimesh) const override; + + virtual void multimesh_set_visible_instances(RID p_multimesh, int p_visible) override; + virtual int multimesh_get_visible_instances(RID p_multimesh) const override; + + _FORCE_INLINE_ RS::MultimeshTransformFormat multimesh_get_transform_format(RID p_multimesh) const { + MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); + return multimesh->xform_format; + } + + _FORCE_INLINE_ bool multimesh_uses_colors(RID p_multimesh) const { + MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); + return multimesh->uses_colors; + } + + _FORCE_INLINE_ bool multimesh_uses_custom_data(RID p_multimesh) const { + MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); + return multimesh->uses_custom_data; + } + + _FORCE_INLINE_ uint32_t multimesh_get_instances_to_draw(RID p_multimesh) const { + MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); + if (multimesh->visible_instances >= 0) { + return multimesh->visible_instances; + } + return multimesh->instances; + } + + /* SKELETON API */ + + virtual RID skeleton_allocate() override; + virtual void skeleton_initialize(RID p_rid) override; + virtual void skeleton_free(RID p_rid) override; + + virtual void skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_skeleton = false) override; + virtual void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) override; + virtual int skeleton_get_bone_count(RID p_skeleton) const override; + virtual void skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform3D &p_transform) override; + virtual Transform3D skeleton_bone_get_transform(RID p_skeleton, int p_bone) const override; + virtual void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) override; + virtual Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const override; + + virtual void skeleton_update_dependency(RID p_base, RendererStorage::DependencyTracker *p_instance) override; +}; + +} // namespace GLES3 + +#endif // GLES3_ENABLED + +#endif // !MESH_STORAGE_GLES3_H diff --git a/drivers/gles3/storage/particles_storage.cpp b/drivers/gles3/storage/particles_storage.cpp new file mode 100644 index 0000000000..9ed9fedd5a --- /dev/null +++ b/drivers/gles3/storage/particles_storage.cpp @@ -0,0 +1,254 @@ +/*************************************************************************/ +/* particles_storage.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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. */ +/*************************************************************************/ + +#ifdef GLES3_ENABLED + +#include "particles_storage.h" + +using namespace GLES3; + +ParticlesStorage *ParticlesStorage::singleton = nullptr; + +ParticlesStorage *ParticlesStorage::get_singleton() { + return singleton; +} + +ParticlesStorage::ParticlesStorage() { + singleton = this; +} + +ParticlesStorage::~ParticlesStorage() { + singleton = nullptr; +} + +/* PARTICLES */ + +RID ParticlesStorage::particles_allocate() { + return RID(); +} + +void ParticlesStorage::particles_initialize(RID p_rid) { +} + +void ParticlesStorage::particles_free(RID p_rid) { +} + +void ParticlesStorage::particles_set_mode(RID p_particles, RS::ParticlesMode p_mode) { +} + +void ParticlesStorage::particles_emit(RID p_particles, const Transform3D &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) { +} + +void ParticlesStorage::particles_set_emitting(RID p_particles, bool p_emitting) { +} + +void ParticlesStorage::particles_set_amount(RID p_particles, int p_amount) { +} + +void ParticlesStorage::particles_set_lifetime(RID p_particles, double p_lifetime) { +} + +void ParticlesStorage::particles_set_one_shot(RID p_particles, bool p_one_shot) { +} + +void ParticlesStorage::particles_set_pre_process_time(RID p_particles, double p_time) { +} + +void ParticlesStorage::particles_set_explosiveness_ratio(RID p_particles, real_t p_ratio) { +} + +void ParticlesStorage::particles_set_randomness_ratio(RID p_particles, real_t p_ratio) { +} + +void ParticlesStorage::particles_set_custom_aabb(RID p_particles, const AABB &p_aabb) { +} + +void ParticlesStorage::particles_set_speed_scale(RID p_particles, double p_scale) { +} + +void ParticlesStorage::particles_set_use_local_coordinates(RID p_particles, bool p_enable) { +} + +void ParticlesStorage::particles_set_process_material(RID p_particles, RID p_material) { +} + +RID ParticlesStorage::particles_get_process_material(RID p_particles) const { + return RID(); +} + +void ParticlesStorage::particles_set_fixed_fps(RID p_particles, int p_fps) { +} + +void ParticlesStorage::particles_set_interpolate(RID p_particles, bool p_enable) { +} + +void ParticlesStorage::particles_set_fractional_delta(RID p_particles, bool p_enable) { +} + +void ParticlesStorage::particles_set_subemitter(RID p_particles, RID p_subemitter_particles) { +} + +void ParticlesStorage::particles_set_view_axis(RID p_particles, const Vector3 &p_axis, const Vector3 &p_up_axis) { +} + +void ParticlesStorage::particles_set_collision_base_size(RID p_particles, real_t p_size) { +} + +void ParticlesStorage::particles_set_transform_align(RID p_particles, RS::ParticlesTransformAlign p_transform_align) { +} + +void ParticlesStorage::particles_set_trails(RID p_particles, bool p_enable, double p_length) { +} + +void ParticlesStorage::particles_set_trail_bind_poses(RID p_particles, const Vector<Transform3D> &p_bind_poses) { +} + +void ParticlesStorage::particles_restart(RID p_particles) { +} + +void ParticlesStorage::particles_set_draw_order(RID p_particles, RS::ParticlesDrawOrder p_order) { +} + +void ParticlesStorage::particles_set_draw_passes(RID p_particles, int p_count) { +} + +void ParticlesStorage::particles_set_draw_pass_mesh(RID p_particles, int p_pass, RID p_mesh) { +} + +void ParticlesStorage::particles_request_process(RID p_particles) { +} + +AABB ParticlesStorage::particles_get_current_aabb(RID p_particles) { + return AABB(); +} + +AABB ParticlesStorage::particles_get_aabb(RID p_particles) const { + return AABB(); +} + +void ParticlesStorage::particles_set_emission_transform(RID p_particles, const Transform3D &p_transform) { +} + +bool ParticlesStorage::particles_get_emitting(RID p_particles) { + return false; +} + +int ParticlesStorage::particles_get_draw_passes(RID p_particles) const { + return 0; +} + +RID ParticlesStorage::particles_get_draw_pass_mesh(RID p_particles, int p_pass) const { + return RID(); +} + +void ParticlesStorage::particles_add_collision(RID p_particles, RID p_instance) { +} + +void ParticlesStorage::particles_remove_collision(RID p_particles, RID p_instance) { +} + +void ParticlesStorage::particles_set_canvas_sdf_collision(RID p_particles, bool p_enable, const Transform2D &p_xform, const Rect2 &p_to_screen, RID p_texture) { +} + +void ParticlesStorage::update_particles() { +} + +bool ParticlesStorage::particles_is_inactive(RID p_particles) const { + return false; +} + +/* PARTICLES COLLISION */ + +RID ParticlesStorage::particles_collision_allocate() { + return RID(); +} + +void ParticlesStorage::particles_collision_initialize(RID p_rid) { +} + +void ParticlesStorage::particles_collision_free(RID p_rid) { +} + +void ParticlesStorage::particles_collision_set_collision_type(RID p_particles_collision, RS::ParticlesCollisionType p_type) { +} + +void ParticlesStorage::particles_collision_set_cull_mask(RID p_particles_collision, uint32_t p_cull_mask) { +} + +void ParticlesStorage::particles_collision_set_sphere_radius(RID p_particles_collision, real_t p_radius) { +} + +void ParticlesStorage::particles_collision_set_box_extents(RID p_particles_collision, const Vector3 &p_extents) { +} + +void ParticlesStorage::particles_collision_set_attractor_strength(RID p_particles_collision, real_t p_strength) { +} + +void ParticlesStorage::particles_collision_set_attractor_directionality(RID p_particles_collision, real_t p_directionality) { +} + +void ParticlesStorage::particles_collision_set_attractor_attenuation(RID p_particles_collision, real_t p_curve) { +} + +void ParticlesStorage::particles_collision_set_field_texture(RID p_particles_collision, RID p_texture) { +} + +void ParticlesStorage::particles_collision_height_field_update(RID p_particles_collision) { +} + +void ParticlesStorage::particles_collision_set_height_field_resolution(RID p_particles_collision, RS::ParticlesCollisionHeightfieldResolution p_resolution) { +} + +AABB ParticlesStorage::particles_collision_get_aabb(RID p_particles_collision) const { + return AABB(); +} + +bool ParticlesStorage::particles_collision_is_heightfield(RID p_particles_collision) const { + return false; +} + +RID ParticlesStorage::particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const { + return RID(); +} + +RID ParticlesStorage::particles_collision_instance_create(RID p_collision) { + return RID(); +} + +void ParticlesStorage::particles_collision_instance_free(RID p_rid) { +} + +void ParticlesStorage::particles_collision_instance_set_transform(RID p_collision_instance, const Transform3D &p_transform) { +} + +void ParticlesStorage::particles_collision_instance_set_active(RID p_collision_instance, bool p_active) { +} + +#endif // GLES3_ENABLED diff --git a/drivers/gles3/storage/particles_storage.h b/drivers/gles3/storage/particles_storage.h new file mode 100644 index 0000000000..cf47ada5d5 --- /dev/null +++ b/drivers/gles3/storage/particles_storage.h @@ -0,0 +1,140 @@ +/*************************************************************************/ +/* particles_storage.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 PARTICLES_STORAGE_GLES3_H +#define PARTICLES_STORAGE_GLES3_H + +#ifdef GLES3_ENABLED + +#include "core/templates/local_vector.h" +#include "core/templates/rid_owner.h" +#include "core/templates/self_list.h" +#include "servers/rendering/storage/particles_storage.h" + +namespace GLES3 { + +class ParticlesStorage : public RendererParticlesStorage { +private: + static ParticlesStorage *singleton; + +public: + static ParticlesStorage *get_singleton(); + + ParticlesStorage(); + virtual ~ParticlesStorage(); + + /* PARTICLES */ + + virtual RID particles_allocate() override; + virtual void particles_initialize(RID p_rid) override; + virtual void particles_free(RID p_rid) override; + + virtual void particles_set_mode(RID p_particles, RS::ParticlesMode p_mode) override; + virtual void particles_emit(RID p_particles, const Transform3D &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) override; + virtual void particles_set_emitting(RID p_particles, bool p_emitting) override; + virtual void particles_set_amount(RID p_particles, int p_amount) override; + virtual void particles_set_lifetime(RID p_particles, double p_lifetime) override; + virtual void particles_set_one_shot(RID p_particles, bool p_one_shot) override; + virtual void particles_set_pre_process_time(RID p_particles, double p_time) override; + virtual void particles_set_explosiveness_ratio(RID p_particles, real_t p_ratio) override; + virtual void particles_set_randomness_ratio(RID p_particles, real_t p_ratio) override; + virtual void particles_set_custom_aabb(RID p_particles, const AABB &p_aabb) override; + virtual void particles_set_speed_scale(RID p_particles, double p_scale) override; + virtual void particles_set_use_local_coordinates(RID p_particles, bool p_enable) override; + virtual void particles_set_process_material(RID p_particles, RID p_material) override; + virtual RID particles_get_process_material(RID p_particles) const override; + virtual void particles_set_fixed_fps(RID p_particles, int p_fps) override; + virtual void particles_set_interpolate(RID p_particles, bool p_enable) override; + virtual void particles_set_fractional_delta(RID p_particles, bool p_enable) override; + virtual void particles_set_subemitter(RID p_particles, RID p_subemitter_particles) override; + virtual void particles_set_view_axis(RID p_particles, const Vector3 &p_axis, const Vector3 &p_up_axis) override; + virtual void particles_set_collision_base_size(RID p_particles, real_t p_size) override; + + virtual void particles_set_transform_align(RID p_particles, RS::ParticlesTransformAlign p_transform_align) override; + + virtual void particles_set_trails(RID p_particles, bool p_enable, double p_length) override; + virtual void particles_set_trail_bind_poses(RID p_particles, const Vector<Transform3D> &p_bind_poses) override; + + virtual void particles_restart(RID p_particles) override; + + virtual void particles_set_draw_order(RID p_particles, RS::ParticlesDrawOrder p_order) override; + + virtual void particles_set_draw_passes(RID p_particles, int p_count) override; + virtual void particles_set_draw_pass_mesh(RID p_particles, int p_pass, RID p_mesh) override; + + virtual void particles_request_process(RID p_particles) override; + virtual AABB particles_get_current_aabb(RID p_particles) override; + virtual AABB particles_get_aabb(RID p_particles) const override; + + virtual void particles_set_emission_transform(RID p_particles, const Transform3D &p_transform) override; + + virtual bool particles_get_emitting(RID p_particles) override; + virtual int particles_get_draw_passes(RID p_particles) const override; + virtual RID particles_get_draw_pass_mesh(RID p_particles, int p_pass) const override; + + virtual void particles_add_collision(RID p_particles, RID p_instance) override; + virtual void particles_remove_collision(RID p_particles, RID p_instance) override; + + virtual void particles_set_canvas_sdf_collision(RID p_particles, bool p_enable, const Transform2D &p_xform, const Rect2 &p_to_screen, RID p_texture) override; + + virtual void update_particles() override; + virtual bool particles_is_inactive(RID p_particles) const override; + + /* PARTICLES COLLISION */ + + virtual RID particles_collision_allocate() override; + virtual void particles_collision_initialize(RID p_rid) override; + virtual void particles_collision_free(RID p_rid) override; + + virtual void particles_collision_set_collision_type(RID p_particles_collision, RS::ParticlesCollisionType p_type) override; + virtual void particles_collision_set_cull_mask(RID p_particles_collision, uint32_t p_cull_mask) override; + virtual void particles_collision_set_sphere_radius(RID p_particles_collision, real_t p_radius) override; + virtual void particles_collision_set_box_extents(RID p_particles_collision, const Vector3 &p_extents) override; + virtual void particles_collision_set_attractor_strength(RID p_particles_collision, real_t p_strength) override; + virtual void particles_collision_set_attractor_directionality(RID p_particles_collision, real_t p_directionality) override; + virtual void particles_collision_set_attractor_attenuation(RID p_particles_collision, real_t p_curve) override; + virtual void particles_collision_set_field_texture(RID p_particles_collision, RID p_texture) override; + virtual void particles_collision_height_field_update(RID p_particles_collision) override; + virtual void particles_collision_set_height_field_resolution(RID p_particles_collision, RS::ParticlesCollisionHeightfieldResolution p_resolution) override; + virtual AABB particles_collision_get_aabb(RID p_particles_collision) const override; + virtual bool particles_collision_is_heightfield(RID p_particles_collision) const override; + virtual RID particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const override; + + virtual RID particles_collision_instance_create(RID p_collision) override; + virtual void particles_collision_instance_free(RID p_rid) override; + virtual void particles_collision_instance_set_transform(RID p_collision_instance, const Transform3D &p_transform) override; + virtual void particles_collision_instance_set_active(RID p_collision_instance, bool p_active) override; +}; + +} // namespace GLES3 + +#endif // GLES3_ENABLED + +#endif // !PARTICLES_STORAGE_GLES3_H diff --git a/drivers/gles3/storage/render_target_storage.h b/drivers/gles3/storage/render_target_storage.h deleted file mode 100644 index 816cc76e40..0000000000 --- a/drivers/gles3/storage/render_target_storage.h +++ /dev/null @@ -1,132 +0,0 @@ -/*************************************************************************/ -/* render_target_storage.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 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 RENDER_TARGET_STORAGE_GLES3_H -#define RENDER_TARGET_STORAGE_GLES3_H - -#ifdef GLES3_ENABLED - -#include "core/templates/rid_owner.h" -#include "servers/rendering/renderer_compositor.h" -#include "servers/rendering/renderer_storage.h" // included until we move stuff into storage/render_target_storage.h -// #include "servers/rendering/storage/render_target_storage.h" - -// This must come first to avoid windows.h mess -#include "platform_config.h" -#ifndef OPENGL_INCLUDE_H -#include <GLES3/gl3.h> -#else -#include OPENGL_INCLUDE_H -#endif - -namespace GLES3 { - -// NOTE, this class currently is just a container for the the RenderTarget struct and is not yet implemented further, we'll do that next after we finish with TextureStorage - -struct RenderTarget { - RID self; - GLuint fbo = 0; - GLuint color = 0; - GLuint depth = 0; - - GLuint multisample_fbo = 0; - GLuint multisample_color = 0; - GLuint multisample_depth = 0; - bool multisample_active = false; - - struct Effect { - GLuint fbo = 0; - int width = 0; - int height = 0; - - GLuint color = 0; - }; - - Effect copy_screen_effect; - - struct MipMaps { - struct Size { - GLuint fbo = 0; - GLuint color = 0; - int width = 0; - int height = 0; - }; - - Vector<Size> sizes; - GLuint color = 0; - int levels = 0; - }; - - MipMaps mip_maps[2]; - - struct External { - GLuint fbo = 0; - GLuint color = 0; - GLuint depth = 0; - RID texture; - } external; - - int x = 0; - int y = 0; - int width = 0; - int height = 0; - - bool flags[RendererStorage::RENDER_TARGET_FLAG_MAX] = {}; - - // instead of allocating sized render targets immediately, - // defer this for faster startup - bool allocate_is_dirty = false; - bool used_in_frame = false; - RS::ViewportMSAA msaa = RS::VIEWPORT_MSAA_DISABLED; - - bool use_fxaa = false; - bool use_debanding = false; - - RID texture; - - bool used_dof_blur_near = false; - bool mip_maps_allocated = false; - - Color clear_color = Color(1, 1, 1, 1); - bool clear_requested = false; - - RenderTarget() { - for (int i = 0; i < RendererStorage::RENDER_TARGET_FLAG_MAX; ++i) { - flags[i] = false; - } - external.fbo = 0; - } -}; - -} // namespace GLES3 - -#endif // !GLES3_ENABLED - -#endif // !RENDER_TARGET_STORAGE_GLES3_H diff --git a/drivers/gles3/storage/texture_storage.cpp b/drivers/gles3/storage/texture_storage.cpp index d199b1032e..2a63c7ccad 100644 --- a/drivers/gles3/storage/texture_storage.cpp +++ b/drivers/gles3/storage/texture_storage.cpp @@ -43,6 +43,81 @@ TextureStorage *TextureStorage::get_singleton() { TextureStorage::TextureStorage() { singleton = this; + + system_fbo = 0; + + frame.count = 0; + frame.delta = 0; + frame.current_rt = nullptr; + frame.clear_request = false; + + Config *config = Config::get_singleton(); + + //determine formats for depth textures (or renderbuffers) + if (config->support_depth_texture) { + // Will use texture for depth + // have to manually see if we can create a valid framebuffer texture using UNSIGNED_INT, + // as there is no extension to test for this. + GLuint fbo; + glGenFramebuffers(1, &fbo); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + GLuint depth; + glGenTextures(1, &depth); + glBindTexture(GL_TEXTURE_2D, depth); + glTexImage2D(GL_TEXTURE_2D, 0, config->depth_internalformat, 32, 32, 0, GL_DEPTH_COMPONENT, config->depth_type, nullptr); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth, 0); + + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + + glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo); + glDeleteFramebuffers(1, &fbo); + glBindTexture(GL_TEXTURE_2D, 0); + glDeleteTextures(1, &depth); + + if (status != GL_FRAMEBUFFER_COMPLETE) { + // If it fails, test to see if it supports a framebuffer texture using UNSIGNED_SHORT + // This is needed because many OSX devices don't support either UNSIGNED_INT or UNSIGNED_SHORT +#ifdef GLES_OVER_GL + config->depth_internalformat = GL_DEPTH_COMPONENT16; +#else + // OES_depth_texture extension only specifies GL_DEPTH_COMPONENT. + config->depth_internalformat = GL_DEPTH_COMPONENT; +#endif + config->depth_type = GL_UNSIGNED_SHORT; + + glGenFramebuffers(1, &fbo); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + + glGenTextures(1, &depth); + glBindTexture(GL_TEXTURE_2D, depth); + glTexImage2D(GL_TEXTURE_2D, 0, config->depth_internalformat, 32, 32, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, nullptr); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth, 0); + + status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) { + //if it fails again depth textures aren't supported, use rgba shadows and renderbuffer for depth + config->support_depth_texture = false; + config->use_rgba_3d_shadows = true; + } + + glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo); + glDeleteFramebuffers(1, &fbo); + glBindTexture(GL_TEXTURE_2D, 0); + glDeleteTextures(1, &depth); + } + } } TextureStorage::~TextureStorage() { @@ -65,6 +140,55 @@ bool TextureStorage::can_create_resources_async() const { return false; } +/* Canvas Texture API */ + +RID TextureStorage::canvas_texture_allocate() { + return canvas_texture_owner.allocate_rid(); +} + +void TextureStorage::canvas_texture_initialize(RID p_rid) { + canvas_texture_owner.initialize_rid(p_rid); +} + +void TextureStorage::canvas_texture_free(RID p_rid) { + canvas_texture_owner.free(p_rid); +} + +void TextureStorage::canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) { + CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture); + switch (p_channel) { + case RS::CANVAS_TEXTURE_CHANNEL_DIFFUSE: { + ct->diffuse = p_texture; + } break; + case RS::CANVAS_TEXTURE_CHANNEL_NORMAL: { + ct->normal_map = p_texture; + } break; + case RS::CANVAS_TEXTURE_CHANNEL_SPECULAR: { + ct->specular = p_texture; + } break; + } +} + +void TextureStorage::canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_specular_color, float p_shininess) { + CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture); + ct->specular_color.r = p_specular_color.r; + ct->specular_color.g = p_specular_color.g; + ct->specular_color.b = p_specular_color.b; + ct->specular_color.a = p_shininess; +} + +void TextureStorage::canvas_texture_set_texture_filter(RID p_canvas_texture, RS::CanvasItemTextureFilter p_filter) { + CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture); + ct->texture_filter = p_filter; +} + +void TextureStorage::canvas_texture_set_texture_repeat(RID p_canvas_texture, RS::CanvasItemTextureRepeat p_repeat) { + CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture); + ct->texture_repeat = p_repeat; +} + +/* Texture API */ + static const GLenum _cube_side_enum[6] = { GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_POSITIVE_X, @@ -1208,4 +1332,812 @@ void TextureStorage::textures_keep_original(bool p_enable) { Config::get_singleton()->keep_original_textures = p_enable; } +/* DECAL API */ + +RID TextureStorage::decal_allocate() { + return RID(); +} + +void TextureStorage::decal_initialize(RID p_rid) { +} + +void TextureStorage::decal_set_extents(RID p_decal, const Vector3 &p_extents) { +} + +void TextureStorage::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) { +} + +void TextureStorage::decal_set_emission_energy(RID p_decal, float p_energy) { +} + +void TextureStorage::decal_set_albedo_mix(RID p_decal, float p_mix) { +} + +void TextureStorage::decal_set_modulate(RID p_decal, const Color &p_modulate) { +} + +void TextureStorage::decal_set_cull_mask(RID p_decal, uint32_t p_layers) { +} + +void TextureStorage::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) { +} + +void TextureStorage::decal_set_fade(RID p_decal, float p_above, float p_below) { +} + +void TextureStorage::decal_set_normal_fade(RID p_decal, float p_fade) { +} + +AABB TextureStorage::decal_get_aabb(RID p_decal) const { + return AABB(); +} + +/* RENDER TARGET API */ + +GLuint TextureStorage::system_fbo = 0; + +void TextureStorage::_set_current_render_target(RID p_render_target) { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + + if (rt) { + if (rt->allocate_is_dirty) { + rt->allocate_is_dirty = false; + _render_target_allocate(rt); + } + + frame.current_rt = rt; + ERR_FAIL_COND(!rt); + frame.clear_request = false; + + glViewport(0, 0, rt->width, rt->height); + + _dims.rt_width = rt->width; + _dims.rt_height = rt->height; + _dims.win_width = rt->width; + _dims.win_height = rt->height; + + } else { + frame.current_rt = nullptr; + frame.clear_request = false; + glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo); + } +} + +void TextureStorage::_render_target_allocate(RenderTarget *rt) { + Config *config = Config::get_singleton(); + + // do not allocate a render target with no size + if (rt->width <= 0 || rt->height <= 0) { + return; + } + + // do not allocate a render target that is attached to the screen + if (rt->flags[RENDER_TARGET_DIRECT_TO_SCREEN]) { + rt->fbo = system_fbo; + return; + } + + GLuint color_internal_format; + GLuint color_format; + GLuint color_type = GL_UNSIGNED_BYTE; + Image::Format image_format; + + if (rt->flags[TextureStorage::RENDER_TARGET_TRANSPARENT]) { +#ifdef GLES_OVER_GL + color_internal_format = GL_RGBA8; +#else + color_internal_format = GL_RGBA; +#endif + color_format = GL_RGBA; + image_format = Image::FORMAT_RGBA8; + } else { +#ifdef GLES_OVER_GL + color_internal_format = GL_RGB8; +#else + color_internal_format = GL_RGB; +#endif + color_format = GL_RGB; + image_format = Image::FORMAT_RGB8; + } + + rt->used_dof_blur_near = false; + rt->mip_maps_allocated = false; + + { + /* Front FBO */ + + Texture *texture = get_texture(rt->texture); + ERR_FAIL_COND(!texture); + + // framebuffer + glGenFramebuffers(1, &rt->fbo); + glBindFramebuffer(GL_FRAMEBUFFER, rt->fbo); + + // color + glGenTextures(1, &rt->color); + glBindTexture(GL_TEXTURE_2D, rt->color); + + glTexImage2D(GL_TEXTURE_2D, 0, color_internal_format, rt->width, rt->height, 0, color_format, color_type, nullptr); + + if (texture->flags & TEXTURE_FLAG_FILTER) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } else { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + } + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->color, 0); + + // depth + + if (config->support_depth_texture) { + glGenTextures(1, &rt->depth); + glBindTexture(GL_TEXTURE_2D, rt->depth); + glTexImage2D(GL_TEXTURE_2D, 0, config->depth_internalformat, rt->width, rt->height, 0, GL_DEPTH_COMPONENT, config->depth_type, nullptr); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->depth, 0); + } else { + glGenRenderbuffers(1, &rt->depth); + glBindRenderbuffer(GL_RENDERBUFFER, rt->depth); + + glRenderbufferStorage(GL_RENDERBUFFER, config->depth_buffer_internalformat, rt->width, rt->height); + + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth); + } + + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + + if (status != GL_FRAMEBUFFER_COMPLETE) { + glDeleteFramebuffers(1, &rt->fbo); + if (config->support_depth_texture) { + glDeleteTextures(1, &rt->depth); + } else { + glDeleteRenderbuffers(1, &rt->depth); + } + + glDeleteTextures(1, &rt->color); + rt->fbo = 0; + rt->width = 0; + rt->height = 0; + rt->color = 0; + rt->depth = 0; + texture->tex_id = 0; + texture->active = false; + WARN_PRINT("Could not create framebuffer!!"); + return; + } + + texture->format = image_format; + texture->gl_format_cache = color_format; + texture->gl_type_cache = GL_UNSIGNED_BYTE; + texture->gl_internal_format_cache = color_internal_format; + texture->tex_id = rt->color; + texture->width = rt->width; + texture->alloc_width = rt->width; + texture->height = rt->height; + texture->alloc_height = rt->height; + texture->active = true; + + texture_set_flags(rt->texture, texture->flags); + } + + /* BACK FBO */ + /* For MSAA */ + +#ifndef JAVASCRIPT_ENABLED + if (rt->msaa >= RS::VIEWPORT_MSAA_2X && rt->msaa <= RS::VIEWPORT_MSAA_8X) { + rt->multisample_active = true; + + static const int msaa_value[] = { 0, 2, 4, 8, 16 }; + int msaa = msaa_value[rt->msaa]; + + int max_samples = 0; + glGetIntegerv(GL_MAX_SAMPLES, &max_samples); + if (msaa > max_samples) { + WARN_PRINT("MSAA must be <= GL_MAX_SAMPLES, falling-back to GL_MAX_SAMPLES = " + itos(max_samples)); + msaa = max_samples; + } + + //regular fbo + glGenFramebuffers(1, &rt->multisample_fbo); + glBindFramebuffer(GL_FRAMEBUFFER, rt->multisample_fbo); + + glGenRenderbuffers(1, &rt->multisample_depth); + glBindRenderbuffer(GL_RENDERBUFFER, rt->multisample_depth); + glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, config->depth_buffer_internalformat, rt->width, rt->height); + + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->multisample_depth); + + glGenRenderbuffers(1, &rt->multisample_color); + glBindRenderbuffer(GL_RENDERBUFFER, rt->multisample_color); + glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, color_internal_format, rt->width, rt->height); + + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rt->multisample_color); + + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + + if (status != GL_FRAMEBUFFER_COMPLETE) { + // Delete allocated resources and default to no MSAA + WARN_PRINT_ONCE("Cannot allocate back framebuffer for MSAA"); + printf("err status: %x\n", status); + rt->multisample_active = false; + + glDeleteFramebuffers(1, &rt->multisample_fbo); + rt->multisample_fbo = 0; + + glDeleteRenderbuffers(1, &rt->multisample_depth); + rt->multisample_depth = 0; + + glDeleteRenderbuffers(1, &rt->multisample_color); + rt->multisample_color = 0; + } + + glBindRenderbuffer(GL_RENDERBUFFER, 0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + } else +#endif // JAVASCRIPT_ENABLED + { + rt->multisample_active = false; + } + + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // copy texscreen buffers + // if (!(rt->flags[TextureStorage::RENDER_TARGET_NO_SAMPLING])) { + if (true) { + glGenTextures(1, &rt->copy_screen_effect.color); + glBindTexture(GL_TEXTURE_2D, rt->copy_screen_effect.color); + + if (rt->flags[TextureStorage::RENDER_TARGET_TRANSPARENT]) { + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rt->width, rt->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + } else { + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, rt->width, rt->height, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr); + } + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glGenFramebuffers(1, &rt->copy_screen_effect.fbo); + glBindFramebuffer(GL_FRAMEBUFFER, rt->copy_screen_effect.fbo); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->copy_screen_effect.color, 0); + + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); + + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) { + _render_target_clear(rt); + ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE); + } + } + + // Allocate mipmap chains for post_process effects + // if (!rt->flags[RendererStorage::RENDER_TARGET_NO_3D] && rt->width >= 2 && rt->height >= 2) { + if (rt->width >= 2 && rt->height >= 2) { + for (int i = 0; i < 2; i++) { + ERR_FAIL_COND(rt->mip_maps[i].sizes.size()); + int w = rt->width; + int h = rt->height; + + if (i > 0) { + w >>= 1; + h >>= 1; + } + + int level = 0; + int fb_w = w; + int fb_h = h; + + while (true) { + RenderTarget::MipMaps::Size mm; + mm.width = w; + mm.height = h; + rt->mip_maps[i].sizes.push_back(mm); + + w >>= 1; + h >>= 1; + + if (w < 2 || h < 2) { + break; + } + + level++; + } + + GLsizei width = fb_w; + GLsizei height = fb_h; + + if (config->render_to_mipmap_supported) { + glGenTextures(1, &rt->mip_maps[i].color); + glBindTexture(GL_TEXTURE_2D, rt->mip_maps[i].color); + + for (int l = 0; l < level + 1; l++) { + glTexImage2D(GL_TEXTURE_2D, l, color_internal_format, width, height, 0, color_format, color_type, nullptr); + width = MAX(1, (width / 2)); + height = MAX(1, (height / 2)); + } +#ifdef GLES_OVER_GL + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level); +#endif + } else { + // Can't render to specific levels of a mipmap in ES 2.0 or Webgl so create a texture for each level + for (int l = 0; l < level + 1; l++) { + glGenTextures(1, &rt->mip_maps[i].sizes.write[l].color); + glBindTexture(GL_TEXTURE_2D, rt->mip_maps[i].sizes[l].color); + glTexImage2D(GL_TEXTURE_2D, 0, color_internal_format, width, height, 0, color_format, color_type, nullptr); + width = MAX(1, (width / 2)); + height = MAX(1, (height / 2)); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } + } + + glDisable(GL_SCISSOR_TEST); + glColorMask(1, 1, 1, 1); + glDepthMask(GL_TRUE); + + for (int j = 0; j < rt->mip_maps[i].sizes.size(); j++) { + RenderTarget::MipMaps::Size &mm = rt->mip_maps[i].sizes.write[j]; + + glGenFramebuffers(1, &mm.fbo); + glBindFramebuffer(GL_FRAMEBUFFER, mm.fbo); + + if (config->render_to_mipmap_supported) { + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->mip_maps[i].color, j); + } else { + glBindTexture(GL_TEXTURE_2D, rt->mip_maps[i].sizes[j].color); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->mip_maps[i].sizes[j].color, 0); + } + + bool used_depth = false; + if (j == 0 && i == 0) { //use always + if (config->support_depth_texture) { + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->depth, 0); + } else { + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth); + } + used_depth = true; + } + + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) { + WARN_PRINT_ONCE("Cannot allocate mipmaps for 3D post processing effects"); + glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo); + return; + } + + glClearColor(1.0, 0.0, 1.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + if (used_depth) { + glClearDepth(1.0); + glClear(GL_DEPTH_BUFFER_BIT); + } + } + + rt->mip_maps[i].levels = level; + + if (config->render_to_mipmap_supported) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } + } + rt->mip_maps_allocated = true; + } + + glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo); +} + +void TextureStorage::_render_target_clear(RenderTarget *rt) { + Config *config = Config::get_singleton(); + + // there is nothing to clear when DIRECT_TO_SCREEN is used + if (rt->flags[RENDER_TARGET_DIRECT_TO_SCREEN]) { + return; + } + + if (rt->fbo) { + glDeleteFramebuffers(1, &rt->fbo); + glDeleteTextures(1, &rt->color); + rt->fbo = 0; + } + + if (rt->external.fbo != 0) { + // free this + glDeleteFramebuffers(1, &rt->external.fbo); + + // clean up our texture + Texture *t = get_texture(rt->external.texture); + t->alloc_height = 0; + t->alloc_width = 0; + t->width = 0; + t->height = 0; + t->active = false; + texture_free(rt->external.texture); + memdelete(t); + + rt->external.fbo = 0; + } + + if (rt->depth) { + if (config->support_depth_texture) { + glDeleteTextures(1, &rt->depth); + } else { + glDeleteRenderbuffers(1, &rt->depth); + } + + rt->depth = 0; + } + + Texture *tex = get_texture(rt->texture); + tex->alloc_height = 0; + tex->alloc_width = 0; + tex->width = 0; + tex->height = 0; + tex->active = false; + + if (rt->copy_screen_effect.color) { + glDeleteFramebuffers(1, &rt->copy_screen_effect.fbo); + rt->copy_screen_effect.fbo = 0; + + glDeleteTextures(1, &rt->copy_screen_effect.color); + rt->copy_screen_effect.color = 0; + } + + for (int i = 0; i < 2; i++) { + if (rt->mip_maps[i].sizes.size()) { + for (int j = 0; j < rt->mip_maps[i].sizes.size(); j++) { + glDeleteFramebuffers(1, &rt->mip_maps[i].sizes[j].fbo); + glDeleteTextures(1, &rt->mip_maps[i].sizes[j].color); + } + + glDeleteTextures(1, &rt->mip_maps[i].color); + rt->mip_maps[i].sizes.clear(); + rt->mip_maps[i].levels = 0; + rt->mip_maps[i].color = 0; + } + } + + if (rt->multisample_active) { + glDeleteFramebuffers(1, &rt->multisample_fbo); + rt->multisample_fbo = 0; + + glDeleteRenderbuffers(1, &rt->multisample_depth); + rt->multisample_depth = 0; + + glDeleteRenderbuffers(1, &rt->multisample_color); + + rt->multisample_color = 0; + } +} + +RID TextureStorage::render_target_create() { + RenderTarget *rt = memnew(RenderTarget); + Texture *t = memnew(Texture); + + t->type = RenderingDevice::TEXTURE_TYPE_2D; + t->flags = 0; + t->width = 0; + t->height = 0; + t->alloc_height = 0; + t->alloc_width = 0; + t->format = Image::FORMAT_R8; + t->target = GL_TEXTURE_2D; + t->gl_format_cache = 0; + t->gl_internal_format_cache = 0; + t->gl_type_cache = 0; + t->data_size = 0; + t->total_data_size = 0; + t->ignore_mipmaps = false; + t->compressed = false; + t->mipmaps = 1; + t->active = true; + t->tex_id = 0; + t->render_target = rt; + + rt->texture = make_rid(t); + return render_target_owner.make_rid(rt); +} + +void TextureStorage::render_target_free(RID p_rid) { + RenderTarget *rt = render_target_owner.get_or_null(p_rid); + _render_target_clear(rt); + + Texture *t = get_texture(rt->texture); + if (t) { + texture_free(rt->texture); + memdelete(t); + } + render_target_owner.free(p_rid); + memdelete(rt); +} + +void TextureStorage::render_target_set_position(RID p_render_target, int p_x, int p_y) { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + ERR_FAIL_COND(!rt); + + rt->x = p_x; + rt->y = p_y; +} + +void TextureStorage::render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + ERR_FAIL_COND(!rt); + + if (p_width == rt->width && p_height == rt->height) { + return; + } + + _render_target_clear(rt); + + rt->width = p_width; + rt->height = p_height; + + // print_line("render_target_set_size " + itos(p_render_target.get_id()) + ", w " + itos(p_width) + " h " + itos(p_height)); + + rt->allocate_is_dirty = true; + //_render_target_allocate(rt); +} + +// TODO: convert to Size2i internally +Size2i TextureStorage::render_target_get_size(RID p_render_target) { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + ERR_FAIL_COND_V(!rt, Size2()); + + return Size2i(rt->width, rt->height); +} + +RID TextureStorage::render_target_get_texture(RID p_render_target) { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + ERR_FAIL_COND_V(!rt, RID()); + + if (rt->external.fbo == 0) { + return rt->texture; + } else { + return rt->external.texture; + } +} + +void TextureStorage::render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + ERR_FAIL_COND(!rt); + + Config *config = Config::get_singleton(); + + if (p_texture_id == 0) { + if (rt->external.fbo != 0) { + // free this + glDeleteFramebuffers(1, &rt->external.fbo); + + // and this + if (rt->external.depth != 0) { + glDeleteRenderbuffers(1, &rt->external.depth); + } + + // clean up our texture + Texture *t = get_texture(rt->external.texture); + t->alloc_height = 0; + t->alloc_width = 0; + t->width = 0; + t->height = 0; + t->active = false; + texture_free(rt->external.texture); + memdelete(t); + + rt->external.fbo = 0; + rt->external.color = 0; + rt->external.depth = 0; + } + } else { + Texture *t; + + if (rt->external.fbo == 0) { + // create our fbo + glGenFramebuffers(1, &rt->external.fbo); + glBindFramebuffer(GL_FRAMEBUFFER, rt->external.fbo); + + // allocate a texture + t = memnew(Texture); + + t->type = RenderingDevice::TEXTURE_TYPE_2D; + t->flags = 0; + t->width = 0; + t->height = 0; + t->alloc_height = 0; + t->alloc_width = 0; + t->format = Image::FORMAT_RGBA8; + t->target = GL_TEXTURE_2D; + t->gl_format_cache = 0; + t->gl_internal_format_cache = 0; + t->gl_type_cache = 0; + t->data_size = 0; + t->compressed = false; + t->srgb = false; + t->total_data_size = 0; + t->ignore_mipmaps = false; + t->mipmaps = 1; + t->active = true; + t->tex_id = 0; + t->render_target = rt; + + rt->external.texture = make_rid(t); + + } else { + // bind our frame buffer + glBindFramebuffer(GL_FRAMEBUFFER, rt->external.fbo); + + // find our texture + t = get_texture(rt->external.texture); + } + + // set our texture + t->tex_id = p_texture_id; + rt->external.color = p_texture_id; + + // size shouldn't be different + t->width = rt->width; + t->height = rt->height; + t->alloc_height = rt->width; + t->alloc_width = rt->height; + + // Switch our texture on our frame buffer + { + // set our texture as the destination for our framebuffer + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, p_texture_id, 0); + + // seeing we're rendering into this directly, better also use our depth buffer, just use our existing one :) + if (config->support_depth_texture) { + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->depth, 0); + } else { + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth); + } + } + + // check status and unbind + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo); + + if (status != GL_FRAMEBUFFER_COMPLETE) { + printf("framebuffer fail, status: %x\n", status); + } + + ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE); + } +} + +void TextureStorage::render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + ERR_FAIL_COND(!rt); + + // When setting DIRECT_TO_SCREEN, you need to clear before the value is set, but allocate after as + // those functions change how they operate depending on the value of DIRECT_TO_SCREEN + if (p_flag == RENDER_TARGET_DIRECT_TO_SCREEN && p_value != rt->flags[RENDER_TARGET_DIRECT_TO_SCREEN]) { + _render_target_clear(rt); + rt->flags[p_flag] = p_value; + _render_target_allocate(rt); + } + + rt->flags[p_flag] = p_value; + + switch (p_flag) { + case RENDER_TARGET_TRANSPARENT: + /* + case RENDER_TARGET_HDR: + case RENDER_TARGET_NO_3D: + case RENDER_TARGET_NO_SAMPLING: + case RENDER_TARGET_NO_3D_EFFECTS: */ + { + //must reset for these formats + _render_target_clear(rt); + _render_target_allocate(rt); + } + break; + default: { + } + } +} + +bool TextureStorage::render_target_was_used(RID p_render_target) { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + ERR_FAIL_COND_V(!rt, false); + + return rt->used_in_frame; +} + +void TextureStorage::render_target_clear_used(RID p_render_target) { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + ERR_FAIL_COND(!rt); + + rt->used_in_frame = false; +} + +void TextureStorage::render_target_set_msaa(RID p_render_target, RS::ViewportMSAA p_msaa) { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + ERR_FAIL_COND(!rt); + + if (rt->msaa == p_msaa) { + return; + } + + _render_target_clear(rt); + rt->msaa = p_msaa; + _render_target_allocate(rt); +} + +void TextureStorage::render_target_set_use_fxaa(RID p_render_target, bool p_fxaa) { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + ERR_FAIL_COND(!rt); + + rt->use_fxaa = p_fxaa; +} + +void TextureStorage::render_target_set_use_debanding(RID p_render_target, bool p_debanding) { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + ERR_FAIL_COND(!rt); + + if (p_debanding) { + WARN_PRINT_ONCE("Debanding is not supported in the OpenGL backend. Switch to the Vulkan backend and make sure HDR is enabled."); + } + + rt->use_debanding = p_debanding; +} + +void TextureStorage::render_target_request_clear(RID p_render_target, const Color &p_clear_color) { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + ERR_FAIL_COND(!rt); + rt->clear_requested = true; + rt->clear_color = p_clear_color; + + // ERR_FAIL_COND(!frame.current_rt); + // frame.clear_request = true; + // frame.clear_request_color = p_color; +} + +bool TextureStorage::render_target_is_clear_requested(RID p_render_target) { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + ERR_FAIL_COND_V(!rt, false); + return rt->clear_requested; +} +Color TextureStorage::render_target_get_clear_request_color(RID p_render_target) { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + ERR_FAIL_COND_V(!rt, Color()); + return rt->clear_color; +} + +void TextureStorage::render_target_disable_clear_request(RID p_render_target) { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + ERR_FAIL_COND(!rt); + rt->clear_requested = false; +} + +void TextureStorage::render_target_do_clear_request(RID p_render_target) { +} + +void TextureStorage::render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) { +} + +Rect2i TextureStorage::render_target_get_sdf_rect(RID p_render_target) const { + return Rect2i(); +} + +void TextureStorage::render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled) { +} + #endif // GLES3_ENABLED diff --git a/drivers/gles3/storage/texture_storage.h b/drivers/gles3/storage/texture_storage.h index 8a921fbe10..7a5140a290 100644 --- a/drivers/gles3/storage/texture_storage.h +++ b/drivers/gles3/storage/texture_storage.h @@ -33,13 +33,20 @@ #ifdef GLES3_ENABLED -#include "canvas_texture_storage.h" #include "config.h" #include "core/os/os.h" #include "core/templates/rid_owner.h" -#include "render_target_storage.h" +#include "servers/rendering/renderer_compositor.h" #include "servers/rendering/storage/texture_storage.h" +// This must come first to avoid windows.h mess +#include "platform_config.h" +#ifndef OPENGL_INCLUDE_H +#include <GLES3/gl3.h> +#else +#include OPENGL_INCLUDE_H +#endif + namespace GLES3 { #define _EXT_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 @@ -90,10 +97,28 @@ enum OpenGLTextureFlags { TEXTURE_FLAGS_DEFAULT = TEXTURE_FLAG_REPEAT | TEXTURE_FLAG_MIPMAPS | TEXTURE_FLAG_FILTER }; +struct CanvasTexture { + RID diffuse; + RID normal_map; + RID specular; + Color specular_color = Color(1, 1, 1, 1); + float shininess = 1.0; + + RS::CanvasItemTextureFilter texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT; + RS::CanvasItemTextureRepeat texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT; + + Size2i size_cache = Size2i(1, 1); + bool use_normal_cache = false; + bool use_specular_cache = false; + bool cleared_cache = true; +}; + +struct RenderTarget; + struct Texture { RID self; - Texture *proxy; + Texture *proxy = nullptr; Set<Texture *> proxy_owners; String path; @@ -125,20 +150,20 @@ struct Texture { uint16_t stored_cube_sides; - RenderTarget *render_target; + RenderTarget *render_target = nullptr; Vector<Ref<Image>> images; bool redraw_if_visible; RS::TextureDetectCallback detect_3d; - void *detect_3d_ud; + void *detect_3d_ud = nullptr; RS::TextureDetectCallback detect_srgb; - void *detect_srgb_ud; + void *detect_srgb_ud = nullptr; RS::TextureDetectCallback detect_normal; - void *detect_normal_ud; + void *detect_normal_ud = nullptr; CanvasTexture *canvas_texture = nullptr; @@ -296,6 +321,81 @@ private: RS::CanvasItemTextureRepeat state_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED; }; +struct RenderTarget { + RID self; + GLuint fbo = 0; + GLuint color = 0; + GLuint depth = 0; + + GLuint multisample_fbo = 0; + GLuint multisample_color = 0; + GLuint multisample_depth = 0; + bool multisample_active = false; + + struct Effect { + GLuint fbo = 0; + int width = 0; + int height = 0; + + GLuint color = 0; + }; + + Effect copy_screen_effect; + + struct MipMaps { + struct Size { + GLuint fbo = 0; + GLuint color = 0; + int width = 0; + int height = 0; + }; + + Vector<Size> sizes; + GLuint color = 0; + int levels = 0; + }; + + MipMaps mip_maps[2]; + + struct External { + GLuint fbo = 0; + GLuint color = 0; + GLuint depth = 0; + RID texture; + } external; + + int x = 0; + int y = 0; + int width = 0; + int height = 0; + + bool flags[RendererTextureStorage::RENDER_TARGET_FLAG_MAX] = {}; + + // instead of allocating sized render targets immediately, + // defer this for faster startup + bool allocate_is_dirty = false; + bool used_in_frame = false; + RS::ViewportMSAA msaa = RS::VIEWPORT_MSAA_DISABLED; + + bool use_fxaa = false; + bool use_debanding = false; + + RID texture; + + bool used_dof_blur_near = false; + bool mip_maps_allocated = false; + + Color clear_color = Color(1, 1, 1, 1); + bool clear_requested = false; + + RenderTarget() { + for (int i = 0; i < RendererTextureStorage::RENDER_TARGET_FLAG_MAX; ++i) { + flags[i] = false; + } + external.fbo = 0; + } +}; + class TextureStorage : public RendererTextureStorage { private: static TextureStorage *singleton; @@ -303,6 +403,12 @@ private: Thread::ID _main_thread_id = 0; bool _is_main_thread(); + /* Canvas Texture API */ + + RID_Owner<CanvasTexture, true> canvas_texture_owner; + + /* Texture API */ + mutable RID_PtrOwner<Texture> texture_owner; Ref<Image> _get_gl_image_and_format(const Ref<Image> &p_image, Image::Format p_format, uint32_t p_flags, Image::Format &r_real_format, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type, bool &r_compressed, bool p_force_decompress) const; @@ -310,12 +416,50 @@ private: void texture_set_proxy(RID p_texture, RID p_proxy); + /* Render Target API */ + + mutable RID_PtrOwner<RenderTarget> render_target_owner; + + // make access easier to these + struct Dimensions { + // render target + int rt_width; + int rt_height; + + // window + int win_width; + int win_height; + Dimensions() { + rt_width = 0; + rt_height = 0; + win_width = 0; + win_height = 0; + } + } _dims; + public: static TextureStorage *get_singleton(); TextureStorage(); virtual ~TextureStorage(); + /* Canvas Texture API */ + + CanvasTexture *get_canvas_texture(RID p_rid) { return canvas_texture_owner.get_or_null(p_rid); }; + bool owns_canvas_texture(RID p_rid) { return canvas_texture_owner.owns(p_rid); }; + + virtual RID canvas_texture_allocate() override; + virtual void canvas_texture_initialize(RID p_rid) override; + virtual void canvas_texture_free(RID p_rid) override; + + virtual void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) override; + virtual void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) override; + + virtual void canvas_texture_set_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) override; + virtual void canvas_texture_set_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) override; + + /* Texture API */ + Texture *get_texture(RID p_rid) { return texture_owner.get_or_null(p_rid); }; bool owns_texture(RID p_rid) { return texture_owner.owns(p_rid); }; RID make_rid(Texture *p_texture) { return texture_owner.make_rid(p_texture); }; @@ -380,6 +524,86 @@ public: void texture_set_shrink_all_x2_on_set_data(bool p_enable); RID texture_create_radiance_cubemap(RID p_source, int p_resolution = -1) const; void textures_keep_original(bool p_enable); + + /* DECAL API */ + + virtual RID decal_allocate() override; + virtual void decal_initialize(RID p_rid) override; + virtual void decal_free(RID p_rid) override{}; + + virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) override; + virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) override; + virtual void decal_set_emission_energy(RID p_decal, float p_energy) override; + virtual void decal_set_albedo_mix(RID p_decal, float p_mix) override; + virtual void decal_set_modulate(RID p_decal, const Color &p_modulate) override; + virtual void decal_set_cull_mask(RID p_decal, uint32_t p_layers) override; + virtual void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) override; + virtual void decal_set_fade(RID p_decal, float p_above, float p_below) override; + virtual void decal_set_normal_fade(RID p_decal, float p_fade) override; + + virtual AABB decal_get_aabb(RID p_decal) const override; + + virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {} + virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {} + + /* RENDER TARGET API */ + + static GLuint system_fbo; + + struct Frame { + GLES3::RenderTarget *current_rt; + + // these 2 may have been superseded by the equivalents in the render target. + // these may be able to be removed. + bool clear_request; + Color clear_request_color; + + float time; + float delta; + uint64_t count; + + Frame() { + // current_rt = nullptr; + // clear_request = false; + } + } frame; + + RenderTarget *get_render_target(RID p_rid) { return render_target_owner.get_or_null(p_rid); }; + bool owns_render_target(RID p_rid) { return render_target_owner.owns(p_rid); }; + + void _render_target_clear(RenderTarget *rt); + void _render_target_allocate(RenderTarget *rt); + void _set_current_render_target(RID p_render_target); + + virtual RID render_target_create() override; + virtual void render_target_free(RID p_rid) override; + virtual void render_target_set_position(RID p_render_target, int p_x, int p_y) override; + virtual void render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) override; + Size2i render_target_get_size(RID p_render_target); + virtual RID render_target_get_texture(RID p_render_target) override; + virtual void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) override; + + virtual void render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) override; + virtual bool render_target_was_used(RID p_render_target) override; + void render_target_clear_used(RID p_render_target); + void render_target_set_msaa(RID p_render_target, RS::ViewportMSAA p_msaa); + void render_target_set_use_fxaa(RID p_render_target, bool p_fxaa); + void render_target_set_use_debanding(RID p_render_target, bool p_debanding); + + // new + void render_target_set_as_unused(RID p_render_target) override { + render_target_clear_used(p_render_target); + } + + void render_target_request_clear(RID p_render_target, const Color &p_clear_color) override; + bool render_target_is_clear_requested(RID p_render_target) override; + Color render_target_get_clear_request_color(RID p_render_target) override; + void render_target_disable_clear_request(RID p_render_target) override; + void render_target_do_clear_request(RID p_render_target) override; + + void render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) override; + Rect2i render_target_get_sdf_rect(RID p_render_target) const override; + void render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled) override; }; } // namespace GLES3 diff --git a/drivers/gles3/texture_loader_gles3.cpp b/drivers/gles3/texture_loader_gles3.cpp index f8d4cfdc61..8c8724686d 100644 --- a/drivers/gles3/texture_loader_gles3.cpp +++ b/drivers/gles3/texture_loader_gles3.cpp @@ -52,7 +52,7 @@ RES ResourceFormatGLES2Texture::load(const String &p_path, const String &p_origi 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 + row_p[i] = nullptr; // No colors any more, I want them to turn black. } memdelete_arr(row_p); diff --git a/drivers/png/image_loader_png.cpp b/drivers/png/image_loader_png.cpp index 46e271f9c9..917bfec574 100644 --- a/drivers/png/image_loader_png.cpp +++ b/drivers/png/image_loader_png.cpp @@ -36,18 +36,16 @@ #include <string.h> -Error ImageLoaderPNG::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale) { +Error ImageLoaderPNG::load_image(Ref<Image> p_image, Ref<FileAccess> f, bool p_force_linear, float p_scale) { const uint64_t buffer_size = f->get_length(); Vector<uint8_t> file_buffer; Error err = file_buffer.resize(buffer_size); if (err) { - f->close(); return err; } { uint8_t *writer = file_buffer.ptrw(); f->get_buffer(writer, buffer_size); - f->close(); } const uint8_t *reader = file_buffer.ptr(); return PNGDriverCommon::png_to_image(reader, buffer_size, p_force_linear, p_image); diff --git a/drivers/png/image_loader_png.h b/drivers/png/image_loader_png.h index af3bcd5b66..522cc901d4 100644 --- a/drivers/png/image_loader_png.h +++ b/drivers/png/image_loader_png.h @@ -40,7 +40,7 @@ private: static Ref<Image> load_mem_png(const uint8_t *p_png, int p_size); public: - virtual Error load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale); + virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> f, bool p_force_linear, float p_scale); virtual void get_recognized_extensions(List<String> *p_extensions) const; ImageLoaderPNG(); }; diff --git a/drivers/png/resource_saver_png.cpp b/drivers/png/resource_saver_png.cpp index ca84fb6be9..8633d2dc4e 100644 --- a/drivers/png/resource_saver_png.cpp +++ b/drivers/png/resource_saver_png.cpp @@ -52,20 +52,16 @@ Error ResourceSaverPNG::save_image(const String &p_path, const Ref<Image> &p_img Vector<uint8_t> buffer; Error err = PNGDriverCommon::image_to_png(p_img, buffer); ERR_FAIL_COND_V_MSG(err, err, "Can't convert image to PNG."); - FileAccess *file = FileAccess::open(p_path, FileAccess::WRITE, &err); + Ref<FileAccess> file = FileAccess::open(p_path, FileAccess::WRITE, &err); ERR_FAIL_COND_V_MSG(err, err, vformat("Can't save PNG at path: '%s'.", p_path)); const uint8_t *reader = buffer.ptr(); file->store_buffer(reader, buffer.size()); if (file->get_error() != OK && file->get_error() != ERR_FILE_EOF) { - memdelete(file); return ERR_CANT_CREATE; } - file->close(); - memdelete(file); - return OK; } diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.cpp b/drivers/pulseaudio/audio_driver_pulseaudio.cpp index ef9bbc3483..a6c35b6837 100644 --- a/drivers/pulseaudio/audio_driver_pulseaudio.cpp +++ b/drivers/pulseaudio/audio_driver_pulseaudio.cpp @@ -41,7 +41,7 @@ #endif void AudioDriverPulseAudio::pa_state_cb(pa_context *c, void *userdata) { - AudioDriverPulseAudio *ad = (AudioDriverPulseAudio *)userdata; + AudioDriverPulseAudio *ad = static_cast<AudioDriverPulseAudio *>(userdata); switch (pa_context_get_state(c)) { case PA_CONTEXT_TERMINATED: @@ -65,7 +65,7 @@ void AudioDriverPulseAudio::pa_state_cb(pa_context *c, void *userdata) { } void AudioDriverPulseAudio::pa_sink_info_cb(pa_context *c, const pa_sink_info *l, int eol, void *userdata) { - AudioDriverPulseAudio *ad = (AudioDriverPulseAudio *)userdata; + AudioDriverPulseAudio *ad = static_cast<AudioDriverPulseAudio *>(userdata); // If eol is set to a positive number, you're at the end of the list if (eol > 0) { @@ -84,7 +84,7 @@ void AudioDriverPulseAudio::pa_sink_info_cb(pa_context *c, const pa_sink_info *l } void AudioDriverPulseAudio::pa_source_info_cb(pa_context *c, const pa_source_info *l, int eol, void *userdata) { - AudioDriverPulseAudio *ad = (AudioDriverPulseAudio *)userdata; + AudioDriverPulseAudio *ad = static_cast<AudioDriverPulseAudio *>(userdata); // If eol is set to a positive number, you're at the end of the list if (eol > 0) { @@ -104,7 +104,7 @@ void AudioDriverPulseAudio::pa_source_info_cb(pa_context *c, const pa_source_inf void AudioDriverPulseAudio::pa_server_info_cb(pa_context *c, const pa_server_info *i, void *userdata) { ERR_FAIL_COND_MSG(!i, "PulseAudio server info is null."); - AudioDriverPulseAudio *ad = (AudioDriverPulseAudio *)userdata; + AudioDriverPulseAudio *ad = static_cast<AudioDriverPulseAudio *>(userdata); ad->capture_default_device = i->default_source_name; ad->default_device = i->default_sink_name; @@ -379,7 +379,7 @@ float AudioDriverPulseAudio::get_latency() { } void AudioDriverPulseAudio::thread_func(void *p_udata) { - AudioDriverPulseAudio *ad = (AudioDriverPulseAudio *)p_udata; + AudioDriverPulseAudio *ad = static_cast<AudioDriverPulseAudio *>(p_udata); unsigned int write_ofs = 0; size_t avail_bytes = 0; uint64_t default_device_msec = OS::get_singleton()->get_ticks_msec(); @@ -588,7 +588,7 @@ AudioDriver::SpeakerMode AudioDriverPulseAudio::get_speaker_mode() const { } void AudioDriverPulseAudio::pa_sinklist_cb(pa_context *c, const pa_sink_info *l, int eol, void *userdata) { - AudioDriverPulseAudio *ad = (AudioDriverPulseAudio *)userdata; + AudioDriverPulseAudio *ad = static_cast<AudioDriverPulseAudio *>(userdata); // If eol is set to a positive number, you're at the end of the list if (eol > 0) { @@ -771,7 +771,7 @@ void AudioDriverPulseAudio::capture_set_device(const String &p_name) { } void AudioDriverPulseAudio::pa_sourcelist_cb(pa_context *c, const pa_source_info *l, int eol, void *userdata) { - AudioDriverPulseAudio *ad = (AudioDriverPulseAudio *)userdata; + AudioDriverPulseAudio *ad = static_cast<AudioDriverPulseAudio *>(userdata); // If eol is set to a positive number, you're at the end of the list if (eol > 0) { diff --git a/drivers/unix/dir_access_unix.cpp b/drivers/unix/dir_access_unix.cpp index af47173b41..7e6105f033 100644 --- a/drivers/unix/dir_access_unix.cpp +++ b/drivers/unix/dir_access_unix.cpp @@ -49,7 +49,7 @@ #include <mntent.h> #endif -DirAccess *DirAccessUnix::create_fs() { +Ref<DirAccess> DirAccessUnix::create_fs() { return memnew(DirAccessUnix); } @@ -374,7 +374,7 @@ Error DirAccessUnix::change_dir(String p_dir) { return OK; } -String DirAccessUnix::get_current_dir(bool p_include_drive) { +String DirAccessUnix::get_current_dir(bool p_include_drive) const { String base = _get_root_path(); if (!base.is_empty()) { String bd = current_dir.replace_first(base, ""); diff --git a/drivers/unix/dir_access_unix.h b/drivers/unix/dir_access_unix.h index f90f55605c..4fea7cd154 100644 --- a/drivers/unix/dir_access_unix.h +++ b/drivers/unix/dir_access_unix.h @@ -41,9 +41,9 @@ #include <unistd.h> class DirAccessUnix : public DirAccess { - DIR *dir_stream; + DIR *dir_stream = nullptr; - static DirAccess *create_fs(); + static Ref<DirAccess> create_fs(); String current_dir; bool _cisdir; @@ -67,7 +67,7 @@ public: virtual bool drives_are_shortcuts(); virtual Error change_dir(String p_dir); ///< can be relative or absolute, return false on success - virtual String get_current_dir(bool p_include_drive = true); ///< return current dir location + virtual String get_current_dir(bool p_include_drive = true) const; ///< return current dir location virtual Error make_dir(String p_dir); virtual bool file_exists(String p_file); diff --git a/drivers/unix/file_access_unix.cpp b/drivers/unix/file_access_unix.cpp index ea442ad8bf..e0b2994b63 100644 --- a/drivers/unix/file_access_unix.cpp +++ b/drivers/unix/file_access_unix.cpp @@ -71,10 +71,7 @@ void FileAccessUnix::check_errors() const { } Error FileAccessUnix::_open(const String &p_path, int p_mode_flags) { - if (f) { - fclose(f); - } - f = nullptr; + _close(); path_src = p_path; path = fix_path(p_path); @@ -148,7 +145,7 @@ Error FileAccessUnix::_open(const String &p_path, int p_mode_flags) { return OK; } -void FileAccessUnix::close() { +void FileAccessUnix::_close() { if (!f) { return; } @@ -336,14 +333,14 @@ Error FileAccessUnix::_set_unix_permissions(const String &p_file, uint32_t p_per return FAILED; } -FileAccess *FileAccessUnix::create_libc() { +Ref<FileAccess> FileAccessUnix::create_libc() { return memnew(FileAccessUnix); } CloseNotificationFunc FileAccessUnix::close_notification_func = nullptr; FileAccessUnix::~FileAccessUnix() { - close(); + _close(); } #endif diff --git a/drivers/unix/file_access_unix.h b/drivers/unix/file_access_unix.h index 8ebdcd2a2d..4340bbbc82 100644 --- a/drivers/unix/file_access_unix.h +++ b/drivers/unix/file_access_unix.h @@ -49,13 +49,13 @@ class FileAccessUnix : public FileAccess { String path; String path_src; - static FileAccess *create_libc(); + static Ref<FileAccess> create_libc(); + void _close(); public: static CloseNotificationFunc close_notification_func; virtual Error _open(const String &p_path, int p_mode_flags); ///< open a file - virtual void close(); ///< close a file virtual bool is_open() const; ///< true when file is open virtual String get_path() const; /// returns the path for the current open file diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index 62de01e8bb..59b4c34c3f 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/drivers/vulkan/rendering_device_vulkan.cpp @@ -1318,7 +1318,7 @@ const VkImageType RenderingDeviceVulkan::vulkan_image_type[RenderingDevice::TEXT /**** BUFFER MANAGEMENT ****/ /***************************/ -Error RenderingDeviceVulkan::_buffer_allocate(Buffer *p_buffer, uint32_t p_size, uint32_t p_usage, VmaMemoryUsage p_mapping) { +Error RenderingDeviceVulkan::_buffer_allocate(Buffer *p_buffer, uint32_t p_size, uint32_t p_usage, VmaMemoryUsage p_mem_usage, VmaAllocationCreateFlags p_mem_flags) { VkBufferCreateInfo bufferInfo; bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; bufferInfo.pNext = nullptr; @@ -1330,8 +1330,8 @@ Error RenderingDeviceVulkan::_buffer_allocate(Buffer *p_buffer, uint32_t p_size, bufferInfo.pQueueFamilyIndices = nullptr; VmaAllocationCreateInfo allocInfo; - allocInfo.flags = 0; - allocInfo.usage = p_mapping; + allocInfo.flags = p_mem_flags; + allocInfo.usage = p_mem_usage; allocInfo.requiredFlags = 0; allocInfo.preferredFlags = 0; allocInfo.memoryTypeBits = 0; @@ -1380,8 +1380,8 @@ Error RenderingDeviceVulkan::_insert_staging_block() { bufferInfo.pQueueFamilyIndices = nullptr; VmaAllocationCreateInfo allocInfo; - allocInfo.flags = 0; - allocInfo.usage = VMA_MEMORY_USAGE_CPU_ONLY; + allocInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT; + allocInfo.usage = VMA_MEMORY_USAGE_AUTO_PREFER_HOST; allocInfo.requiredFlags = 0; allocInfo.preferredFlags = 0; allocInfo.memoryTypeBits = 0; @@ -1484,7 +1484,7 @@ Error RenderingDeviceVulkan::_staging_buffer_allocate(uint32_t p_amount, uint32_ //this is an old block, which was already processed, let's reuse staging_buffer_blocks.write[staging_buffer_current].frame_used = frames_drawn; staging_buffer_blocks.write[staging_buffer_current].fill_amount = 0; - } else if (staging_buffer_blocks[staging_buffer_current].frame_used > frames_drawn - frame_count) { + } else { //this block may still be in use, let's not touch it unless we have to, so.. can we create a new one? if ((uint64_t)staging_buffer_blocks.size() * staging_buffer_block_size < staging_buffer_max_size) { //we are still allowed to create a new block, so let's do that and insert it for current pos @@ -1847,9 +1847,9 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T uint32_t image_size = get_image_format_required_size(p_format.format, p_format.width, p_format.height, p_format.depth, p_format.mipmaps, &width, &height); VmaAllocationCreateInfo allocInfo; - allocInfo.flags = 0; + allocInfo.flags = (p_format.usage_bits & TEXTURE_USAGE_CPU_READ_BIT) ? VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT : 0; allocInfo.pool = nullptr; - allocInfo.usage = p_format.usage_bits & TEXTURE_USAGE_CPU_READ_BIT ? VMA_MEMORY_USAGE_CPU_ONLY : VMA_MEMORY_USAGE_GPU_ONLY; + allocInfo.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE; allocInfo.requiredFlags = 0; allocInfo.preferredFlags = 0; allocInfo.memoryTypeBits = 0; @@ -2703,7 +2703,7 @@ Vector<uint8_t> RenderingDeviceVulkan::texture_get_data(RID p_texture, uint32_t //allocate buffer VkCommandBuffer command_buffer = frames[frame].draw_command_buffer; //makes more sense to retrieve Buffer tmp_buffer; - _buffer_allocate(&tmp_buffer, buffer_size, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VMA_MEMORY_USAGE_CPU_ONLY); + _buffer_allocate(&tmp_buffer, buffer_size, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VMA_MEMORY_USAGE_AUTO_PREFER_HOST, VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT); { //Source image barrier VkImageMemoryBarrier image_memory_barrier; @@ -3364,8 +3364,14 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF attachment_last_pass.resize(p_attachments.size()); Vector<VkAttachmentDescription> attachments; + Vector<int> attachment_remap; for (int i = 0; i < p_attachments.size(); i++) { + if (p_attachments[i].usage_flags == AttachmentFormat::UNUSED_ATTACHMENT) { + attachment_remap.push_back(VK_ATTACHMENT_UNUSED); + continue; + } + ERR_FAIL_INDEX_V(p_attachments[i].format, DATA_FORMAT_MAX, VK_NULL_HANDLE); ERR_FAIL_INDEX_V(p_attachments[i].samples, TEXTURE_SAMPLES_MAX, VK_NULL_HANDLE); ERR_FAIL_COND_V_MSG(!(p_attachments[i].usage_flags & (TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | TEXTURE_USAGE_INPUT_ATTACHMENT_BIT)), @@ -3567,7 +3573,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF } attachment_last_pass[i] = -1; - + attachment_remap.push_back(attachments.size()); attachments.push_back(description); } @@ -3612,7 +3618,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF } else { ERR_FAIL_COND_V_MSG(texture_samples != p_attachments[attachment].samples, VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), if an attachment is marked as multisample, all of them should be multisample and use the same number of samples."); } - reference.attachment = attachment; + reference.attachment = attachment_remap[attachment]; reference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; attachment_last_pass[attachment] = i; } @@ -3631,7 +3637,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF ERR_FAIL_INDEX_V_MSG(attachment, p_attachments.size(), VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), input attachment (" + itos(j) + ")."); ERR_FAIL_COND_V_MSG(!(p_attachments[attachment].usage_flags & TEXTURE_USAGE_INPUT_ATTACHMENT_BIT), VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), it isn't marked as an input texture."); ERR_FAIL_COND_V_MSG(attachment_last_pass[attachment] == i, VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), it already was used for something else before in this pass."); - reference.attachment = attachment; + reference.attachment = attachment_remap[attachment]; reference.layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; attachment_last_pass[attachment] = i; } @@ -3657,7 +3663,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF ERR_FAIL_COND_V_MSG(attachment_last_pass[attachment] == i, VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), it already was used for something else before in this pass."); bool multisample = p_attachments[attachment].samples > TEXTURE_SAMPLES_1; ERR_FAIL_COND_V_MSG(multisample, VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), resolve attachments can't be multisample."); - reference.attachment = attachment; + reference.attachment = attachment_remap[attachment]; reference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; // VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; attachment_last_pass[attachment] = i; } @@ -3671,7 +3677,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF ERR_FAIL_INDEX_V_MSG(attachment, p_attachments.size(), VK_NULL_HANDLE, "Invalid framebuffer depth format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), depth attachment."); ERR_FAIL_COND_V_MSG(!(p_attachments[attachment].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT), VK_NULL_HANDLE, "Invalid framebuffer depth format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), it's marked as depth, but it's not a depth attachment."); ERR_FAIL_COND_V_MSG(attachment_last_pass[attachment] == i, VK_NULL_HANDLE, "Invalid framebuffer depth format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), it already was used for something else before in this pass."); - depth_stencil_reference.attachment = attachment; + depth_stencil_reference.attachment = attachment_remap[attachment]; depth_stencil_reference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; attachment_last_pass[attachment] = i; @@ -3958,14 +3964,13 @@ RID RenderingDeviceVulkan::framebuffer_create(const Vector<RID> &p_texture_attac for (int i = 0; i < p_texture_attachments.size(); i++) { Texture *texture = texture_owner.get_or_null(p_texture_attachments[i]); - ERR_FAIL_COND_V_MSG(!texture, RID(), "Texture index supplied for framebuffer (" + itos(i) + ") is not a valid texture."); - ERR_FAIL_COND_V_MSG(texture->layers != p_view_count, RID(), "Layers of our texture doesn't match view count for this framebuffer"); + ERR_FAIL_COND_V_MSG(texture && texture->layers != p_view_count, RID(), "Layers of our texture doesn't match view count for this framebuffer"); - if (texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { + if (texture && texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { pass.depth_attachment = i; } else { - pass.color_attachments.push_back(i); + pass.color_attachments.push_back(texture ? i : FramebufferPass::ATTACHMENT_UNUSED); } } @@ -3979,29 +3984,35 @@ RID RenderingDeviceVulkan::framebuffer_create_multipass(const Vector<RID> &p_tex _THREAD_SAFE_METHOD_ Vector<AttachmentFormat> attachments; + attachments.resize(p_texture_attachments.size()); Size2i size; - + bool size_set = false; for (int i = 0; i < p_texture_attachments.size(); i++) { + AttachmentFormat af; Texture *texture = texture_owner.get_or_null(p_texture_attachments[i]); - ERR_FAIL_COND_V_MSG(!texture, RID(), "Texture index supplied for framebuffer (" + itos(i) + ") is not a valid texture."); + if (!texture) { + af.usage_flags = AttachmentFormat::UNUSED_ATTACHMENT; + } else { + ERR_FAIL_COND_V_MSG(texture->layers != p_view_count, RID(), "Layers of our texture doesn't match view count for this framebuffer"); - ERR_FAIL_COND_V_MSG(texture->layers != p_view_count, RID(), "Layers of our texture doesn't match view count for this framebuffer"); + if (!size_set) { + size.width = texture->width; + size.height = texture->height; + size_set = true; + } else { + ERR_FAIL_COND_V_MSG((uint32_t)size.width != texture->width || (uint32_t)size.height != texture->height, RID(), + "All textures in a framebuffer should be the same size."); + } - if (i == 0) { - size.width = texture->width; - size.height = texture->height; - } else { - ERR_FAIL_COND_V_MSG((uint32_t)size.width != texture->width || (uint32_t)size.height != texture->height, RID(), - "All textures in a framebuffer should be the same size."); + af.format = texture->format; + af.samples = texture->samples; + af.usage_flags = texture->usage_flags; } - - AttachmentFormat af; - af.format = texture->format; - af.samples = texture->samples; - af.usage_flags = texture->usage_flags; - attachments.push_back(af); + attachments.write[i] = af; } + ERR_FAIL_COND_V_MSG(!size_set, RID(), "All attachments unused."); + FramebufferFormatID format_id = framebuffer_format_create_multipass(attachments, p_passes, p_view_count); if (format_id == INVALID_ID) { return RID(); @@ -4019,7 +4030,9 @@ RID RenderingDeviceVulkan::framebuffer_create_multipass(const Vector<RID> &p_tex RID id = framebuffer_owner.make_rid(framebuffer); for (int i = 0; i < p_texture_attachments.size(); i++) { - _add_dependency(id, p_texture_attachments[i]); + if (p_texture_attachments[i].is_valid()) { + _add_dependency(id, p_texture_attachments[i]); + } } return id; @@ -4097,7 +4110,7 @@ RID RenderingDeviceVulkan::vertex_buffer_create(uint32_t p_size_bytes, const Vec usage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; } Buffer buffer; - _buffer_allocate(&buffer, p_size_bytes, usage, VMA_MEMORY_USAGE_GPU_ONLY); + _buffer_allocate(&buffer, p_size_bytes, usage, VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, 0); if (p_data.size()) { uint64_t data_size = p_data.size(); const uint8_t *r = p_data.ptr(); @@ -4259,7 +4272,7 @@ RID RenderingDeviceVulkan::index_buffer_create(uint32_t p_index_count, IndexBuff #else index_buffer.max_index = 0xFFFFFFFF; #endif - _buffer_allocate(&index_buffer, size_bytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VMA_MEMORY_USAGE_GPU_ONLY); + _buffer_allocate(&index_buffer, size_bytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, 0); if (p_data.size()) { uint64_t data_size = p_data.size(); const uint8_t *r = p_data.ptr(); @@ -4862,9 +4875,8 @@ Vector<uint8_t> RenderingDeviceVulkan::shader_compile_binary_from_spirv(const Ve "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "' failed obtaining push constants."); #if 0 if (pconstants[0] == nullptr) { - FileAccess *f = FileAccess::open("res://popo.spv", FileAccess::WRITE); + Ref<FileAccess> f = FileAccess::open("res://popo.spv", FileAccess::WRITE); f->store_buffer((const uint8_t *)&SpirV[0], SpirV.size() * sizeof(uint32_t)); - memdelete(f); } #endif @@ -4952,8 +4964,8 @@ Vector<uint8_t> RenderingDeviceVulkan::shader_compile_binary_from_spirv(const Ve Vector<uint8_t> ret; ret.resize(total_size); - uint32_t offset = 0; { + uint32_t offset = 0; uint8_t *binptr = ret.ptrw(); binptr[0] = 'G'; binptr[1] = 'V'; @@ -5026,7 +5038,7 @@ RID RenderingDeviceVulkan::shader_create_from_bytecode(const Vector<uint8_t> &p_ uint32_t bin_data_size = decode_uint32(binptr + 8); - const RenderingDeviceVulkanShaderBinaryData &binary_data = *(const RenderingDeviceVulkanShaderBinaryData *)(binptr + 12); + const RenderingDeviceVulkanShaderBinaryData &binary_data = *(reinterpret_cast<const RenderingDeviceVulkanShaderBinaryData *>(binptr + 12)); Shader::PushConstant push_constant; push_constant.push_constant_size = binary_data.push_constant_size; @@ -5038,7 +5050,7 @@ RID RenderingDeviceVulkan::shader_create_from_bytecode(const Vector<uint8_t> &p_ bool is_compute = binary_data.is_compute; - uint32_t compute_local_size[3] = { binary_data.compute_local_size[0], binary_data.compute_local_size[1], binary_data.compute_local_size[2] }; + const uint32_t compute_local_size[3] = { binary_data.compute_local_size[0], binary_data.compute_local_size[1], binary_data.compute_local_size[2] }; read_offset += sizeof(uint32_t) * 3 + bin_data_size; @@ -5062,7 +5074,7 @@ RID RenderingDeviceVulkan::shader_create_from_bytecode(const Vector<uint8_t> &p_ ERR_FAIL_COND_V(read_offset + sizeof(uint32_t) >= binsize, RID()); uint32_t set_count = decode_uint32(binptr + read_offset); read_offset += sizeof(uint32_t); - const RenderingDeviceVulkanShaderBinaryDataBinding *set_ptr = (const RenderingDeviceVulkanShaderBinaryDataBinding *)(binptr + read_offset); + const RenderingDeviceVulkanShaderBinaryDataBinding *set_ptr = reinterpret_cast<const RenderingDeviceVulkanShaderBinaryDataBinding *>(binptr + read_offset); uint32_t set_size = set_count * sizeof(RenderingDeviceVulkanShaderBinaryDataBinding); ERR_FAIL_COND_V(read_offset + set_size >= binsize, RID()); @@ -5134,7 +5146,7 @@ RID RenderingDeviceVulkan::shader_create_from_bytecode(const Vector<uint8_t> &p_ Vector<Shader::SpecializationConstant> specialization_constants; for (uint32_t i = 0; i < binary_data.specialization_constant_count; i++) { - const RenderingDeviceVulkanShaderBinarySpecializationConstant &src_sc = *(const RenderingDeviceVulkanShaderBinarySpecializationConstant *)(binptr + read_offset); + const RenderingDeviceVulkanShaderBinarySpecializationConstant &src_sc = *(reinterpret_cast<const RenderingDeviceVulkanShaderBinarySpecializationConstant *>(binptr + read_offset)); Shader::SpecializationConstant sc; sc.constant.int_value = src_sc.int_value; sc.constant.type = PipelineSpecializationConstantType(src_sc.type); @@ -5371,7 +5383,7 @@ RID RenderingDeviceVulkan::uniform_buffer_create(uint32_t p_size_bytes, const Ve "Creating buffers with data is forbidden during creation of a draw list"); Buffer buffer; - Error err = _buffer_allocate(&buffer, p_size_bytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VMA_MEMORY_USAGE_GPU_ONLY); + Error err = _buffer_allocate(&buffer, p_size_bytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, 0); ERR_FAIL_COND_V(err != OK, RID()); if (p_data.size()) { uint64_t data_size = p_data.size(); @@ -5397,7 +5409,7 @@ RID RenderingDeviceVulkan::storage_buffer_create(uint32_t p_size_bytes, const Ve if (p_usage & STORAGE_BUFFER_USAGE_DISPATCH_INDIRECT) { flags |= VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT; } - Error err = _buffer_allocate(&buffer, p_size_bytes, flags, VMA_MEMORY_USAGE_GPU_ONLY); + Error err = _buffer_allocate(&buffer, p_size_bytes, flags, VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, 0); ERR_FAIL_COND_V(err != OK, RID()); if (p_data.size()) { @@ -5423,7 +5435,7 @@ RID RenderingDeviceVulkan::texture_buffer_create(uint32_t p_size_elements, DataF ERR_FAIL_COND_V(p_data.size() && (uint32_t)p_data.size() != size_bytes, RID()); TextureBuffer texture_buffer; - Error err = _buffer_allocate(&texture_buffer.buffer, size_bytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, VMA_MEMORY_USAGE_GPU_ONLY); + Error err = _buffer_allocate(&texture_buffer.buffer, size_bytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, 0); ERR_FAIL_COND_V(err != OK, RID()); if (p_data.size()) { @@ -6170,7 +6182,7 @@ Vector<uint8_t> RenderingDeviceVulkan::buffer_get_data(RID p_buffer) { VkCommandBuffer command_buffer = frames[frame].setup_command_buffer; Buffer tmp_buffer; - _buffer_allocate(&tmp_buffer, buffer->size, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VMA_MEMORY_USAGE_CPU_ONLY); + _buffer_allocate(&tmp_buffer, buffer->size, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VMA_MEMORY_USAGE_AUTO_PREFER_HOST, VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT); VkBufferCopy region; region.srcOffset = 0; region.dstOffset = 0; @@ -6243,7 +6255,7 @@ RID RenderingDeviceVulkan::render_pipeline_create(RID p_shader, FramebufferForma //validate with inputs for (uint32_t i = 0; i < 32; i++) { - if (!(shader->vertex_input_mask & (1 << i))) { + if (!(shader->vertex_input_mask & (1UL << i))) { continue; } bool found = false; @@ -6321,7 +6333,7 @@ RID RenderingDeviceVulkan::render_pipeline_create(RID p_shader, FramebufferForma rasterization_state_create_info.depthClampEnable = p_rasterization_state.enable_depth_clamp; rasterization_state_create_info.rasterizerDiscardEnable = p_rasterization_state.discard_primitives; rasterization_state_create_info.polygonMode = (p_rasterization_state.wireframe ? VK_POLYGON_MODE_LINE : VK_POLYGON_MODE_FILL); - static VkCullModeFlags cull_mode[3] = { + static const VkCullModeFlags cull_mode[3] = { VK_CULL_MODE_NONE, VK_CULL_MODE_FRONT_BIT, VK_CULL_MODE_BACK_BIT @@ -6348,7 +6360,7 @@ RID RenderingDeviceVulkan::render_pipeline_create(RID p_shader, FramebufferForma Vector<VkSampleMask> sample_mask; if (p_multisample_state.sample_mask.size()) { //use sample mask - int rasterization_sample_mask_expected_size[TEXTURE_SAMPLES_MAX] = { + const int rasterization_sample_mask_expected_size[TEXTURE_SAMPLES_MAX] = { 1, 2, 4, 8, 16, 32, 64 }; ERR_FAIL_COND_V(rasterization_sample_mask_expected_size[p_multisample_state.sample_count] != p_multisample_state.sample_mask.size(), RID()); @@ -6417,49 +6429,55 @@ RID RenderingDeviceVulkan::render_pipeline_create(RID p_shader, FramebufferForma Vector<VkPipelineColorBlendAttachmentState> attachment_states; { const FramebufferPass &pass = fb_format.E->key().passes[p_for_render_pass]; - + attachment_states.resize(pass.color_attachments.size()); + ERR_FAIL_COND_V(p_blend_state.attachments.size() < pass.color_attachments.size(), RID()); for (int i = 0; i < pass.color_attachments.size(); i++) { - if (pass.color_attachments[i] != FramebufferPass::ATTACHMENT_UNUSED) { - int idx = attachment_states.size(); - - ERR_FAIL_INDEX_V(idx, p_blend_state.attachments.size(), RID()); - VkPipelineColorBlendAttachmentState state; - state.blendEnable = p_blend_state.attachments[idx].enable_blend; - - ERR_FAIL_INDEX_V(p_blend_state.attachments[idx].src_color_blend_factor, BLEND_FACTOR_MAX, RID()); - state.srcColorBlendFactor = blend_factors[p_blend_state.attachments[idx].src_color_blend_factor]; - ERR_FAIL_INDEX_V(p_blend_state.attachments[idx].dst_color_blend_factor, BLEND_FACTOR_MAX, RID()); - state.dstColorBlendFactor = blend_factors[p_blend_state.attachments[idx].dst_color_blend_factor]; - ERR_FAIL_INDEX_V(p_blend_state.attachments[idx].color_blend_op, BLEND_OP_MAX, RID()); - state.colorBlendOp = blend_operations[p_blend_state.attachments[idx].color_blend_op]; - - ERR_FAIL_INDEX_V(p_blend_state.attachments[idx].src_alpha_blend_factor, BLEND_FACTOR_MAX, RID()); - state.srcAlphaBlendFactor = blend_factors[p_blend_state.attachments[idx].src_alpha_blend_factor]; - ERR_FAIL_INDEX_V(p_blend_state.attachments[idx].dst_alpha_blend_factor, BLEND_FACTOR_MAX, RID()); - state.dstAlphaBlendFactor = blend_factors[p_blend_state.attachments[idx].dst_alpha_blend_factor]; - ERR_FAIL_INDEX_V(p_blend_state.attachments[idx].alpha_blend_op, BLEND_OP_MAX, RID()); - state.alphaBlendOp = blend_operations[p_blend_state.attachments[idx].alpha_blend_op]; + VkPipelineColorBlendAttachmentState state; + if (pass.color_attachments[i] == FramebufferPass::ATTACHMENT_UNUSED) { + state.blendEnable = false; + + state.srcColorBlendFactor = VK_BLEND_FACTOR_ZERO; + state.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO; + state.colorBlendOp = VK_BLEND_OP_ADD; + + state.srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; + state.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; + state.alphaBlendOp = VK_BLEND_OP_ADD; + + state.colorWriteMask = 0; + } else { + state.blendEnable = p_blend_state.attachments[i].enable_blend; + + ERR_FAIL_INDEX_V(p_blend_state.attachments[i].src_color_blend_factor, BLEND_FACTOR_MAX, RID()); + state.srcColorBlendFactor = blend_factors[p_blend_state.attachments[i].src_color_blend_factor]; + ERR_FAIL_INDEX_V(p_blend_state.attachments[i].dst_color_blend_factor, BLEND_FACTOR_MAX, RID()); + state.dstColorBlendFactor = blend_factors[p_blend_state.attachments[i].dst_color_blend_factor]; + ERR_FAIL_INDEX_V(p_blend_state.attachments[i].color_blend_op, BLEND_OP_MAX, RID()); + state.colorBlendOp = blend_operations[p_blend_state.attachments[i].color_blend_op]; + + ERR_FAIL_INDEX_V(p_blend_state.attachments[i].src_alpha_blend_factor, BLEND_FACTOR_MAX, RID()); + state.srcAlphaBlendFactor = blend_factors[p_blend_state.attachments[i].src_alpha_blend_factor]; + ERR_FAIL_INDEX_V(p_blend_state.attachments[i].dst_alpha_blend_factor, BLEND_FACTOR_MAX, RID()); + state.dstAlphaBlendFactor = blend_factors[p_blend_state.attachments[i].dst_alpha_blend_factor]; + ERR_FAIL_INDEX_V(p_blend_state.attachments[i].alpha_blend_op, BLEND_OP_MAX, RID()); + state.alphaBlendOp = blend_operations[p_blend_state.attachments[i].alpha_blend_op]; state.colorWriteMask = 0; - if (p_blend_state.attachments[idx].write_r) { + if (p_blend_state.attachments[i].write_r) { state.colorWriteMask |= VK_COLOR_COMPONENT_R_BIT; } - if (p_blend_state.attachments[idx].write_g) { + if (p_blend_state.attachments[i].write_g) { state.colorWriteMask |= VK_COLOR_COMPONENT_G_BIT; } - if (p_blend_state.attachments[idx].write_b) { + if (p_blend_state.attachments[i].write_b) { state.colorWriteMask |= VK_COLOR_COMPONENT_B_BIT; } - if (p_blend_state.attachments[idx].write_a) { + if (p_blend_state.attachments[i].write_a) { state.colorWriteMask |= VK_COLOR_COMPONENT_A_BIT; } - - attachment_states.push_back(state); - idx++; } + attachment_states.write[i] = state; } - - ERR_FAIL_COND_V(attachment_states.size() != p_blend_state.attachments.size(), RID()); } color_blend_state_create_info.attachmentCount = attachment_states.size(); @@ -6863,10 +6881,11 @@ Error RenderingDeviceVulkan::_draw_list_setup_framebuffer(Framebuffer *p_framebu Vector<VkImageView> attachments; for (int i = 0; i < p_framebuffer->texture_ids.size(); i++) { Texture *texture = texture_owner.get_or_null(p_framebuffer->texture_ids[i]); - ERR_FAIL_COND_V(!texture, ERR_BUG); - attachments.push_back(texture->view); - ERR_FAIL_COND_V(texture->width != p_framebuffer->size.width, ERR_BUG); - ERR_FAIL_COND_V(texture->height != p_framebuffer->size.height, ERR_BUG); + if (texture) { + attachments.push_back(texture->view); + ERR_FAIL_COND_V(texture->width != p_framebuffer->size.width, ERR_BUG); + ERR_FAIL_COND_V(texture->height != p_framebuffer->size.height, ERR_BUG); + } } framebuffer_create_info.attachmentCount = attachments.size(); framebuffer_create_info.pAttachments = attachments.ptr(); @@ -6910,13 +6929,18 @@ Error RenderingDeviceVulkan::_draw_list_render_pass_begin(Framebuffer *framebuff Vector<VkClearValue> clear_values; clear_values.resize(framebuffer->texture_ids.size()); - + int clear_values_count = 0; { int color_index = 0; for (int i = 0; i < framebuffer->texture_ids.size(); i++) { - Texture *texture = texture_owner.get_or_null(framebuffer->texture_ids[i]); VkClearValue clear_value; + Texture *texture = texture_owner.get_or_null(framebuffer->texture_ids[i]); + if (!texture) { + color_index++; + continue; + } + if (color_index < p_clear_colors.size() && texture->usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) { ERR_FAIL_INDEX_V(color_index, p_clear_colors.size(), ERR_BUG); //a bug Color clear_color = p_clear_colors[color_index]; @@ -6934,15 +6958,18 @@ Error RenderingDeviceVulkan::_draw_list_render_pass_begin(Framebuffer *framebuff clear_value.color.float32[2] = 0; clear_value.color.float32[3] = 0; } - clear_values.write[i] = clear_value; + clear_values.write[clear_values_count++] = clear_value; } } - render_pass_begin.clearValueCount = clear_values.size(); + render_pass_begin.clearValueCount = clear_values_count; render_pass_begin.pClearValues = clear_values.ptr(); for (int i = 0; i < p_storage_textures.size(); i++) { Texture *texture = texture_owner.get_or_null(p_storage_textures[i]); + if (!texture) { + continue; + } ERR_CONTINUE_MSG(!(texture->usage_flags & TEXTURE_USAGE_STORAGE_BIT), "Supplied storage texture " + itos(i) + " for draw list is not set to be used for storage."); if (texture->usage_flags & TEXTURE_USAGE_SAMPLING_BIT) { @@ -6981,6 +7008,9 @@ Error RenderingDeviceVulkan::_draw_list_render_pass_begin(Framebuffer *framebuff for (int i = 0; i < framebuffer->texture_ids.size(); i++) { Texture *texture = texture_owner.get_or_null(framebuffer->texture_ids[i]); + if (!texture) { + continue; + } texture->bound = true; draw_list_bound_textures.push_back(framebuffer->texture_ids[i]); } @@ -6989,15 +7019,21 @@ Error RenderingDeviceVulkan::_draw_list_render_pass_begin(Framebuffer *framebuff } void RenderingDeviceVulkan::_draw_list_insert_clear_region(DrawList *draw_list, Framebuffer *framebuffer, Point2i viewport_offset, Point2i viewport_size, bool p_clear_color, const Vector<Color> &p_clear_colors, bool p_clear_depth, float p_depth, uint32_t p_stencil) { + ERR_FAIL_COND_MSG(p_clear_color && p_clear_colors.size() != framebuffer->texture_ids.size(), "Clear color values supplied (" + itos(p_clear_colors.size()) + ") differ from the amount required for framebuffer color attachments (" + itos(framebuffer->texture_ids.size()) + ")."); Vector<VkClearAttachment> clear_attachments; int color_index = 0; + int texture_index = 0; for (int i = 0; i < framebuffer->texture_ids.size(); i++) { Texture *texture = texture_owner.get_or_null(framebuffer->texture_ids[i]); - VkClearAttachment clear_at = {}; + if (!texture) { + texture_index++; + continue; + } + + VkClearAttachment clear_at = {}; if (p_clear_color && texture->usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) { - ERR_FAIL_INDEX(color_index, p_clear_colors.size()); //a bug - Color clear_color = p_clear_colors[color_index]; + Color clear_color = p_clear_colors[texture_index++]; clear_at.clearValue.color.float32[0] = clear_color.r; clear_at.clearValue.color.float32[1] = clear_color.g; clear_at.clearValue.color.float32[2] = clear_color.b; @@ -7073,18 +7109,14 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebu } if (p_initial_color_action == INITIAL_ACTION_CLEAR) { //check clear values - int color_count = 0; for (int i = 0; i < framebuffer->texture_ids.size(); i++) { Texture *texture = texture_owner.get_or_null(framebuffer->texture_ids[i]); - - if (texture->usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) { + if (!texture || !(texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) { color_count++; } } - - ERR_FAIL_COND_V_MSG(p_clear_color_values.size() != color_count, INVALID_ID, - "Clear color values supplied (" + itos(p_clear_color_values.size()) + ") differ from the amount required for framebuffer color attachments (" + itos(color_count) + ")."); + ERR_FAIL_COND_V_MSG(p_clear_color_values.size() != color_count, INVALID_ID, "Clear color values supplied (" + itos(p_clear_color_values.size()) + ") differ from the amount required for framebuffer color attachments (" + itos(color_count) + ")."); } VkFramebuffer vkframebuffer; @@ -7176,7 +7208,7 @@ Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p for (int i = 0; i < framebuffer->texture_ids.size(); i++) { Texture *texture = texture_owner.get_or_null(framebuffer->texture_ids[i]); - if (texture->usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) { + if (!texture || !(texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) { color_count++; } } diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h index a4d5af91a4..7d9bd19309 100644 --- a/drivers/vulkan/rendering_device_vulkan.h +++ b/drivers/vulkan/rendering_device_vulkan.h @@ -219,7 +219,7 @@ class RenderingDeviceVulkan : public RenderingDevice { } }; - Error _buffer_allocate(Buffer *p_buffer, uint32_t p_size, uint32_t p_usage, VmaMemoryUsage p_mapping); + Error _buffer_allocate(Buffer *p_buffer, uint32_t p_size, uint32_t p_usage, VmaMemoryUsage p_mem_usage, VmaAllocationCreateFlags p_mem_flags); Error _buffer_free(Buffer *p_buffer); Error _buffer_update(Buffer *p_buffer, size_t p_offset, const uint8_t *p_data, size_t p_data_size, bool p_use_draw_command_buffer = false, uint32_t p_required_align = 32); diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp index 3551b5d6c4..a09a757842 100644 --- a/drivers/vulkan/vulkan_context.cpp +++ b/drivers/vulkan/vulkan_context.cpp @@ -900,7 +900,7 @@ Error VulkanContext::_create_physical_device(VkSurfaceKHR p_surface) { free(device_queue_props); print_verbose(" #" + itos(i) + ": " + vendor + " " + name + " - " + (present_supported ? "Supported" : "Unsupported") + ", " + dev_type); - if (present_supported) { // Select first supported device of preffered type: Discrete > Integrated > Virtual > CPU > Other. + if (present_supported) { // Select first supported device of preferred type: Discrete > Integrated > Virtual > CPU > Other. switch (props.deviceType) { case VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: { if (type_selected < 4) { diff --git a/drivers/wasapi/audio_driver_wasapi.cpp b/drivers/wasapi/audio_driver_wasapi.cpp index c9609b469a..3a62850339 100644 --- a/drivers/wasapi/audio_driver_wasapi.cpp +++ b/drivers/wasapi/audio_driver_wasapi.cpp @@ -680,7 +680,7 @@ void AudioDriverWASAPI::write_sample(WORD format_tag, int bits_per_sample, BYTE } void AudioDriverWASAPI::thread_func(void *p_udata) { - AudioDriverWASAPI *ad = (AudioDriverWASAPI *)p_udata; + AudioDriverWASAPI *ad = static_cast<AudioDriverWASAPI *>(p_udata); uint32_t avail_frames = 0; uint32_t write_ofs = 0; diff --git a/drivers/windows/dir_access_windows.cpp b/drivers/windows/dir_access_windows.cpp index 6f3bad12c1..881575d245 100644 --- a/drivers/windows/dir_access_windows.cpp +++ b/drivers/windows/dir_access_windows.cpp @@ -185,7 +185,7 @@ Error DirAccessWindows::make_dir(String p_dir) { return ERR_CANT_CREATE; } -String DirAccessWindows::get_current_dir(bool p_include_drive) { +String DirAccessWindows::get_current_dir(bool p_include_drive) const { String base = _get_root_path(); if (!base.is_empty()) { String bd = current_dir.replace("\\", "/").replace_first(base, ""); diff --git a/drivers/windows/dir_access_windows.h b/drivers/windows/dir_access_windows.h index 78d37074e5..fbb07ddef8 100644 --- a/drivers/windows/dir_access_windows.h +++ b/drivers/windows/dir_access_windows.h @@ -64,7 +64,7 @@ public: virtual String get_drive(int p_drive); virtual Error change_dir(String p_dir); ///< can be relative or absolute, return false on success - virtual String get_current_dir(bool p_include_drive = true); ///< return current dir location + virtual String get_current_dir(bool p_include_drive = true) const; ///< return current dir location virtual bool file_exists(String p_file); virtual bool dir_exists(String p_dir); diff --git a/drivers/windows/file_access_windows.cpp b/drivers/windows/file_access_windows.cpp index 59dc1d8e77..1a66d19373 100644 --- a/drivers/windows/file_access_windows.cpp +++ b/drivers/windows/file_access_windows.cpp @@ -59,11 +59,10 @@ void FileAccessWindows::check_errors() const { } Error FileAccessWindows::_open(const String &p_path, int p_mode_flags) { + _close(); + path_src = p_path; path = fix_path(p_path); - if (f) { - close(); - } const WCHAR *mode_string; @@ -134,7 +133,7 @@ Error FileAccessWindows::_open(const String &p_path, int p_mode_flags) { } } -void FileAccessWindows::close() { +void FileAccessWindows::_close() { if (!f) { return; } @@ -350,7 +349,7 @@ Error FileAccessWindows::_set_unix_permissions(const String &p_file, uint32_t p_ } FileAccessWindows::~FileAccessWindows() { - close(); + _close(); } #endif // WINDOWS_ENABLED diff --git a/drivers/windows/file_access_windows.h b/drivers/windows/file_access_windows.h index 93d37c3b5a..5d67b6ca4f 100644 --- a/drivers/windows/file_access_windows.h +++ b/drivers/windows/file_access_windows.h @@ -48,9 +48,10 @@ class FileAccessWindows : public FileAccess { String path_src; String save_path; + void _close(); + public: virtual Error _open(const String &p_path, int p_mode_flags); ///< open a file - virtual void close(); ///< close a file virtual bool is_open() const; ///< true when file is open virtual String get_path() const; /// returns the path for the current open file diff --git a/drivers/xaudio2/audio_driver_xaudio2.cpp b/drivers/xaudio2/audio_driver_xaudio2.cpp index 03fdfda23d..c32c7cf1e5 100644 --- a/drivers/xaudio2/audio_driver_xaudio2.cpp +++ b/drivers/xaudio2/audio_driver_xaudio2.cpp @@ -84,7 +84,7 @@ Error AudioDriverXAudio2::init() { } void AudioDriverXAudio2::thread_func(void *p_udata) { - AudioDriverXAudio2 *ad = (AudioDriverXAudio2 *)p_udata; + AudioDriverXAudio2 *ad = static_cast<AudioDriverXAudio2 *>(p_udata); while (!ad->exit_thread) { if (!ad->active) { |